web-dev-qa-db-fra.com

Comment le score de polarité «composé» de Vader est-il calculé en Python NLTK?

J'utilise le Vader SentimentAnalyzer pour obtenir les scores de polarité. J'ai utilisé les scores de probabilité pour positif/négatif/neutre auparavant, mais je viens de réaliser que le score "composé", allant de -1 (le plus négatif) à 1 (le plus pos), fournirait une seule mesure de polarité. Je me demande comment le score "composé" a été calculé. Est-ce calculé à partir du vecteur [pos, neu, neg]?

18
alicecongcong

L'algorithme VADER génère des scores de sentiment dans 4 classes de sentiments https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L441 :

  • neg: négatif
  • neu: Neutre
  • pos: positif
  • compound: Composé (c'est-à-dire score agrégé)

Parcourons le code, la première instance de compound est à https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L421 , où il calcule:

compound = normalize(sum_s)

La fonction normalize() est définie comme telle à 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

Il y a donc un hyper-paramètre alpha.

Quant au sum_s, Il s'agit d'une somme des arguments de sentiment passés à la fonction score_valence()https://github.com/nltk/nltk/blob/develop/nltk /sentiment/vader.py#L41

Et si nous remontons cet argument sentiment, nous voyons qu'il est calculé lors de l'appel de la fonction 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)

En regardant la fonction polarity_scores, Ce qu'elle fait est de parcourir tout le lexique SentiText et vérifie avec la fonction sentiment_valence() basée sur des règles pour attribuer le score de valence au sentiment https : //github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L24 , voir la section 2.1.1 de http://comp.social.gatech.edu/ papers/icwsm14.vader.hutto.pdf

Donc, pour en revenir au score composé, nous voyons que:

  • le score compound est un score normalisé de sum_s et
  • sum_s Est la somme de la valence calculée sur la base de quelques heuristiques et d'un Lexique des sentiments (aka. Sentiment Intensity) et
  • le score normalisé est simplement le sum_s divisé par son carré plus un paramètre alpha qui augmente le dénominateur de la fonction de normalisation.

Est-ce calculé à partir du vecteur [pos, neu, neg]?

Pas vraiment =)

Si nous jetons un œil à la fonction score_valencehttps://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L411 , nous voyons que le score composé est calculé avec le sum_s avant que les scores pos, neg et neu soient calculés à l'aide de _sift_sentiment_scores() qui calcule les scores inv, pos, neg et neu à l'aide des scores bruts de la fonction sentiment_valence() sans la somme.


Si nous jetons un coup d'œil à cette alpha mathémagique, il semble que la sortie de la normalisation soit plutôt instable (si elle n'est pas contrainte), en fonction de la valeur de alpha:

alpha=0:

enter image description here

alpha=15:

enter image description here

alpha=50000:

enter image description here

alpha=0.001:

enter image description here

Ça devient génial quand c'est négatif:

alpha=-10:

enter image description here

alpha=-1,000,000:

enter image description here

alpha=-1,000,000,000:

enter image description here

55
alvas

La section "À propos de la notation" du repo github a une description.

1
leonfrench