Twitter Sentiment Analysis Using Zero-Shot Classification

Are you looking for a way to quickly assess the sentiment of public companies through their tweets without previously training any ML models? The OpenAI API provides powerful, zero-shot classification capabilities so that text data can be classified into multiple categories – regardless of whether or not the model has encountered those categories.

This guide explains each step using excellent tools from OpenAI for an effective and precise analysis of corporate tweet sentiment! With accurate insight into a company’s image and overall perception, anyone – from traders and investors alike – can make more informed investment decisions quickly and confidently.

Why Should You Classify Public Company Tweets Sentiments?

Studying how people feel about public companies via Twitter posts is essential for many reasons. Research shows their opinions affect share prices – when sentiment is high, so too are the costs, whereas poor attitudes lead to lower values on the market. Additionally, investors use sentiment analysis data to assess a brand’s image and predict future successes (or failures) based on events like new products or controversial scandals, which helps them decide if they should purchase shares in that business.

What is Zero-Shot Classification?

Zero-shot classification is a machine-learning technique that enables models to classify data that it has never seen before, making it a versatile and valuable tool in modern machine-learning applications.

Zero-shot sentiment analysis lets models use their knowledge on data they’ve never encountered before – making it perfect for analyzing sentiments – like public company tweets – or any written material. For example, suppose you train a model to identify movie reviews as either positive or negative. In that case, it doesn’t matter how many movies it has previously come across – with zero-shot sentiment analysis, the model will sort out new reviews successfully and have them fall under one of those two categories!

Pros and Cons of Zero-Shot Classification?

Following are some pros and cons of zero-shot classification.

Zero-Shot Classification Pros

  • It enables models to classify data that it has never seen before.
  • Reduces the need for retraining by recognizing relationships between different categories.
  • Useful for multilingual models as it can recognize and classify text in different languages without specific training in each language
  • Enables more flexible and efficient systems that can handle a wide range of inputs without constant retraining

Zero-Shot Classification Cons

  • It can be less accurate than traditional classification methods trained on specific categories.
  • It relies heavily on the model’s initial training data quality.
  • It may not work well for tasks that require fine-grained distinctions between categories.
  • It may not be suitable for tasks where accuracy is critical, and the consequences of inaccurate classification can be significant.

What Is OpenAI API?

OpenAI API is a suite of tools and services offered by OpenAI, an AI research and development company. The API provides access to cutting-edge machine learning models, including language models, text generators, and image recognition models. It allows developers to integrate state-of-the-art AI technologies into their applications without building and training models from scratch.

OpenAIs GPT-3, Codex, and Content filtering models allow you to implement advanced text classification, summarization, question answering, and chatbot applications.

You can learn more about these models from my OpenAI API Crash Course and how to transcribe audio in my OpenAI Whisper tutorial.

Getting Started with Twitter API

Twitter provides an easy-to-use API for retrieving tweets. The Twitter developer portal provides API keys that allow you to connect to the Twitter API. Once you have your API keys, you can use the Python Tweepy module to request the Twitter API in Python.

Creating a Twitter Developer Account

A standard Twitter account works as a developer account. All you have to do is create a Twitter account (if you haven’t already) and go to the Twitter Developer Portal.

Click the “Developer Portal” option from the top-right corner.

Getting Twitter API Key and Secret

To fetch your API Keys, create a Project or a Standalone App in your developer portal. I will make a standalone app.

Click the “Overview” link from the left sidebar of the developer portal. Scroll down to see a list of all your existing standalone apps. The list will be empty if you do not have any previous standalone apps.

Click the “+Create App” button to create a new app.

Give a name to your app and click the “Next” button.

You will see your API Key, API Secret, and Bearer Token. You only need your API key and API secret to search tweets. Save these values in a secure place. Environment variables are a good option for storing API keys and secrets.

Scraping Public Company Tweets Using Python Tweepy API

