Classification of Tweet Sentiments on Synovus Bank

This project is developed as a demonstration of my experience in handling unstructured data. The business case considered here is:

" To understand the online behavior of customers of "Synovus Bank" using their Twitter Data "

Aim of this project:

1) Find the percentage of Positive, Negative and Neutral Tweets
2) Analyze the tweets and understand the customer behavior for taking Decisions for optimizing customer satisfaction
3) Suggest the ideas to the business team
Step 1 - Importing the dependenices and python libraries

In [14]:
'''
Importing the dependencies
"re" - for regular expression functionalities to handle the textual data

tweepy - this is the python client for the official Twitter API

tweepy's OAuthHandler - Twitter has the developer account who can download the tweets from twitter website. Every developer
has a customer key and access token. When this valid combination is given in the program, it makes a call to the twitter API
and download the required number of tweets accordingly

textblob - this is the NLP library to handle the polarity(sentiment) of the textual data (here text data is tweets) '''

import re
import tweepy
from tweepy import OAuthHandler
from textblob import TextBlob

Step -2 : Functionalities covered

1) Validate the developer's account to download the tweets
2) Clean tweets using python regex
3) obtain the tweet's sentiment using python's textblob nlp library
4) Function to download tweets and parse them

In [15]:
class TwitterClient(object):
    '''
    Generic Twitter Class for sentiment analysis.
    '''
    def __init__(self):
        '''
        Class constructor or initialization method.
        '''
        # keys and tokens from the Twitter Dev Console
        consumer_key = 'SnnT3pizFAHViBKU6qE013XuY'
        consumer_secret = 'dY7Gksp2yCvV5YxQMJjeTbAGvYRsBx831aQfccHhAsoRjOo7RJ'
        access_token = '166258894-zjBbDnhNJPwL0b2jDGERUIyoa6QOrQF8iLfRzcrP'
        access_token_secret = 'r7PVqYRAuI1Wo2awFwgJDxgFq1KHW4pn5jQrb3FWeAWbT'
 
        # attempt authentication
        try:
            # create OAuthHandler object
            self.auth = OAuthHandler(consumer_key, consumer_secret)
            # set access token and secret
            self.auth.set_access_token(access_token, access_token_secret)
            # create tweepy API object to fetch tweets
            self.api = tweepy.API(self.auth)
        except:
            print("Error: Authentication Failed")
 
    def clean_tweet(self, tweet):
        '''
        Utility function to clean tweet text by removing links, special characters
        using simple regex statements.
        '''
        return ' '.join(re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)", " ", tweet).split())
    
    def get_tweet_sentiment(self, tweet):
        '''
        Utility function to classify sentiment of passed tweet
        using textblob's sentiment method
        '''
        # create TextBlob object of passed tweet text
        analysis = TextBlob(self.clean_tweet(tweet))
        # set sentiment
        if analysis.sentiment.polarity > 0:
            return 'positive'
        elif analysis.sentiment.polarity == 0:
            return 'neutral'
        else:
            return 'negative'
 
    def get_tweets(self, query, count = 10):
        '''
        Main function to fetch tweets and parse them.
        '''
        # empty list to store parsed tweets
        tweets = []
 
        try:
            # call twitter api to fetch tweets
            fetched_tweets = self.api.search(q = query, count = count)
 
            # parsing tweets one by one
            for tweet in fetched_tweets:
                # empty dictionary to store required params of a tweet
                parsed_tweet = {}
 
                # saving text of tweet
                parsed_tweet['text'] = tweet.text
                # saving sentiment of tweet
                parsed_tweet['sentiment'] = self.get_tweet_sentiment(tweet.text)
 
                # appending parsed tweet to tweets list
                if tweet.retweet_count > 0:
                    # if tweet has retweets, ensure that it is appended only once
                    if parsed_tweet not in tweets:
                        tweets.append(parsed_tweet)
                else:
                    tweets.append(parsed_tweet)
 
            # return parsed tweets
            return tweets
 
        except tweepy.TweepError as e:
            # print error (if any)
            print("Error : " + str(e))

In [16]:
def main():
    # creating object of TwitterClient Class
    api = TwitterClient()
    # calling function to get tweets
    tweets = api.get_tweets(query = '@synovus', count = 1000)
 
    # picking positive tweets from tweets
    ptweets = [tweet for tweet in tweets if tweet['sentiment'] == 'positive']
    
    # percentage of positive tweets
    print("Positive tweets percentage: {} %".format(100*len(ptweets)/len(tweets)))
    
    # picking negative tweets from tweets
    ntweets = [tweet for tweet in tweets if tweet['sentiment'] == 'negative']
    
    # percentage of negative tweets
    print("Negative tweets percentage: {} %".format(100*len(ntweets)/len(tweets)))
   
    # percentage of neutral tweets
    
    print("Neutral tweets percentage: {} %".format(100*(len(tweets) - len(ntweets) - len(ptweets))/len(tweets)))
 
    # printing first 5 positive tweets
    print("\n\nPositive tweets:")
    for tweet in ptweets[:5]:
        print(tweet['text'])
     
    # printing first 5 negative tweets
    print("\n\nNegative tweets:")
    for tweet in ntweets[:
                         5]:
        print(tweet['text'])
    
if __name__ == "__main__":
    # calling main function
    main()


Positive tweets percentage: 56.25 %
Negative tweets percentage: 20.833333333333332 %
Neutral tweets percentage: 22.916666666666668 %


Positive tweets:
@synovus I heard the DJ was amazing! @WillRArd
RT @synovus: We've hidden five $1,000 gift cards in east Atlanta near our new Reynoldstown branch. Find them Nov. 11., starting at 11 a.m!…
.@synovus supporting #ChildProtectionCenter    in their mission to prevent child abuse & provide intervention & tre… https://t.co/eZCH8LRFo3
@synovus Again: Do the right thing and give that $5000 to something other than your promotion. Such as helping the… https://t.co/tIQ1UNpIbQ
RT @SDS: What are your favorite local traditions? We recently asked some fans. Presented by @Synovus, the bank of here. https://t.co/QlvLq1…


Negative tweets:
RT @synovus: Our brand conversion begins this week with new signs in Tampa/St. Pete! One down, 250+ to go! Chattanooga/Cohutta Bank is next…
Langston's Davis is Fifth @synovus and @GeoSouthernCOE Teacher of the Game Winner https://t.co/dmkzqSIJqI… https://t.co/DcEPazEcCW
This week's @COEAlumniSpotlight is a @synovus Teacher of the Game and the 2016 Langston Chapel Middle School Teache… https://t.co/SqyEMfI6UF
@synovus Maybe you should give the $5000 to poor black families that have been pushed out of their family homes in… https://t.co/ckKR02qOzO
The fucking Twitter ads from this place are every reason to hate gentrification. Stop this shit @synovus You're a f… https://t.co/kTuLjbIB5h