2016-10-30 3 views
5

J'utilise le Vader SentimentAnalyzer pour obtenir les scores de polarité. J'ai utilisé les scores de probabilité pour positif/négatif/neutre avant, mais je viens de réaliser que le score «composé», allant de -1 (la plus nég) à 1 (la 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]?Comment le score de polarité Vader 'composé' est-il calculé en Python NLTK?

+0

Le code est à: https://github.com/nltk/nltk/blob/develop/ nltk/sentiment/vader.py – alvas

Répondre

24

Les sorties de l'algorithme VADER scores de sentiment à 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é (ie résultat agrégé)

Marchons à travers le code, la première instance du composé 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 en tant que 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 

Donc il y a un hyper-paramètre alpha.

Quant au sum_s, il est une somme des arguments de sentiment passés à la fonction score_valence()https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L413

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'il fait est de itérer à travers tout le lexique SentiText et vérifie avec la fonction sentiment_valence() à base de règles pour attribuer e e score Valence au sentiment https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L243, voir la section 2.1.1 de http://comp.social.gatech.edu/papers/icwsm14.vader.hutto.pdf

Pour en revenir au score composé, on voit que:

  • le score compound est un score normalisé de sum_s et
  • sum_s est la somme de valence calculée sur la base de certaines heuristiques et d'un lexique de sentiment (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 coup d'œ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 la pos, NEG et les scores neu sont calculés à l'aide _sift_sentiment_scores() qui calcule la scores pos, neg et neu invidiuels en utilisant les scores bruts de sentiment_valence() sans la somme.


Si nous jetons un coup d'œil à ce alpha Mathemagic, il semble que la sortie de la normalisation est assez instable (si on les laisse sans 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

Il obtient génial quand il 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

+0

Très bonne explication, il semble que vous manquiez la partie sqrt dans les graphiques & equatio ns –