Анализ настроений Вейдера: Как оцениваются отдельные слова?

Поэтому я использовал Vader Sentiment Analyzer для анализа определенных отзывов клиентов. Оценивая результаты, я увидел, что анализатор настроений давал мне смешанные результаты.

For eg: "Again, human interaction needs to have resolutions. Your reps 
        cannot BLAME the system and shrug off being able to help. Let 
        alone blame the system and not know WHY the system makes 
        indiscriminate decisions."

Output: compound: 0.2212 neg: 0.111 neu: 0.756, pos: 0.133

В этом случае O/P должен был быть отрицательным, но вместо этого он давал составной балл от нейтрального до положительного, что не имеет смысла.

Я видел этот файл в AppData\Roaming\nltk_data\sentiment\vader_lexicon.txt, который содержал оценки настроения большинства английских слов.

Я просто хотел узнать, как эти индивидуальные слова получают оценки настроения в терминах позитивного отношения и сложного? Есть ли алгоритм / процесс, чтобы оценить их?

Наконец, я думал о создании своего собственного словаря для анализа настроений, чтобы получить лучшие результаты, но для этого мне нужно знать, как каждому слову присваиваются оценки настроения?

2 ответа

Используя приведенный ниже код (не мой), вы можете определить, какие слова лексикон Вейдера классифицирует как положительные, отрицательные и нейтральные:

import nltk
from nltk.tokenize import word_tokenize, RegexpTokenizer
from nltk.sentiment.vader import SentimentIntensityAnalyzer
sentence = 'Again, human interaction needs to have resolutions. Your reps cannot BLAME the system and shrug off being able to help. Let alone blame the system and not know WHY the system makes indiscriminate decisions.'
tokenized_sentence = nltk.word_tokenize(sentence)

sid = SentimentIntensityAnalyzer()
pos_word_list=[]
neu_word_list=[]
neg_word_list=[]

for word in tokenized_sentence:
    if (sid.polarity_scores(word)['compound']) >= 0.1:
        pos_word_list.append(word)
    elif (sid.polarity_scores(word)['compound']) <= -0.1:
        neg_word_list.append(word)
    else:
    neu_word_list.append(word)                

print('Positive:',pos_word_list)        
print('Neutral:',neu_word_list)    
print('Negative:',neg_word_list) 
score = sid.polarity_scores(sentence)
print('\nScores:', score)

Запуск этого кода приводит к следующему результату:

Positive: ['help']
Neutral: ['Again', ',', 'human', 'interaction', 'needs', 'to', 'have', 'resolutions', '.', 'Your', 'reps', 'can', 'not', 'the', 'system', 'and', 'shrug', 'off', 'being', 'able', 'to', '.', 'Let', 'the', 'system', 'and', 'not', 'know', 'WHY', 'the', 'system', 'makes', 'indiscriminate', 'decisions', '.']
Negative: ['BLAME', 'alone', 'blame']

Затем мы можем перейти к файлу vader .txt и узнать, какие оценки были назначены вашим словам. Виноват получает -1,4 балла, один - -1,0 балла, а балл +1,7. Это должно привести к отрицательному результату, однако у вас есть слово "не может" перед одним использованием слова "винить", которое отрицает отрицательный элемент слова и вместо этого преобразует его в положительный. Хотя Вейдер умен, он может идентифицировать отрицание, но не может связать это с общей структурой предложения (что верно для большинства альтернативных методов).

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

Индивидуальные баллы за каждое слово можно найти .

Очки, которые вы получаете от бегаsid.polarity_scores(individual_word)это индивидуальная оценка после того, как она была «нормализована» (VaderConstants.normalize) до оценки между [-1,1]. Это не обязательно оценка слова в предложении, поскольку оценка может быть изменена окружающими словами.

Подсчет баллов за предложение включает (на высоком уровне):

  1. Присвоение значения каждому слову (после удаления стоп-слов) на основе найденных здесьздесь данных .
  2. Управление баллами для отдельных слов на основе правил (например, переключение полярности после отрицания)
  3. Объединение отдельных баллов
  4. Внесение дополнительных изменений в комбинированные баллы на основе большего количества правил (например, если в конце предложения есть восклицательный знак).

Если мы просто используемpolarity_scores(individual_word)['compound'], оценка может не иметь оценки, как при использовании слова в предложении, поскольку Вейдер изменяет оценку на основе окружающих слов. Кроме того, после того как на шаге 3 будут объединены оценки всех слов, мы потеряем счет оценок, присвоенных отдельным словам. Однако мы можем вывести оценки после шага 2. Во многих случаях шаг 4 неприменим, поэтому оценки с шага 2 сразу попадают в функцию нормализации.

      from nltk.sentiment.vader import SentimentIntensityAnalyzer, SentiText, VaderConstants

text = "The movie was not great."

# Code from SentimentIntensityAnalyzer.polarity_scores with minor modifications
# https://www.nltk.org/_modules/nltk/sentiment/vader.html#SentimentIntensityAnalyzer.polarity_scores

sentitext = SentiText(text, VaderConstants.PUNC_LIST, VaderConstants.REGEX_REMOVE_PUNCTUATION)

sid = SentimentIntensityAnalyzer()

sentiments = []
words_and_emoticons = sentitext.words_and_emoticons
for item in words_and_emoticons:
    valence = 0
    i = words_and_emoticons.index(item)
    if (
        i < len(words_and_emoticons) - 1
        and item.lower() == "kind"
        and words_and_emoticons[i + 1].lower() == "of"
    ) or item.lower() in VaderConstants.BOOSTER_DICT:
        sentiments.append(valence)
        continue

    sentiments = sid.sentiment_valence(valence, sentitext, item, i, sentiments)

sentiments = sid._but_check(words_and_emoticons, sentiments)
print(list(zip(words_and_emoticons,sentiments)))
print("Total score after 'normalizing' individual scores:", sid.score_valence(sentiments, text))

Используя приведенные ниже примеры, обратите внимание на то, что оценка слова «великолепный» является отрицательной, когда оно стоит после «не», и положительной в противном случае.

Чтобы получить оценку в инвертированном контексте, нормальная оценка подвергается функции, поэтому абсолютные оценки для слова «хорошо» немного отличаются.

Вывод для "Фильм не понравился".

      [('The', 0), ('movie', 0), ('was', 0), ('not', 0), ('great', -2.294)]
Total score after 'normalizing' individual scores: {'neg': 0.452, 'neu': 0.548, 'pos': 0.0, 'compound': -0.5096}

Выходные данные для «Фильм был великолепен».

      [('The', 0), ('movie', 0), ('was', 0), ('great', 3.1)]
Total score after 'normalizing' individual scores: {'neg': 0.0, 'neu': 0.423, 'pos': 0.577, 'compound': 0.6249}
Другие вопросы по тегам