We will use the Python Tweepy library to scrap tweets from Twitter API. You can install the Tweepy library with the following “pip” command.

pip install tweepy

You must create a Twitter API authentication handle and an API object to fetch Tweets using Tweepy. The AppAuthHandler object allows to create a Twitter API authentication handle. You must pass your Twitter API key and secret to the AppAuthHandler object. Next, you need to pass the AppAuthHandler object to the Tweepy.API class constructor to create an API object.

import tweepy
import os

twitter_api_key = os.environ['TWITTER_API_KEY']
twitter_api_secret = os.environ['TWITTER_API_KEY_SECRET']

authentication = tweepy.AppAuthHandler(twitter_api_key, twitter_api_secret)
api_object = tweepy.API(authentication)

As an example, this tutorial will fetch tweets relevant to Microsoft. In the next section, you will see how to find the sentiment of these tweets using zero-shot classification. You can search tweets for any other public company if you want.

The search_tweets() method from the API object allows you to search and fetch tweets. You must pass the query containing information about the tweet you want to search to the q parameter of the search_tweets() method.

In the following script, we will use the query “microsoft -filter:retweets -filter:replies” which fetches tweets with the following characteristics:

  • microsoft: searches for the tweets relevant to Microsoft. Twitter API returns the most relevant tweets matching the searched text. In response, you might see tweets that do not contain the term Microsoft. Twitter returns the tweets it thinks are most relevant to the searched query.
  • -filter:retweets: will remove all the retweets from the response and only return the original tweets.
  • -filter:replies: removes all the tweets that are in reply to some other tweets. You can remove this filter if you want. But In my case, there were many very similar replies, so I removed all tweets that replied to another tweet.

The lang parameter species language of the tweets you want to return. You must pass an ISO 639-1 language code to the lang parameter.

The result_type parameter species whether you want to return recent, most popular, or mixed tweets. The “recent” value returns the most recent tweets.

The count parameter defines the number of tweets to return in one request. The search_tweets() method returns a maximum of 100 tweets in a single request.

You can check the official documentation to see the details of all parameter values for the search_tweets() method.

The search_tweets() method returns a collection of tweets matching your search criteria. You can iterate through the collection to fetch information from an individual tweet.

In the following script, we retrieve ids, tweet creation times, user screen names of the author, and the tweets’ texts. We store these values in a list of dictionaries, which we convert into a Pandas DataFrame.

import pandas as pd

tweet_dataset = []
tweets = api_object.search_tweets(q='microsoft -filter:retweets -filter:replies',
                                  lang = "en",
                                  result_type="recent",
                                  count = 100
                                 )
 
for tweet in tweets:
    tweet_content = {'id': tweet.id,
                    'date': tweet.created_at,
                  'user_name':tweet.user.screen_name,
                  'text':tweet.text,
                  
                 }

    tweet_dataset.append(tweet_content)

tweet_dataframe = pd.DataFrame(tweet_dataset)
print(tweet_dataframe.shape)
tweet_dataframe.head()

You can implement pagination to retrieve more than 100 records via Tweepy. To do so, you can use the max_id parameter of the search_tweets() method. The max_id parameter defines the id of the last tweet you want to retrieve. Twitter assigns an id to each tweet. Recent tweets have a greater id number than the old tweets.

You can execute the search_tweets() inside a for loop to implement pagination. Assign none as the initial for the max_id attribute. Then in each iteration, update the max_id with the id of the last tweet i.e., tweet with the smallest id. In the next iteration, the search_tweets() method will return tweets with ids less than the current max_id. For example, if you retrieve 100 tweets in each iteration, the first iteration will return the 100 latest tweets. The second iteration will retrieve the subsequent 100 most recent tweets with ids less than the id of the 100th tweet retrieved previously.

The following script implements pagination with ten iterations of for loops. In the output, you will see 997 tweets. I don’t know why it didn’t return 1000 tweets. A possible reason could be that it didn’t find 100 relevant tweets in one or multiple iterations.

