Company Earnings Sentiment Analysis with Python

In my previous post, we had a short introduction on how to analyse company earning calls using Python. In this post, we are going to take the company earning calls analysis a step further. We will perform a sentiment analysis based on the latest company earnings call using Python.

Sentiment Analysis Company Earnings Python
Photo by studio sason on Pexels.com

What is Sentiment Analysis?

A sentiment analysis refers to the use of natural language processing to analyse subjective information such as opinions or statements.

In other words, a sentiment analysis is the process for which we take a text (normally an opinion expressed by someone) in order to analyse it and try to extract a meaning out of it. We may use sentiment analysis to categorise a piece of text into a positive, negative or neutral statement. It is commonly applied to analyse opinions about a particular topic or product.

In this post, we will take the whole earning call transcript from a company (exactly as we did in my previous post) and perform a sentiment analysis on it.

As you probably know, the earning calls is a conference call between the management of a company and the media. During the call, management offers an overview of recent performance and provide a guidance for the next quarter expectations. This is where sentiment analysis may be useful. We can take the summary provided by management and apply sentiment analysis to it. That should give us some indication if management has a positive, neutral or negative perspective about the short term company performance.

Why is Python used for Sentiment Analysis?

Python has great libraries that make sentiment analysis super easy. Such libraries have built in the needed algorithms for the end user to perform a sentiment analysis of a very long text with only a couple of lines of code.

How can Python measure sentiment analysis?

Python sentiment packages are built based on specific guidelines which indicate the algorithm how to categorise each word in a sentence or text to a particular category (e.g. positive or negative). For example, words such as good, great, increase, excellent, etc. are associated to a positive opinion. While words such as bad, decrease, poor, etc. are associated to a negative opinion.

Therefore, when we pass a piece of text to the Python algorithm as input, this is analysed by looking into the text and searching for positive and negative words. Then, based on this, the algorithm produce an output categorising the text into positive, negative or neutral.

TextBlob to perform Sentiment Analysis with Python

We will use TextBlob, a very nice, easy to use and free library for sentiment analysis. We can install it by passing below command:

pip install -U textblob

You may also need to download NLTK punk and the necessary NLTK corpora as per below code. In case of troubles, you can always refer to the TextBlob get started documentation.

python -m textblob.download_corpora
nltk.download('punkt')

We will use the sentiment property from this package. This will take the company earning call as an input and give us a polarity and subjectivity score.

The polarity is a float which lies in the range of [-1,1] where 1 means a positive statement, 0 a neutral statement and -1 means a negative statement.

While Subjectivity is a float within the range [0.0, 1.0] where 0.0 is very objective and 1.0 is very subjective.

We will see it in action in the next section of the post.

Sentiment Analysis and Company Earnings

Let’s start with the company earnings Sentiment Analysis with Python. First of all, we import all required packages. Remember from the previous post on how to analyse earning calls with Python, that we are using financialmodelingprep to get the earning call transcript. For that to work, you need to sign up to get a free API key (i.e. 250 free API requests per month). Then pass your API key as the value of the demo variable.

We will analyse Apple earnings.

from textblob import TextBlob
import numpy as np
import requests
import pandas as pd
import nltk
demo = 'your api key'
company = 'AAPL'

Next, we make the request to the API end point to get the full earnings transcript from the latest company call.

transcript = requests.get(f'https://financialmodelingprep.com/api/v3/earning_call_transcript/{company}?quarter=3&year=2020&apikey={demo}').json()

transcript = transcript[0]['content']
print(transcript)

#outcome
Operator: Good day, everyone.
Welcome to the Apple Incorporated Third Quarter Fiscal Year 2020 Earnings Conference Call.
Good afternoon and thank you for joining us.
Good afternoon, everyone.
We've lost a hero who walked among us, a leader in the truest sense who urged this country to aim higher and be better until the very end.
I was humbled and for....

Great, now we have in the variable transcript the full transcript from the latest Apple earnings call. We are ready to perform a sentiment analysis on it.

To do that, we just need to pass the variable transcript as an argument of TextBlob. We store the object in a variable call sentiment_call.

Note: Remember to install the TextBlob package as shown in the previous section.

sentiment_call = TextBlob(transcript)

Now, we are able to use the different properties provided by TextBlob in order to apply sentiment analysis to our earnings transcript.

First, we will apply a sentiment analysis to the full earnings call. Then, we will split the earnings call transcript into sentences and compute the sentiment analysis for each of them individually. Finally, we will compute a sentiment analysis score based on the average score of each of the individual sentences.

Overall Sentiment Analysis

To perform a sentiment analysis to the full earnings, we just need to use the property sentiment on the text that we want to analyse. In our case, the variable transcript:

print(sentiment_call.sentiment)
#outcome
Sentiment(polarity=0.16686529115695806, subjectivity=0.462708070083069)

