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?
Répondre
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égatifneu
: Neutrepos
: Positifcompound
: 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é desum_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_valence
https://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
:
alpha=15
:
alpha=50000
:
alpha=0.001
:
Il obtient génial quand il est négatif:
alpha=-10
:
alpha=-1,000,000
:
alpha=-1,000,000,000
:
Très bonne explication, il semble que vous manquiez la partie sqrt dans les graphiques & equatio ns –
Le code est à: https://github.com/nltk/nltk/blob/develop/ nltk/sentiment/vader.py – alvas