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:
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 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
:
alpha=15
:
alpha=50000
:
alpha=0.001
:
Se pone funky cuando es negativo:
alpha=-10
:
alpha=-1,000,000
:
alpha=-1,000,000,000
: