Effortless Sentiment Analysis with Hugging Face Transformers: A Beginner’s Guide

Ganesh Lokare
9 min readFeb 4, 2023

--

Sentiment Analysis

Sentiment analysis is the process of determining the emotion or opinion expressed in a piece of text, such as a tweet or a review. It is a subfield of natural language processing (NLP) that involves using machine learning and NLP techniques to classify the sentiment of a piece of text as positive, negative, or neutral. The goal of sentiment analysis is to extract insights from large amounts of unstructured text data and understand the overall sentiment of a population towards a particular topic.

What We Will Cover in This Blog

  1. Review of what sentiment analysis is.
  2. How to perform sentiment analysis with Hugging face Transformers (just a few lines of code)

The main focus of this blog, using a very high level interface for transformers which is the Hugging face pipeline. Using this interface you will see that we can perform sentiment analysis with just 1 or 2 lines of code.

Sentiment Analysis as a classification task

  • Binary classification (positive, negative)
  • Multiclass: positive, negative or neutral
  • Fine-grain: very positive, positive, neutral, negative, very negative
  • Dependent on the dataset you’re using or how you made your dataset
  • If we use prebuild classifier (e.g. Hugging Face) we are stuck with whatever the model was trained to do (in this case binary classification)

Use of Sentiment Analysis

  1. Improve customer experience: Sentiment analysis can be used to understand customer opinions and feedback on products and services, allowing companies to improve the customer experience and build stronger customer relationships.
  2. Market research: Sentiment analysis can be used to monitor public sentiment towards a particular topic or brand, providing valuable insights into market trends and customer preferences.
  3. Improve product design: Sentiment analysis can be used to understand customer preferences and opinions on product features, allowing companies to design products that better meet customer needs.
  4. Improve social media monitoring: Sentiment analysis can be used to monitor social media conversations and understand the tone and sentiment behind them, providing valuable insights into public perception and sentiment.
  5. Improve decision making: Sentiment analysis can provide a broad overview of the sentiment of a population towards a particular topic or brand, allowing decision-makers to make informed decisions based on data-driven insights.

History of Sentiment Analysis

Traditionally, sentiment analysis was performed using shallow learning techniques such as Support Vector Machines (SVMs) and Naive Bayes Classifiers. However, these techniques had several limitations, such as the inability to capture context and the need for a large annotated dataset for training.

Why use Transformers for Sentiment Analysis

Enter Transformers, a breakthrough in NLP that has revolutionized the field of sentiment analysis. Transformers are deep learning models that were introduced in 2017 by Vaswani et al. in the paper “Attention is All You Need”. They are based on the Transformer architecture and use self-attention mechanisms to process the input sequence, allowing the model to capture the context and dependencies between words.

  1. Improve context representation: Transformers use self-attention mechanisms to process the input sequence, allowing the model to capture the context and dependencies between words, leading to improved representation of the input text.
  2. Handling long sequences: Transformers are able to handle long sequences of text, making them well-suited for sentiment analysis where the context and dependencies between words play an important role.
  3. Large number of parameters: Transformers have a large number of parameters, allowing them to learn complex representations of the input text, resulting in improved performance compared to shallow learning methods.
  4. Pre-training: Many Transformer-based models, such as BERT, are pre-trained on large annotated datasets, providing a strong base for fine-tuning on specific NLP tasks, including sentiment analysis.
  5. State-of-the-art performance: Transformer-based models, such as BERT, have achieved state-of-the-art results on a variety of NLP tasks, including sentiment analysis, making them a popular choice for the task.

Enough theory!!! Let’s code…

# install transformers
!pip install transformers

The command pip install transformers is used to install the transformers package, which provides access to state-of-the-art Transformer-based models for NLP tasks, including sentiment analysis.

Once the transformers package is installed, you can import and use the Transformer-based models in your own projects

from transformers import pipeline

# create pipeline for sentiment analysis
classification = pipeline('sentiment-analysis')

The above code is a demonstration of how to use the transformers package for sentiment analysis in Python.

  1. Importing the pipeline class from the transformers package: The first line from transformers import pipeline imports the pipeline class from the transformers package. The pipeline class provides a simple and convenient interface to perform NLP tasks, including sentiment analysis, using pre-trained Transformer-based models.
  2. Creating a sentiment analysis pipeline: The second line classification = pipeline('sentiment-analysis') creates a sentiment analysis pipeline using the pipeline class. The argument 'sentiment-analysis' specifies the task to perform, which in this case is sentiment analysis.

With these two lines of code, you have created a sentiment analysis pipeline that can be used to classify the sentiment of a given text as positive, negative, or neutral. You can now use the classification object to perform sentiment analysis on any text by calling its predict method and passing the text as an argument.

Perform Sentiment Analysis on custom text

No need to convert input into pyTorch tensor, Numpy array or TensorFlow tensor. In this case we can simply pass raw text.

#let's try on simple movie reviews 
classification("I thoroughly enjoyed this movie!")
classification("I did not understand anything in this movie.")
Results on simple movie review
# let's try on difficult movie reviews
classification('''Although the movie had its flaws and some scenes were slow-paced,
I still found myself captivated by the strong performances and unique storyline.
The cinematography was stunning and added another level of depth to the film. Overall,
I would still recommend it for those looking for a thought-provoking movie experience.''')

classification('''At first, I was intrigued by the premise and was excited to see where the story would go.
However, as the movie progressed, I became disappointed by the lackluster execution and
underdeveloped characters. Despite a few moments of promise, the movie ultimately fell
flat for me and failed to deliver on its potential. Not recommended.''')

This pipeline is very flexible, we can pass list of reviews at a time and will get multiple outputs.