The outcome shows that the overall sentiment of the call is positive with a polarity score of 0.16 and a subjectivity score of 0.46.

As a whole, we see that the earnings call sentiment was categorised as positive with a score of 0.16. The score is positive but rather low. Let’s see if the result changes by looking into each sentence separately.

Sentiment Analysis for each sentence

With TextBlob we can break the text into words and sentences easily using Tokenisation. Let’s do that to our script by using the property sentences in our sentiment_call object:

print(sentiment_call.sentences)
#outcome
[Sentence("Operator: Good day, everyone."),
 Sentence("Welcome to the Apple Incorporated Third Quarter Fiscal Year 2020 Earnings Conference Call."),
 Sentence("Today's call is being recorded."),
 Sentence("At this time, for opening remarks and introductions, I would like to turn things over to Mr. Tejas Gala, Senior Manager, Corporate Finance and Investor Relations."),
 Sentence("Please go ahead, sir."),
 Sentence("Tejas Gala: Thank you."),
 Sentence("Good afternoon and thank you for joining us."),
 Sentence("Speaking first today is App

Great, next let’s count the number of positive and negative sentences in our transcript. We also append the sentiment score of each of the sentences to a Python list. So later, we can calculate the average score:

sentiment_call.sentences
negative = 0
positive = 0
neutral = 0
all_sentences = []

for sentence in sentiment_call.sentences:
  #print(sentence.sentiment.polarity)
  if sentence.sentiment.polarity < 0:
    negative +=1
  if sentence.sentiment.polarity > 0:
    positive += 1
  else:
    neutral += 1
 
  all_sentences.append(sentence.sentiment.polarity) 

print('positive: ' +  str(positive))
print('negative: ' +  str(negative))
print('neutral: ' + str(neutral))

#outcome:
positive: 218
negative: 51
neutral: 207

Finally, we can compute the average score of all sentences using Numpy:

all_sentences = np.array(all_sentences)
print('sentence polarity: ' + str(all_sentences.mean()))
#outcome
sentence polarity: 0.15182078480887307

We have completed the sentiment analysis of the latest Apple earning call. We can see that the overall sentiment from management toward the company future is rather a weak positive (from 0.15 to 0.17). In line to the 0.16 obtained when we looked at the whole text.

Sentiment Analysis Limiations

Some of the limitations of this kind of sentiment analysis is the fact that some of the sentences containing words such as good afternoon will be categorised as a positive statement when they should not. This will create a positive bias by inflating the score towards positive ranges.

For example, if we print all sentences with a very strong positive polarity:

for sentence in sentiment_call.sentences:
  if sentence.sentiment.polarity > 0.8:
     print(sentence)

#outcome
- iPad performance was equally impressive with revenue of $6.6 billion, up 31% and our highest June quarter revenue in eight years.
- Amit Daryanani: Perfect, that's helpful.
- We believe based on what we've heard that it's the fastest rollout in the history of credit cards and so we feel very good about that.

We see that out of the three sentences with a strong positive score, the second one is just a thank you note that should not be categorised as a positive statement.

This could be avoided by performing some clean up before processing the text. But this may be super time consuming in long texts.

Sentiment Analysis with Python

Wrapping Up

We only covered a part of what TextBlob offers, I would encourage to have a look at the documentation to find out about other Natural Language capabilities offered by Text Blob.

One thing to take into account is the fact that company earnings call may be a bias since it is company management who is trying to defend their performance. Therefore, we should expect management to express a positive bias toward future and recent company performance.

In addition to looking into company earnings call, we could analyse customer opinions on company products to complement the sentiment analysis. We can do that, for example, by taking user tweets about company products. We will do that in my next post.

Hope you have liked the post! See below code for your reference:

from textblob import TextBlob
import numpy as np
import requests
import pandas as pd
import nltk
demo = 'your api key'
#nltk.download('punkt')
company = 'AAPL'

transcript = requests.get(f'https://financialmodelingprep.com/api/v3/earning_call_transcript/{company}?quarter=3&year=2020&apikey={demo}').json()

transcript = transcript[0]['content']
print(transcript)

sentiment_call = TextBlob(transcript)

print(sentiment_call.sentiment)
print(sentiment_call.sentences)

sentiment_call.sentences
negative = 0
positive = 0
neutral = 0
all_sentences = []

for sentence in sentiment_call.sentences:
  #print(sentence.sentiment.polarity)
  if sentence.sentiment.polarity < 0:
    negative +=1
  if sentence.sentiment.polarity > 0:
    positive += 1
  else:
    neutral += 1
 
  all_sentences.append(sentence.sentiment.polarity) 

print('positive: ' +  str(positive))
print('negative: ' +  str(negative))
print('neutral: ' + str(neutral))

all_sentences = np.array(all_sentences)
print('sentence polarity: ' + str(all_sentences.mean()))

for sentence in sentiment_call.sentences:
  if sentence.sentiment.polarity > 0.8:
     print(sentence)