tweet_dataset = []

max_id = None

for i in range(10):
    
    tweets = api_object.search_tweets(q='"microsoft" -filter:retweets -filter:replies',
                                      lang = "en",
                                      result_type="recent",
                                      count = 100,
                                      max_id=max_id
                                     )
    for tweet in tweets:
        tweet_content = {'date': tweet.created_at,
                          'user_name': tweet.user.screen_name,
                          'text': tweet.text,
                        }
        tweet_dataset.append(tweet_content)
    if len(tweets) == 0:
        break
    max_id = tweets[-1].id - 1

# Convert the list of dictionaries into a DataFrame
tweet_dataframe = pd.DataFrame(tweet_dataset)
print(tweet_dataframe.shape)
tweet_dataframe.head()

Let’s print the tweet’s text at the 0th index in our dataset.

tweet_dataframe['text'].iloc[0]

The tweet text clearly shows that the tweet contains a positive sentiment.

In the next section, you will use the OpenAI API to detect the sentiments of all tweets in our dataset.

Zero-Shot Classification of Tweets with OpenAI

Since we will use zero-shot classification for the sentiment analysis of tweets in our dataset, we do not need to perform any training on our dataset. We will pass the tweet text to an OpenAI model and get the tweet’s sentiment in response.

The following pip command installs the OpenAI Python library.

pip install openai

You can look at my detailed article on OpenAI API: Complete Python Tutorial to see how to connect to the OpenAI API and perform various NLP tasks.

In the next section, you will see how to get sentiments for all tweets in our dataset and store them in the sentiments column of the Pandas dataframe containing tweets.

Creating Dataset Containing Tweets Sentiments

The following script defines the get_sentiment() method, which accepts tweet text as a parameter value and returns the sentiment of the text.

Inside the get_sentiment() method, we call open.Competion.create() method uses the OpenAI text-davinci-003 model to fetch the tweet sentiment. The prompt value informs the model that we want to classify the tweet’s sentiment as positive, negative, or neutral towards Microsoft. You can add more sentiments if you wish. Crafting the right prompt is vital to retrieving the correct sentiment.

import openai
import re

api_key = os.getenv('OPENAI_KEY')
openai.api_key = api_key

def get_sentiment(text):

    prompt_text = """Classify the sentiment of the following tweet as positive, negative, or neutral towards Microsoft. 
    text: {}
    sentiment: """.format(text)

    sentiment = openai.Completion.create(
                  model="text-davinci-003",
                  prompt = prompt_text,
                  max_tokens= 15,
                  temperature=0,
                  )

    # remove special characters e.g n etc, from response
    sentiment = re.sub('W+','', sentiment['choices'][0]['text'])
    
    return sentiment

We will add a sentiment column to the Pandas Dataframe containing the tweets. The Pandas apply() method allows us to call the get_sentiment() method on each row of a Pandas Dataframe.

Fetching sentiments for a large number of tweets can take some time. You can use the tqdm.pandas() method to keep track of the progress of the Pandas apply() method.

from tqdm import tqdm
tqdm.pandas()

tweet_dataframe['sentiment'] = tweet_dataframe['text'].progress_apply(get_sentiment)
tweet_dataframe.head()

You can see that our Pandas Dataframe now contains a sentiment column.

Let’s plot a bar plot displaying the number of positive, negative, and neutral tweets.

import seaborn as sns
sns.set_style("darkgrid")
sns.set(rc={'figure.figsize':(10,7)})
sns.set_context("poster")

print(tweet_dataframe['sentiment'].value_counts())
sns.countplot(x='sentiment', data = tweet_dataframe)

As expected, the majority of tweets have a neutral sentiment. The number of tweets with positive sentiments significantly outperforms negative sentiment tweets.

Let’s plot some tweets with positive sentiments to see how well the OpenAI model classified tweet sentiments.