classification(["I thoroughly enjoyed this movie!",
"I did not understand anything in this movie."])
Multiple results

Sentiment Analysis on a custom dataset

# download dataset from given link for sentiment analysis
! wget https://www.dropbox.com/s/h5n6nl55bngk8rx/twitter.zip?dl=0

# Unzipping the data
!unzip -q "twitter.zip?dl=0"

The command is downloading the file twitter_training.csv from the URL ! wget https://www.dropbox.com/s/h5n6nl55bngk8rx/twitter.zip?dl=0 and unzip it. The file is a CSV (Comma-Separated Values) file containing training data for sentiment analysis on Twitter data.

# import required liabraries
from transformers import pipeline
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.metrics import roc_auc_score, f1_score, confusion_matrix
from sklearn.model_selection import train_test_split
# create pipeline for sentiment analysis
classification = pipeline('sentiment-analysis')
type(classification)

transformers.pipelines.text_classification.TextClassificationPipeline

TextClassificationPipeline is a pre-defined pipeline in the transformers library for text classification tasks. It consists of a sequence of pre-defined processing steps for natural language text data, such as tokenization, converting text into numerical representations (i.e., embeddings), and using these embeddings as input to a classifier. The purpose of this pipeline is to simplify the process of building and training a text classification model, allowing you to quickly train a model with good performance on your specific task.

Load twitter data

# read data into DataFrame
df = pd.read_csv("twitter_training.csv")
# set the columns
df.columns = ['id','entity','sentiment','Tweet content']
# drop null values
df = df.dropna()
# print first 5 rows
df.head()
# select only required columns
df = df[['sentiment','Tweet content']]

As this is the sentiment analysis, we require only text and label columns. Here they are sentiment and Tweet content.

Let’s check the number of classes available in dataset and their distribution.

df['sentiment'].hist()
Histogram

Here we have 4 number of classes in our dataset. As we are using pre-trained sentiment analysis model from Hugging Face which is trained on binary classes e.g. positive and negative. We are filtering positive and negative labeled data only.

# filter positive and negative sentiments only
df = df[(df.sentiment == 'Positive') | (df.sentiment == 'Negative')]

Now, we are only keeping positive and negative classes. Let’s check distribution now.

Now we have only 2 classes and almost balanced distribution of the classes.

target_map = { 'Positive': 1, 'Negative': 0}
df['target'] = df['sentiment'].map(target_map)

The first line defines a dictionary target_map that maps the original categorical target variable 'sentiment' to a numerical representation, with 'Positive' mapped to 1 and 'Negative' mapped to 0.

The second line applies this mapping to the ‘sentiment’ column of the DataFrame df using the map method and saves the result as a new column 'target' in the same DataFrame. This can be useful for training machine learning models, which often require numerical input variables.

texts = df['Tweet content'].to_list()

The code above is extracting the ‘Tweet content’ column from a Pandas DataFrame df and converting it to a list of text values.

The line df['Tweet content'] is selecting the 'Tweet content' column from the DataFrame df and returns it as a Pandas Series object. The to_list() method is then used to convert the Series object to a list of text values. The resulting list texts contains all the text values in the 'Tweet content' column of the DataFrame.

This is a common preprocessing step when working with text data in machine learning, as many models expect text inputs to be represented as lists of strings.

Predictions

predictions = classification(texts)

Here we are directly making predictions using pre-trained transformer. It will take a while.

printout few predictions

predictions[:10]

We got predictions in the form of list of dictionaries with label and score. See score for positive as well as negative classes showing near to 1. By using this score it will be difficult to evaluate performance. We will convert it into probabilities ranging from 0–1 with 0 tends to negative class ad 1 tends to positive class.

probs = [d['score'] if d['label'].startswith('P') else 1 - d['score'] for d in predictions ]

The code above is creating a list of probabilities from a list of dictionaries named “predictions”. Each dictionary in the list “predictions” has two keys: “label” and “score”.

The code iterates over each dictionary in the “predictions” list and applies the following logic for each dictionary:

  1. If the value of the “label” key starts with the letter “P”, it takes the value of the “score” key as the probability.
  2. If the value of the “label” key does not start with the letter “P”, it subtracts the value of the “score” key from 1 and takes that as the probability.

The result of this logic is a new list “probs” that contains the calculated probabilities.

# print few probabilities
probs[:10]
preds = [1 if d['label'].startswith('P') else 0 for d in predictions]

Extracting labels from prediction and creating new list. Here we are performing similar operation as we preformed above.

# convert into numpy array 
preds = np.array(preds)
print("acc:", np.mean(df['target'] == preds))

acc: 0.7869896772993583

The code calculates the accuracy of binary predictions stored in the list “preds” by comparing them with the true values stored in the “target” column of the dataframe “df”. The accuracy is calculated as the mean of a boolean array, which is created by element-wise comparison of the “target” and “preds”.

We got 78.69% accuracy. We are considering here accuracy as a evaluation matrix because we have almost balanced dataset.

Plot Confusion matrix

# calculate confusion matrix
cm = confusion_matrix(df['target'], preds)
# create function for plotting confusion matrix
def plot_cm(cm):
classes = ['negative','positive']
df_cm = pd.DataFrame(cm, index=classes, columns=classes)
ax = sns.heatmap(df_cm, annot = True, fmt='g')
ax.set_xlabel('Predicted')
ax.set_ylabel('Actual')

plot_cm(cm)
Confusion matrix

We have achieved 78% accuracy without conducting any training, showcasing the strength of Transformers. This was a high-level overview of the use of Transformers for Sentiment Analysis.

Next I plan to write additional blogs on Transformers where I will demonstrate how to fine-tune transformer models on custom datasets, as well as how to create transformer models from scratch and train them on custom datasets.

--

--