The Natural Language Toolkit (NLTK) (https://www.nltk.org) provides an excellent starting point for natural language processing projects. In this blog we wanted to explore the creation and use of a custom docker image to allow one of the components of NLTK, that is the VADER sentiment analysis tool (https://www.nltk.org/_modules/nltk/sentiment/vader.html). A key advantage of VADER (Valence Aware Dictionary for Sentiment Reasoning) is that the model comes pre-trained, and so is easy to get to work. A Python3 API is provided.
Sentiment analysis seeks to infer from the choice of words and structure of text an estimate of the sentiment. VADER will assign a proportional polarity score for positive, neutral and negative sentiment, as well as provide a single compound score ranging from -1 to 1.
As with earlier blogs, we will use docker to set up the project (https://www.docker.com), the advantage being we can configure a whole ‘virtual container image’ with all the tools needed but without affecting the configuration of our own computer.
This blog uses the files placed on GitHub at https://github.com/SPFDigiEnv/nlp and assumes Docker is installed locally – we used a MacBook Pro.
To run the test, first download the git files to a local repository. Included in the repo are:
- Dockerfile – the docker file
- nlp-nltk_sentiment_test.py – the Python code to run VADER
- LICENSE
- requirements.txt – prerequisite libraries to load into docker image
- README.md – full details
Having downloaded the files, the docker image is built with the following command at the terminal:
docker build -t nlp .
After creating the docker image, it can be run with the following command:
docker run -it -v $(pwd):/code -w /code --name="natural_language_toolkit" nlp /bin/bash
This should result in a prompt, and the Python code, based on code from the nltk documentation, can be run thus:
python3 nlp-nltk_classification_test.py
To see the results of the sentiment analysis we need to run tests on different texts. For the neutral/negative who else can we turn to than Marvin the Paranoid Android from the brilliant ‘The Hitchhiker’s Guide to the Galaxy‘ (a must read!). For Positive/Neutral text we look to the lyrics of Pharrell Williams’ great song ‘Happy’. The resultant output should appear thus:
Hello NLP - Vader Sentiments, see https://github.com/cjhutto/vaderSentiment Scoring description: https://stackoverflow.com/questions/40325980/how-is-the-vader-compound-polarity-score-calculated-in-python-nltk What the scores mean: SentimentIntensityAnalyzer is an object and polarity_scores uses the following categories: Positive; Negative; Neutral; Compound The compound score is the sum of positive, negative & neutral scores which is then normalized between -1 (most extreme negative) and +1 (most extreme positive). The more Compound score closer to +1, the higher the positivity of the text. Life? Don't talk to me about life. compound------- 0.0, neg------------ 0.0, neu------------ 1.0, pos------------ 0.0, Here I am, brain the size of a planet, and they tell me to take you up to the bridge. Call that job satisfaction? 'Cos I don't. compound------- 0.4404, neg------------ 0.0, neu------------ 0.888, pos------------ 0.112, I think you ought to know I'm feeling very depressed. Pardon me for breathing, which I never do anyway so I don't know why I bother to say it, Oh God, I'm so depressed. compound------- -0.2433, neg------------ 0.182, neu------------ 0.609, pos------------ 0.208, You think you've got problems? What are you supposed to do if you are a manically depressed robot? No, don't try to answer that. I'm fifty thousand times more intelligent than you and even I don't know the answer. It gives me a headache just trying to think down to your level. compound------- -0.6448, neg------------ 0.151, neu------------ 0.792, pos------------ 0.058, And then, of course, I've got this terrible pain in all the diodes down my left side. compound------- -0.7861, neg------------ 0.316, neu------------ 0.684, pos------------ 0.0, It might seem crazy what I am about to say Sunshine she's here, you can take a break I'm a hot air balloon that could go to space With the air, like I don't care, baby by the way compound------- 0.171, neg------------ 0.12, neu------------ 0.743, pos------------ 0.137, Huh (Because I'm happy) Clap along if you feel like a room without a roof (Because I'm happy) Clap along if you feel like happiness is the truth (Because I'm happy) Clap along if you know what happiness is to you (Because I'm happy) Clap along if you feel like that's what you wanna do compound------- 0.9432, neg------------ 0.0, neu------------ 0.734, pos------------ 0.266, I said Clap along if you feel like a room without a roof (Because I'm happy) Clap along if you feel like happiness is the truth (Because I'm happy) Clap along if you know what happiness is to you (Because I'm happy) Clap along if you feel like that's what you wanna do Clap along if you feel like a room without a roof (Because I'm happy) Clap along if you feel like happiness is the truth (Because I'm happy) Clap along if you know what happiness is to you (Because I'm happy) Clap along if you feel like that's what you wanna do compound------- 0.9849, neg------------ 0.0, neu------------ 0.719, pos------------ 0.281, Bring me down (Happy, happy, happy, happy) Can't nothing (Happy, happy, happy, happy) Bring me down, my level's too high To bring me down (Happy, happy, happy, happy) Can't nothing (Happy, happy, happy, happy) Bring me down compound------- 0.9843, neg------------ 0.0, neu------------ 0.495, pos------------ 0.505,
It’s interesting to see the difference in the polarity and composite sentiment scores between the two texts! The composite score often reads more strongly than the single polarity scores might suggest. The compound score represents a score of the sum of valence computed, based on heuristics and the VADER sentiment lexicon, normalised to between -1 to 1 as the sum divided by its square plus an alpha parameter that increases the denominator of the normalisation function, see https://github.com/cjhutto/vaderSentiment.
Typical suggested threshold values are:
positive sentiment: compound score >= 0.05
neutral sentiment: (compound score > -0.05) and (compound score < 0.05)
negative sentiment: compound score <= -0.05
To find out more about VADER, see
Hutto, C.J. & Gilbert, E.E. (2014). VADER: A Parsimonious Rule-based Model for Sentiment Analysis of Social Media Text. Eighth International Conference on Weblogs and Social Media (ICWSM-14). Ann Arbor, MI, June 2014.