positive_tweets = tweet_dataframe[tweet_dataframe['sentiment'] == 'Positive']['text'].tolist()
for i, pos in enumerate(positive_tweets[10:15]):
  print(i, " - ", pos)

The output shows that the majority of the tweets have a positive sentiment. Pretty impressive? Without training on our dataset, the OpenAI DaVinci model is more than capable of predicting the sentiments in our dataset.

Let’s see some tweets with negative sentiments.

negative_tweets = tweet_dataframe[tweet_dataframe['sentiment'] == 'Negative']['text'].tolist()
for i, neg in enumerate(negative_tweets[10:15]):
  print(i, " - ", neg)

Again you can see that all the tweets express negative sentiments.

Once you have tweets discussing public companies and their sentiments, you can perform any downstream task.

For instance, you can perform topic modeling to see which topics mostly appear in negative or positive tweets. This can explain why people think investing in a particular stock is good or bad. You can summarize collections of positive or negative tweets. You can also analyze the tweets’ sentiment time series if you have date and time information.

In the next section, we will perform a time series analysis of sentiments expressed in tweets related to Microsoft.

Time Series Plots for Tweets Sentiments

We will perform the following steps in this section.

  1. We will set the date column as the index of our Pandas DataFrame, and sort the rows by the ascending order of the date values.
  2. We will find the cumulative sentiment count for positive, negative, and neutral sentiments in our dataset. We will then convert the cumulative sentiment count to percentages.
  3. We will plot line-plot and area-plot for the percentages of sentiments at every 10th-time step in our dataset.

The following script sets the date column as the index column in our Pandas DataFrame and sorts the rows by the ascending order of the values in the date column.

tweet_dataframe['date'] = pd.to_datetime(tweet_dataframe['date'])
tweet_dataframe.set_index('date', inplace=True)
tweet_dataframe = tweet_dataframe.sort_values(by='date', ascending=True)
tweet_dataframe.head()

Next, we need to find the cumulative sum of all sentiments for each row. The Pandas cumsum() method can find the cumulative sum.

tweet_dataframe['positive_sent'] = (tweet_dataframe['sentiment'] == 'Positive').cumsum()
tweet_dataframe['negative_sent'] = (tweet_dataframe['sentiment'] == 'Negative').cumsum()
tweet_dataframe['neutral_sent'] = (tweet_dataframe['sentiment'] == 'Neutral').cumsum()
tweet_dataframe.head()

You can see the cumulative sums of all sentiments in the above Pandas DataFrame. For example, in the 5th row, you can see 3 as the cumulative sentiment count for the positive sentiment. This is because 3 rows contain positive sentiments out of the first five rows. Similarly, you can see 2 as the cumulative sentiment count for the neutral sentiment.

We want to convert the cumulative sentiment counts to percentage values. For instance, in the 5th row, 60% of all the sentiments are positive, while 40% are neutral. The following script finds the cumulative percentage values.

row_sum = tweet_dataframe[['positive_sent', 'negative_sent', 'neutral_sent']].sum(axis=1)


tweet_dataframe['positive_sent'] = tweet_dataframe['positive_sent'] / row_sum * 100
tweet_dataframe['negative_sent'] = tweet_dataframe['negative_sent'] / row_sum * 100
tweet_dataframe['neutral_sent'] = tweet_dataframe['neutral_sent'] / row_sum * 100

tweet_dataframe.head(40)

We now have everything we need to plot a time series plot of sentiment percentages. You can plot time series plots of individual time steps. In the later time steps, the percentage values won’t fluctuate much. I recommend using a larger window size for time series plots. I will use a window size of 10. You can use a different value if you want.

The following script fetches every 10th row from our Pandas Dataframe.

window_size = 10

time_series_df = tweet_dataframe.iloc[window_size-1::window_size]
time_series_df.head()

Let’s draw a line plot using Pandas Seaborn library to see how sentiments fluctuate.

import matplotlib.pyplot as plt

