¿Cómo se calcula la puntuación de polaridad de “compuesto” de Vader en Python NLTK?

Estoy usando Vader SentimentAnalyzer para obtener las puntuaciones de polaridad. Utilicé las puntuaciones de probabilidad para positivo / negativo / neutral antes, pero me di cuenta de que la puntuación “compuesta”, que va de -1 (la mayoría negativa) a 1 (la mayoría pos) proporcionaría una medida única de polaridad. Me pregunto cómo se calculó la puntuación “compuesta”. ¿Se calcula a partir del vector [pos, neu, neg]?

El algoritmo VADER produce puntuaciones de sentimiento en 4 clases de sentimientos https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L441 :

  • neg : Negativo
  • neu : Neutral
  • pos : positivo
  • compound : compuesto (es decir, puntuación agregada)

Veamos el código, la primera instancia del compuesto se encuentra en https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L421 , donde se calcula:

 compound = normalize(sum_s) 

La función normalize() se define como tal en 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 

Así que hay un hiper-parámetro alpha .

En cuanto a los sum_s , es una sum de los argumentos de sentimiento pasados ​​a la función score_valence() https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L413

Y si rastreamos este argumento de sentiment , vemos que se calcula al llamar a la función polarity_scores() en 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) 

Al observar la función polarity_scores, lo que está haciendo es recorrer todo el léxico SentiText y verifica con la función sentiment_valence() basada en reglas para asignar la puntuación de valencia al sentimiento https://github.com/nltk/nltk/blob/ desarrollar / nltk / sentiment / vader.py # L243 , consulte la Sección 2.1.1 de http://comp.social.gatech.edu/papers/icwsm14.vader.hutto.pdf

Así que volviendo a la puntuación compuesta, vemos que:

  • el puntaje compound es un puntaje normalizado de sum_s y
  • sum_s es la sum de la valencia calculada en base a algunas heurísticas y un léxico de sentimiento (también conocido como Intensidad del sentimiento) y
  • la puntuación normalizada es simplemente la sum_s dividida por su cuadrado más un parámetro alfa que aumenta el denominador de la función de normalización.

¿Se calcula a partir del vector [pos, neu, neg]?

En realidad no =)

Si echamos un vistazo a la función score_valence https://github.com/nltk/nltk/blob/develop/nltk/sentiment/vader.py#L411 , vemos que la puntuación compuesta se calcula con los sum_s antes de la posición, las puntuaciones neg y neu se calculan utilizando _sift_sentiment_scores() que calcula las puntuaciones individuales pos, neg y neu utilizando las puntuaciones brutas de sentiment_valence() sin la sum.


Si echamos un vistazo a este alpha mathemagic, parece que la salida de la normalización es bastante inestable (si se deja sin restricciones), dependiendo del valor de alpha :

alpha=0 :

introduzca la descripción de la imagen aquí

alpha=15 :

introduzca la descripción de la imagen aquí

alpha=50000 :

introduzca la descripción de la imagen aquí

alpha=0.001 :

introduzca la descripción de la imagen aquí

Se pone funky cuando es negativo:

alpha=-10 :

introduzca la descripción de la imagen aquí

alpha=-1,000,000 :

introduzca la descripción de la imagen aquí

alpha=-1,000,000,000 :

introduzca la descripción de la imagen aquí