Обучите классификатор настроений

В этом примере показано, как обучить классификатор для анализа настроений с помощью аннотированного списка положительных и отрицательных слов настроения и предварительно обученного встраивания слова.

Предварительно обученное встраивание слов играет несколько ролей в этом рабочем процессе. Он преобразует слова в числовые векторы и формирует базис для классификатора. Затем можно использовать классификатор, чтобы предсказать настроение других слов, используя их векторное представление, и использовать эти классификации, чтобы вычислить настроение части текста. Существует четыре шага в обучении и использовании классификатора настроений:

  • Загрузите предварительно обученное встраивание слов.

  • Загрузите лексикон мнения со списком положительных и отрицательных слов.

  • Обучите классификатор настроений с помощью векторов слов положительных и отрицательных слов.

  • Вычислим средние счета настроений слов в фрагменте текста.

Загрузка предварительно обученного встраивания в Word

Вложения в Word сопоставляют слова в словаре с числовыми векторами. Эти вложения могут захватывать семантические детали слов, так что подобные слова имеют похожие векторы. Они также моделируют отношения между словами через векторную арифметику. Например, отношение Рима к Парижу, так как Италия к Франции описывается уравнением Rome-Italy+FranceParis.

Загрузите предварительно обученное встраивание слова с помощью fastTextWordEmbedding функция. Эта функция требует Text Analytics Toolbox™ Model для fastText English 16 млрд Token Word Embedding пакет поддержки. Если этот пакет поддержки не установлен, то функция предоставляет ссылку на загрузку.

emb = fastTextWordEmbedding;

Загрузка Lexicon мнения

Загрузите положительные и отрицательные слова из лексикона мнения (также известного как лексикон настроения) из 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;

Классификатор настроений train

Обучите классификатор машины опорных векторов (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, перечисленный в конце примера, выполняет следующие шаги по порядку:

  1. Токенизация текста с помощью tokenizedDocument.

  2. Удалите пунктуацию с помощью erasePunctuation.

  3. Удалите стоповые слова (такие как «and», «of», и «the») с помощью removeStopWords.

  4. Преобразуйте в строчный регистр с помощью 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 выполняет следующие шаги:

  1. Токенизация текста с помощью tokenizedDocument.

  2. Удалите пунктуацию с помощью erasePunctuation.

  3. Удалите стоповые слова (такие как «and», «of», и «the») с помощью removeStopWords.

  4. Преобразуйте в строчный регистр с помощью 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

Библиография

  1. Ху, Миньцин и Бин Лю. «Майнинг и подведение итогов отзывов клиентов». В Трудах десятой международной конференции ACM SIGKDD по открытию знаний и майнингу данных, стр. 168-177. ACM, 2004.

См. также

| | | | | | |

Похожие темы