sns.set_context("notebook")

time_series_df.plot(y = ["positive_sent", "negative_sent", "neutral_sent"], 
                    kind = "line", 
                    figsize = (10, 8)).legend(loc='lower right')

You can see that 60% to 70% of the tweets related to Microsoft in the last 5 minutes have neutral sentiment, while 30% to 40% have a positive sentiment. Only 5% to 10% of the tweets have negative. It is probably a good time to invest in Microsoft right now.

The sample size is tiny, i.e., 5 minutes, but it shows how to fetch sentiment from tweets related to public companies and see how the sentiment fluctuates over time.  

You can draw other types of plots to visualize the time series information. For instance, the following script plots a stacked area plot which shows that neutral tweets occupy the majority of surface area over time, followed by positive and negative tweets.

time_series_df.plot(y = ["negative_sent", "positive_sent",  "neutral_sent"], 
                    kind = "area", 
                    figsize = (10, 8),
                    color=( '#FF8D41', '#4C8D34', '#8CCFF0')).legend(loc='lower right')

OpenAI and Tweepy Alternatives

Following are some services similar to OpenAI.

  1. Hugging Face
  2. Microsoft Azure
  3. IBM Watson
  4. Google Cloud
  5. AWS

Below are some alternatives to Tweepy.

  1. Twint
  2. Python-twitter
  3. Twython

You can also use the Python requests module to call Twitter REST API.

Frequently Asked Questions

Can Twitter Predict Stocks?

Studies indicate a connection between Twitter sentiment and stock prices, but investors should factor in other elements when making decisions, as the platform alone is not a reliable predictor.

How Does Twitter Influence the Stock Market?

Twitter can influence stock market trends by providing real-time info, spreading rumors, being used for company promotion or announcements, and expressing opinions that shape public sentiment.

How Does Elon Musk Affect Stock Market?

Elon Musk’s tweets have had a major impact on stock markets. In May 2020, his dissatisfaction with Tesla’s stock price caused shares to drop by 10%. Similarly, when he announced Tesla would invest $1.5 billion in Bitcoin in February 2021, the cryptocurrency surged by over 10%. This demonstrates how influential an entrepreneur’s words can be for financial markets.

How Do You Evaluate Zero-shot Classification?

Evaluate your zero-shot classification model’s performance with traditional metrics such as accuracy, F1, and confusion matrix. Test it on a small sample of annotated data before using it to predict unseen data for reliable results.

Which Model Is Best for Zero-shot Text Classification?

The accuracy of zero-shot text classification models depends on the initial training data used to train the model. If you cannot find a domain-specific zero-shot classification model, the OpenAI DaVinci model with 175 billion parameters usually returns the best results.

What Is Unsupervised vs. Zero-shot?

Zero-shot classification is a supervised learning technique that uses labeled training datasets to uncover hidden patterns in data. Unlike unsupervised learning, which relies on unlabeled or unannotated datasets, zero-shot classification models can generalize beyond the training dataset and provide accurate predictions without human supervision.

What are Tweepy Rate Limits?

The Python Tweepy library does not set its own rate limits for accessing the Twitter API. Instead, you can check out the official documentation to view rate limits for various Twitter API subscriptions and methods. To see your current status of rate limits, use the Tweepy API object’s rate_limit_status() method.

The Bottom Line

Sentiment analysis of tweets related to public companies is helpful for traders and investors looking to make informed decisions. With the help of the OpenAI API, it’s now possible to efficiently analyze public company tweets and gain valuable insights into the company’s brand image and public perception.

In this tutorial, you saw how to fetch public company tweets using Tweepy and use the OpenAI API zero-shot classification models to accurately classify tweets’ sentiments without prior training data. You also studied how to perform a time series analysis of tweet sentiments over time.

Using the OpenAI API’s zero-shot classification and time series analysis techniques, you can create powerful tools to analyze public perception and sentiment towards specific companies or industries.

Leave a Comment