Как рассчитывается оценка полярности "Вейдера" в Python NLTK?

Я использую Vader SentimentAnalyzer, чтобы получить баллы полярности. Раньше я использовал оценки вероятности для положительного/отрицательного/нейтрального, но я только что понял, что "составная" оценка, начиная с -1 (самая отрицательная) до 1 (самая позиция), обеспечит единую меру полярности. Интересно, как вычисляется "составная" оценка. Это рассчитывается из вектора [pos, neu, neg]?

Ответ 1

Алгоритм VADER выводит оценки оценок до 4 классов чувств https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L441:

  • neg: Отрицательный
  • neu: Нейтральный
  • pos: Положительный
  • compound: Соединение (т.е. агрегированный балл)

Пропустив код, первый экземпляр соединения находится в https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L421, где он вычисляет:

compound = normalize(sum_s)

Функция normalize() определяется как таковая в https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L107:

def normalize(score, alpha=15):
    """
    Normalize the score to be between -1 and 1 using an alpha that
    approximates the max expected value
    """
    norm_score = score/math.sqrt((score*score) + alpha)
    return norm_score

Итак, есть гиперпараметр alpha.

Что касается sum_s, это сумма аргументов сентимента, переданных функции score_valence() https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L413

И если мы отследим этот аргумент sentiment, мы увидим, что он вычислен при вызове функции polarity_scores() в https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L217:

def polarity_scores(self, text):
    """
    Return a float for sentiment strength based on the input text.
    Positive values are positive valence, negative value are negative
    valence.
    """
    sentitext = SentiText(text)
    #text, words_and_emoticons, is_cap_diff = self.preprocess(text)

    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 BOOSTER_DICT:
            sentiments.append(valence)
            continue

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

    sentiments = self._but_check(words_and_emoticons, sentiments)

Глядя на функцию polarity_scores, он выполняет итерацию по всей лексике SentiText и проверяет с помощью функции sentiment_valence() на основе правил, чтобы присвоить валентную оценку настроению https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L243, см. Раздел 2.1.1 http://comp.social.gatech.edu/papers/icwsm14.vader.hutto.pdf

Итак, возвращаясь к составной оценке, мы видим, что:

  • оценка compound - нормализованная оценка sum_s и
  • sum_s - сумма валентности, вычисленная на основе некоторых эвристик и лексики чувств (например, интенсивность соблазна) и
  • нормализованная оценка - это просто sum_s, деленная на ее квадрат плюс альфа-параметр, который увеличивает знаменатель функции нормализации.

Является ли это вычислением из вектора [pos, neu, neg]?

Не действительно =)

Если мы посмотрим на функцию score_valence https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L411, мы увидим, что составной балл вычисляется с помощью sum_s до pos, neg и neu рассчитываются с использованием _sift_sentiment_scores(), который вычисляет оценки invidiual pos, neg и neu, используя исходные оценки из sentiment_valence() без суммы.


Если мы посмотрим на эту математическую математику alpha, кажется, что выход нормализации довольно неустойчив (если оставить его без ограничений), в зависимости от значения alpha:

alpha=0:

введите описание изображения здесь

alpha=15:

введите описание изображения здесь

alpha=50000:

введите описание изображения здесь

alpha=0.001:

введите описание изображения здесь

Он становится фанк, когда он отрицательный:

alpha=-10:

введите описание изображения здесь

alpha=-1,000,000:

введите описание изображения здесь

alpha=-1,000,000,000:

введите описание изображения здесь