В этом примере показано, как обучить классификатор для анализа настроений с помощью аннотированного списка положительных и отрицательных слов настроения и предварительно обученного встраивания слова.
Предварительно обученное встраивание слов играет несколько ролей в этом рабочем процессе. Он преобразует слова в числовые векторы и формирует базис для классификатора. Затем можно использовать классификатор, чтобы предсказать настроение других слов, используя их векторное представление, и использовать эти классификации, чтобы вычислить настроение части текста. Существует четыре шага в обучении и использовании классификатора настроений:
Загрузите предварительно обученное встраивание слов.
Загрузите лексикон мнения со списком положительных и отрицательных слов.
Обучите классификатор настроений с помощью векторов слов положительных и отрицательных слов.
Вычислим средние счета настроений слов в фрагменте текста.
Вложения в Word сопоставляют слова в словаре с числовыми векторами. Эти вложения могут захватывать семантические детали слов, так что подобные слова имеют похожие векторы. Они также моделируют отношения между словами через векторную арифметику. Например, отношение Рима к Парижу, так как Италия к Франции описывается уравнением .
Загрузите предварительно обученное встраивание слова с помощью fastTextWordEmbedding
функция. Эта функция требует Text Analytics Toolbox™ Model для fastText English 16 млрд Token Word Embedding пакет поддержки. Если этот пакет поддержки не установлен, то функция предоставляет ссылку на загрузку.
emb = fastTextWordEmbedding;
Загрузите положительные и отрицательные слова из лексикона мнения (также известного как лексикон настроения) из https://www.cs.uic.edu/~liub/FBS/sentiment-analysis.html. [1] Сначала извлеките файлы из .rar
файл в папку с именем opinion-lexicon-English
, а затем импортируйте текст.
Загрузите данные с помощью функции readLexicon
приведенный в конце этого примера. Область выхода data
- таблица с переменными Word
содержащие слова и Label
содержащая категориальную метку настроения, Positive
или Negative
.
data = readLexicon;
Просмотрите первые несколько слов, помеченных как положительные.
idx = data.Label == "Positive";
head(data(idx,:))
ans=8×2 table
Word Label
____________ ________
"a+" Positive
"abound" Positive
"abounds" Positive
"abundance" Positive
"abundant" Positive
"accessable" Positive
"accessible" Positive
"acclaim" Positive
Просмотрите первые несколько слов, помеченных как отрицательные.
idx = data.Label == "Negative";
head(data(idx,:))
ans=8×2 table
Word Label
_____________ ________
"2-faced" Negative
"2-faces" Negative
"abnormal" Negative
"abolish" Negative
"abominable" Negative
"abominably" Negative
"abominate" Negative
"abomination" Negative
Чтобы обучить классификатор настроений, преобразуйте слова в векторы слов с помощью предварительно обученного emb
встраивания слов. Сначала удалите слова, которые не появляются в слове embedding
emb
.
idx = ~isVocabularyWord(emb,data.Word); data(idx,:) = [];
Отложите 10% слов наугад для проверки.
numWords = size(data,1);
cvp = cvpartition(numWords,'HoldOut',0.1);
dataTrain = data(training(cvp),:);
dataTest = data(test(cvp),:);
Преобразуйте слова в обучающих данных в векторы слов с помощью word2vec
.
wordsTrain = dataTrain.Word; XTrain = word2vec(emb,wordsTrain); YTrain = dataTrain.Label;
Обучите классификатор машины опорных векторов (SVM), который классифицирует векторы слов в положительные и отрицательные категории.
mdl = fitcsvm(XTrain,YTrain);
Преобразуйте слова в тестовых данных в векторы слов с помощью word2vec
.
wordsTest = dataTest.Word; XTest = word2vec(emb,wordsTest); YTest = dataTest.Label;
Спрогнозируйте метки настроения векторов тестового слова.
[YPred,scores] = predict(mdl,XTest);
Визуализируйте точность классификации в матрице неточностей.
figure confusionchart(YTest,YPred);
Визуализируйте классификации в облаках слов. Постройте график слов с положительными и отрицательными настроениями в облаках слов с размерами слов, соответствующими счетам предсказания.
figure subplot(1,2,1) idx = YPred == "Positive"; wordcloud(wordsTest(idx),scores(idx,1)); title("Predicted Positive Sentiment") subplot(1,2,2) wordcloud(wordsTest(~idx),scores(~idx,2)); title("Predicted Negative Sentiment")
Чтобы вычислить настроение части текста, например обновления в социальных сетях, спрогнозируйте счет настроения каждого слова в тексте и возьмите средний счет настроения.
filename = "weekendUpdates.xlsx"; tbl = readtable(filename,'TextType','string'); textData = tbl.TextData; textData(1:10)
ans = 10×1 string array
"Happy anniversary! ❤ Next stop: Paris! ✈ #vacation"
"Haha, BBQ on the beach, engage smug mode! ❤ #vacation"
"getting ready for Saturday night #yum #weekend "
"Say it with me - I NEED A #VACATION!!! ☹"
" Chilling at home for the first time in ages…This is the life! #weekend"
"My last #weekend before the exam ."
"can’t believe my #vacation is over so unfair"
"Can’t wait for tennis this #weekend "
"I had so much fun! Best trip EVER! #vacation #weekend"
"Hot weather and air con broke in car #sweaty #roadtrip #vacation"
Создайте функцию, которая токенизирует и предварительно обрабатывает текстовые данные, чтобы их можно было использовать для анализа. Функция preprocessText
, перечисленный в конце примера, выполняет следующие шаги по порядку:
Токенизация текста с помощью tokenizedDocument
.
Удалите пунктуацию с помощью erasePunctuation
.
Удалите стоповые слова (такие как «and», «of», и «the») с помощью removeStopWords
.
Преобразуйте в строчный регистр с помощью lower
.
Используйте функцию предварительной обработки preprocessText
для подготовки текстовых данных. Этот шаг может занять несколько минут.
documents = preprocessText(textData);
Удалите слова из документов, которые не фигурируют в слове embedding emb
.
idx = ~isVocabularyWord(emb,documents.Vocabulary); documents = removeWords(documents,idx);
Чтобы визуализировать, насколько хорошо классификатор настроений обобщает новый текст, классифицируйте настроения на слова, которые происходят в тексте, но не в обучающих данных и визуализируйте их в облаках слов. Используйте облака слов, чтобы вручную проверить, что классификатор ведет себя должным образом.
words = documents.Vocabulary; words(ismember(words,wordsTrain)) = []; vec = word2vec(emb,words); [YPred,scores] = predict(mdl,vec); figure subplot(1,2,1) idx = YPred == "Positive"; wordcloud(words(idx),scores(idx,1)); title("Predicted Positive Sentiment") subplot(1,2,2) wordcloud(words(~idx),scores(~idx,2)); title("Predicted Negative Sentiment")
Чтобы вычислить настроение данного фрагмента текста, вычислите счет настроения для каждого слова в тексте и вычислите средний счет настроения.
Вычислите средний счет настроений обновлений. Для каждого документа преобразуйте слова в векторы слов, прогнозируйте счет настроения на векторах слов, преобразуйте счета с помощью функции преобразования счет-апостериорный и затем вычисляйте средний счет настроений.
for i = 1:numel(documents) words = string(documents(i)); vec = word2vec(emb,words); [~,scores] = predict(mdl,vec); sentimentScore(i) = mean(scores(:,1)); end
Просмотрите предсказанные счета настроения с помощью текстовых данных. Счета, больше 0, соответствуют положительным настроениям, счета меньше 0 соответствуют отрицательным настроениям, и счета, близкие к 0, соответствуют нейтральным настроениям.
table(sentimentScore', textData)
ans=50×2 table
Var1 textData
__________ ___________________________________________________________________________________________________________________________
1.8382 "Happy anniversary! ❤ Next stop: Paris! ✈ #vacation"
1.294 "Haha, BBQ on the beach, engage smug mode! ❤ #vacation"
1.0922 "getting ready for Saturday night #yum #weekend "
0.094709 "Say it with me - I NEED A #VACATION!!! ☹"
1.4073 " Chilling at home for the first time in ages…This is the life! #weekend"
-0.8356 "My last #weekend before the exam ."
-1.3556 "can’t believe my #vacation is over so unfair"
1.4312 "Can’t wait for tennis this #weekend "
3.0458 "I had so much fun! Best trip EVER! #vacation #weekend"
-0.39243 "Hot weather and air con broke in car #sweaty #roadtrip #vacation"
0.8028 " Check the out-of-office crew, we are officially ON #VACATION!! "
0.38217 "Well that wasn’t how I expected this #weekend to go Total washout!! "
3.03 "So excited for my bestie to visit this #weekend! ❤ "
2.3849 "Who needs a #vacation when the weather is this good ☀ "
-0.0006176 "I love meetings in summer that run into the weekend! Wait that was sarcasm. Bring on the aircon apocalypse! ☹ #weekend"
0.52992 "You know we all worked hard for this! We totes deserve this #vacation Ibiza ain’t gonna know what hit em "
⋮
Эта функция читает положительные и отрицательные слова из лексикона настроений и возвращает таблицу. Таблица содержит переменные Word
и Label
, где Label
содержит категориальные значения Positive
и Negative
соответствующий настроению каждого слова.
function data = readLexicon % Read positive words fidPositive = fopen(fullfile('opinion-lexicon-English','positive-words.txt')); C = textscan(fidPositive,'%s','CommentStyle',';'); wordsPositive = string(C{1}); % Read negative words fidNegative = fopen(fullfile('opinion-lexicon-English','negative-words.txt')); C = textscan(fidNegative,'%s','CommentStyle',';'); wordsNegative = string(C{1}); fclose all; % Create table of labeled words words = [wordsPositive;wordsNegative]; labels = categorical(nan(numel(words),1)); labels(1:numel(wordsPositive)) = "Positive"; labels(numel(wordsPositive)+1:end) = "Negative"; data = table(words,labels,'VariableNames',{'Word','Label'}); end
Функция preprocessText
выполняет следующие шаги:
Токенизация текста с помощью tokenizedDocument
.
Удалите пунктуацию с помощью erasePunctuation
.
Удалите стоповые слова (такие как «and», «of», и «the») с помощью removeStopWords
.
Преобразуйте в строчный регистр с помощью lower
.
function documents = preprocessText(textData) % Tokenize the text. documents = tokenizedDocument(textData); % Erase punctuation. documents = erasePunctuation(documents); % Remove a list of stop words. documents = removeStopWords(documents); % Convert to lowercase. documents = lower(documents); end
Ху, Миньцин и Бин Лю. «Майнинг и подведение итогов отзывов клиентов». В Трудах десятой международной конференции ACM SIGKDD по открытию знаний и майнингу данных, стр. 168-177. ACM, 2004.
bagOfWords
| erasePunctuation
| fastTextWordEmbedding
| removeStopWords
| removeWords
| tokenizedDocument
| word2vec
| wordcloud