avatarAbhijat Sarari

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

6748

Abstract

pan class="hljs-built_in">print</span>(<span class="hljs-string">"Classification Report:\n"</span>, classification_report(y_test, y_pred))</pre></div><p id="8f84">This gives us an idea of how well the model is performing in terms of predicting the correct sentiments.</p><h1 id="5996">Step 7: Creating a Dashboard for Data Visualization</h1><p id="3ce4">We will create a simple dashboard to visualize the sentiment distribution, word cloud, and confusion matrix.</p><div id="b128"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">create_dashboard</span>(): fig, axes = plt.subplots(<span class="hljs-number">2</span>, <span class="hljs-number">2</span>, figsize=(<span class="hljs-number">15</span>, <span class="hljs-number">10</span>))

<span class="hljs-comment"># Sentiment Distribution</span>
sns.countplot(x=<span class="hljs-string">'polarity'</span>, data=tweets, ax=axes[<span class="hljs-number">0</span>, <span class="hljs-number">0</span>])
axes[<span class="hljs-number">0</span>, <span class="hljs-number">0</span>].set_title(<span class="hljs-string">'Sentiment Distribution'</span>)

<span class="hljs-comment"># Word Cloud</span>
text = <span class="hljs-string">' '</span>.join(tweets[<span class="hljs-string">'text'</span>])
wordcloud = WordCloud(width=<span class="hljs-number">800</span>, height=<span class="hljs-number">400</span>, background_color=<span class="hljs-string">'white'</span>).generate(text)
axes[<span class="hljs-number">0</span>, <span class="hljs-number">1</span>].imshow(wordcloud, interpolation=<span class="hljs-string">'bilinear'</span>)
axes[<span class="hljs-number">0</span>, <span class="hljs-number">1</span>].axis(<span class="hljs-string">'off'</span>)
axes[<span class="hljs-number">0</span>, <span class="hljs-number">1</span>].set_title(<span class="hljs-string">'Word Cloud'</span>)

<span class="hljs-comment"># Sentiment Pie Chart</span>
sentiment_counts = tweets[<span class="hljs-string">'polarity'</span>].value_counts()
<span class="hljs-comment"># Check the unique values in the 'polarity' column</span>
labels = sentiment_counts.index.tolist() 
axes[<span class="hljs-number">1</span>, <span class="hljs-number">0</span>].pie(sentiment_counts, labels=labels, autopct=<span class="hljs-string">'%1.1f%%'</span>, startangle=<span class="hljs-number">140</span>) <span class="hljs-comment">#Use the labels derived from the sentiment_counts variable</span>
axes[<span class="hljs-number">1</span>, <span class="hljs-number">0</span>].set_title(<span class="hljs-string">'Sentiment Pie Chart'</span>)

<span class="hljs-comment"># Confusion Matrix</span>
sns.heatmap(confusion_matrix(y_test, y_pred), annot=<span class="hljs-literal">True</span>, fmt=<span class="hljs-string">'d'</span>, cmap=<span class="hljs-string">'Blues'</span>, ax=axes[<span class="hljs-number">1</span>, <span class="hljs-number">1</span>])
axes[<span class="hljs-number">1</span>, <span class="hljs-number">1</span>].set_title(<span class="hljs-string">'Confusion Matrix'</span>)
axes[<span class="hljs-number">1</span>, <span class="hljs-number">1</span>].set_xlabel(<span class="hljs-string">'Predicted'</span>)
axes[<span class="hljs-number">1</span>, <span class="hljs-number">1</span>].set_ylabel(<span class="hljs-string">'Actual'</span>)

plt.tight_layout()
plt.show()

create_dashboard()</pre></div><p id="9e60">Output:</p><figure id="a0bb"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*XZyD5bqaUUyiW5-SRNSfPg.png"><figcaption></figcaption></figure><p id="df0c">This dashboard includes four components:</p><ol><li><b>Sentiment Distribution</b> — A bar chart showing the number of positive, neutral, and negative tweets.</li><li><b>Word Cloud</b> — A visual representation of the most common words in the dataset.</li><li><b>Sentiment Pie Chart</b> — A pie chart showing the percentage distribution of sentiment categories.</li><li><b>Confusion Matrix</b> — A heatmap showing the performance of the model’s predictions.</li></ol><h1 id="8ddd">Step 8: Real-Time Tweet Sentiment Prediction</h1><p id="d7f1">We add a function to predict the sentiment of a tweet entered by the user. Using <code>ipywidgets</code>, we create a simple input box for the user to enter a tweet and get real-time sentiment predictions. We also display sample tweets on demand.</p><div id="c50a"><pre><span class="hljs-keyword">import</span> ipywidgets <span class="hljs-keyword">as</span> widgets <span class="hljs-keyword">from</span> IPython.display <span class="hljs-keyword">import</span> display, clear_output <span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt

<span class="hljs-comment"># Predict sentiment function</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">predict_sentiment</span>(<span class="hljs-params">text</span>): text = preprocess_text(text) text_vectorized = vectorizer.transform([text]) prediction = model.predict(text_vectorized) sentiment = <span class="hljs-string">'Positive'</span> <span class="hljs-keyword">if</span> prediction == <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> <span class="hljs-string">'Neutral'</span> <span class="hljs-keyword">if</span> prediction == <span class="hljs-number">0</span> <span class="hljs-keyword">else</span> <span class="hljs-string">'Negative'</span> <span class="hljs-keyword">return</span> sentiment

<span class="hljs-comment"># Function to handle input from the user and display the sentiment</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">on_text_submit</span>(<span class="hljs-params">change</span>): <span class="hljs-keyword">with</span> output: clear_output() <span class="hljs-comment"># Clear previous output</span> user_text = tweet_input.value <span class="hljs-comment"># Get the input text</span> sentiment = predict_sentiment(user_text) <span class="hljs-comment"># Predict the sentiment</span> sentiment_label.value = <span class="hljs-string">f"Sentiment: <span class="hljs-subst">{sentiment}</span>"</span> <span class="hljs-comment"># Update sentiment label</span>

    <span class="hljs-comment"># Display corresponding image based on sentiment</span>
    <span class="hljs-keyword">if</span> sentiment == <span class="hljs-string">'Positive'</span>:
        img = plt.imread(<span class="hljs-string">'/content/positive.png'</span>)
    <span class="hljs-keyword">elif</span> sentiment == <span class="hljs-string">'Neutral'</span>:
        img =

Options

plt.imread(<span class="hljs-string">'/content/neutral.png'</span>) <span class="hljs-keyword">else</span>: img = plt.imread(<span class="hljs-string">'/content/negative.png'</span>)

    plt.imshow(img)
    plt.axis(<span class="hljs-string">'off'</span>)
    plt.show()
    
    <span class="hljs-comment"># Adjust the height of the output widget based on the image size</span>
    output.layout.height = <span class="hljs-string">'auto'</span>

<span class="hljs-comment"># Function to handle clicking on a sample tweet</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">on_tweet_click</span>(<span class="hljs-params">b</span>): tweet_input.value = b.description <span class="hljs-comment"># Set the clicked tweet in the input field</span>

<span class="hljs-comment"># Function to show random sample tweets from the dataset with clickable buttons</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">show_sample_tweets</span>(<span class="hljs-params">b</span>): <span class="hljs-keyword">with</span> sample_output: clear_output() <span class="hljs-comment"># Clear previous output</span> sample_tweets = tweets.sample(<span class="hljs-number">5</span>) tweet_buttons = [] <span class="hljs-keyword">for</span> _, row <span class="hljs-keyword">in</span> sample_tweets.iterrows(): tweet_text = row[<span class="hljs-string">'text'</span>] button = widgets.Button( description=tweet_text, layout=widgets.Layout(width=<span class="hljs-string">'100%'</span>, height=<span class="hljs-string">'auto'</span>) ) button.on_click(on_tweet_click) tweet_buttons.append(button)

    tweet_box = widgets.VBox(tweet_buttons)
    display(tweet_box)

<span class="hljs-comment"># Input text box for entering tweets</span> tweet_input = widgets.Text( value=<span class="hljs-string">''</span>, placeholder=<span class="hljs-string">'Type a tweet...'</span>, description=<span class="hljs-string">'Tweet:'</span>, layout=widgets.Layout(width=<span class="hljs-string">'70%'</span>, height=<span class="hljs-string">'30px'</span>), <span class="hljs-comment"># Adjust the size for better appearance</span> style={<span class="hljs-string">'description_width'</span>: <span class="hljs-string">'initial'</span>} )

<span class="hljs-comment"># Button to analyze the tweet</span> analyze_button = widgets.Button( description=<span class="hljs-string">"Analyze Sentiment"</span>, button_style=<span class="hljs-string">'info'</span>, <span class="hljs-comment"># Apply some color to the button for better visual appeal</span> layout=widgets.Layout(width=<span class="hljs-string">'100%'</span>, height=<span class="hljs-string">'40px'</span>) )

<span class="hljs-comment"># Label to display the result of the sentiment analysis</span> sentiment_label = widgets.Label( value=<span class="hljs-string">""</span>, layout=widgets.Layout(width=<span class="hljs-string">'100%'</span>, height=<span class="hljs-string">'40px'</span>, font_size=<span class="hljs-string">'200px'</span>) ) <span class="hljs-comment"># Output area to show the sentiment image</span> output = widgets.Output(layout=widgets.Layout(width=<span class="hljs-string">'100%'</span>, height=<span class="hljs-string">'auto'</span>))

<span class="hljs-comment"># Button to display sample tweets</span> sample_button = widgets.Button( description=<span class="hljs-string">"Show Sample Tweets"</span>, button_style=<span class="hljs-string">'primary'</span>, layout=widgets.Layout(width=<span class="hljs-string">'100%'</span>, height=<span class="hljs-string">'40px'</span>) )

<span class="hljs-comment"># Output area for displaying sample tweets</span> sample_output = widgets.Output(layout=widgets.Layout(width=<span class="hljs-string">'100%'</span>, height=<span class="hljs-string">'auto'</span>))

<span class="hljs-comment"># Event handling for buttons</span> analyze_button.on_click(<span class="hljs-keyword">lambda</span> b: on_text_submit(<span class="hljs-literal">None</span>)) <span class="hljs-comment"># Call the sentiment analysis function on click</span> sample_button.on_click(show_sample_tweets)

<span class="hljs-comment"># Adding a container (window) to visually encapsulate the UI elements</span> ui_container = widgets.Box( [ widgets.HTML(value=<span class="hljs-string">"<h2 style='text-align:center;'>Real-Time Twitter Sentiment Analysis</h2>"</span>), tweet_input, widgets.HBox([analyze_button], layout=widgets.Layout(justify_content=<span class="hljs-string">'center'</span>)), widgets.HBox([sentiment_label], layout=widgets.Layout(justify_content=<span class="hljs-string">'center'</span>)), widgets.HBox([output], layout=widgets.Layout(justify_content=<span class="hljs-string">'center'</span>)), widgets.HBox([sample_button], layout=widgets.Layout(justify_content=<span class="hljs-string">'center'</span>)), sample_output ], layout=widgets.Layout( display=<span class="hljs-string">'flex'</span>, flex_flow=<span class="hljs-string">'column'</span>, align_items=<span class="hljs-string">'center'</span>, border=<span class="hljs-string">'solid 1px #ccc'</span>, padding=<span class="hljs-string">'20px'</span>, width=<span class="hljs-string">'90%'</span> ) )

<span class="hljs-comment"># Display the UI inside the container</span> display(ui_container)</pre></div><p id="a79d">Output:</p><figure id="3d0c"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*dUEeRqtwM0p2Jw6VMVkSqA.gif"><figcaption></figcaption></figure><p id="144c">This section allows users to type a tweet and instantly get a sentiment prediction. It also has a button that shows random sample tweets with their corresponding sentiment labels.</p><p id="b606"><b>Github code: <a href="https://github.com/ABHIJATSARARI/Data-Science-Project-with-Python/blob/main/Real_Time_Twitter_Sentiment_Analysis.ipynb"></a></b><a href="https://github.com/ABHIJATSARARI/Data-Science-Project-with-Python/blob/main/Real_Time_Twitter_Sentiment_Analysis.ipynb">Real_Time_Twitter_Sentiment_Analysis</a></p><h1 id="79b5">Conclusion</h1><p id="c51d">This Real-Time Twitter Sentiment Analysis project uses machine learning to classify tweets into sentiments and provides an interactive interface for real-time predictions. You can extend this project by integrating it with live Twitter feeds or building a full web application.</p></article></body>

Project | Real-Time Twitter Sentiment Analysis

In this blog post, we’ll walk through the implementation of a Real-Time Twitter Sentiment Analysis project using Python. This project will analyze tweets, classify them into positive, neutral, or negative sentiments, and display the results in real time through a simple interactive dashboard.

Step 1: Importing Required Libraries

First, we import the necessary libraries to handle data processing, model training, and visualization.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from wordcloud import WordCloud
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import ipywidgets as widgets
from IPython.display import display
import re
import zipfile
import requests
from io import BytesIO

Step 2: Loading the Dataset

We’ll be using a public dataset from Stanford, which contains labeled tweets for sentiment analysis.

url = "https://cs.stanford.edu/people/alecmgo/trainingandtestdata.zip"
response = requests.get(url)
zip_file = zipfile.ZipFile(BytesIO(response.content))
csv_file = zip_file.open('training.1600000.processed.noemoticon.csv')
tweets = pd.read_csv(csv_file, encoding='latin-1', header=None)
tweets.columns = ['polarity', 'id', 'date', 'query', 'user', 'text']
tweets = tweets[['text', 'polarity']]
tweets.head()

Here, we’re downloading the dataset directly from the internet, unzipping it, and loading it into a Pandas DataFrame. The dataset contains various fields like text, user information, and polarity (sentiment), but we only keep the text and polarity columns.

Step 3: Data Preprocessing

Next, we clean the tweet text and map the polarity values to sentiments: 1 for positive, 0 for neutral, and -1 for negative.

def preprocess_text(text):
    text = text.lower()
    text = re.sub(r'http\S+', '', text)
    text = re.sub(r'@\w+', '', text)
    text = re.sub(r'#\w+', '', text)
    text = re.sub(r'\d+', '', text)
    text = re.sub(r'[^\w\s]', '', text)
    return text

tweets['text'] = tweets['text'].apply(preprocess_text)
tweets['polarity'] = tweets['polarity'].map({4: 1, 2: 0, 0: -1})

This function removes unwanted content from the tweets such as URLs, mentions, hashtags, numbers, and punctuation. Additionally, it standardizes all the text to lowercase for uniformity.

Step 4: Feature Extraction and Data Splitting

We convert the text data into a format that the machine learning model can understand using the CountVectorizer. Then, we split the data into training and testing sets.

vectorizer = CountVectorizer(stop_words='english')
X = vectorizer.fit_transform(tweets['text'])
y = tweets['polarity']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Here, CountVectorizer is used to transform the text data into a bag-of-words model, which represents the text as a matrix of token counts.

Step 5: Training the Sentiment Classifier

We use the Multinomial Naive Bayes classifier to train a sentiment analysis model.

model = MultinomialNB()
model.fit(X_train, y_train)

The model is trained on the training data, and we use it to predict the sentiment of the test data.

Step 6: Evaluating the Model

We evaluate the model’s performance using accuracy, confusion matrix, and classification report.

y_pred = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))
print("Confusion Matrix:\n", confusion_matrix(y_test, y_pred))
print("Classification Report:\n", classification_report(y_test, y_pred))

This gives us an idea of how well the model is performing in terms of predicting the correct sentiments.

Step 7: Creating a Dashboard for Data Visualization

We will create a simple dashboard to visualize the sentiment distribution, word cloud, and confusion matrix.

def create_dashboard():
    fig, axes = plt.subplots(2, 2, figsize=(15, 10))
    
    # Sentiment Distribution
    sns.countplot(x='polarity', data=tweets, ax=axes[0, 0])
    axes[0, 0].set_title('Sentiment Distribution')
    
    # Word Cloud
    text = ' '.join(tweets['text'])
    wordcloud = WordCloud(width=800, height=400, background_color='white').generate(text)
    axes[0, 1].imshow(wordcloud, interpolation='bilinear')
    axes[0, 1].axis('off')
    axes[0, 1].set_title('Word Cloud')
    
    # Sentiment Pie Chart
    sentiment_counts = tweets['polarity'].value_counts()
    # Check the unique values in the 'polarity' column
    labels = sentiment_counts.index.tolist() 
    axes[1, 0].pie(sentiment_counts, labels=labels, autopct='%1.1f%%', startangle=140) #Use the labels derived from the sentiment_counts variable
    axes[1, 0].set_title('Sentiment Pie Chart')
    
    # Confusion Matrix
    sns.heatmap(confusion_matrix(y_test, y_pred), annot=True, fmt='d', cmap='Blues', ax=axes[1, 1])
    axes[1, 1].set_title('Confusion Matrix')
    axes[1, 1].set_xlabel('Predicted')
    axes[1, 1].set_ylabel('Actual')
    
    plt.tight_layout()
    plt.show()

create_dashboard()

Output:

This dashboard includes four components:

  1. Sentiment Distribution — A bar chart showing the number of positive, neutral, and negative tweets.
  2. Word Cloud — A visual representation of the most common words in the dataset.
  3. Sentiment Pie Chart — A pie chart showing the percentage distribution of sentiment categories.
  4. Confusion Matrix — A heatmap showing the performance of the model’s predictions.

Step 8: Real-Time Tweet Sentiment Prediction

We add a function to predict the sentiment of a tweet entered by the user. Using ipywidgets, we create a simple input box for the user to enter a tweet and get real-time sentiment predictions. We also display sample tweets on demand.

import ipywidgets as widgets
from IPython.display import display, clear_output
import matplotlib.pyplot as plt

# Predict sentiment function
def predict_sentiment(text):
    text = preprocess_text(text)
    text_vectorized = vectorizer.transform([text])
    prediction = model.predict(text_vectorized)
    sentiment = 'Positive' if prediction == 1 else 'Neutral' if prediction == 0 else 'Negative'
    return sentiment

# Function to handle input from the user and display the sentiment
def on_text_submit(change):
    with output:
        clear_output()  # Clear previous output
        user_text = tweet_input.value  # Get the input text
        sentiment = predict_sentiment(user_text)  # Predict the sentiment
        sentiment_label.value = f"Sentiment: {sentiment}"  # Update sentiment label
        
        # Display corresponding image based on sentiment
        if sentiment == 'Positive':
            img = plt.imread('/content/positive.png')
        elif sentiment == 'Neutral':
            img = plt.imread('/content/neutral.png')
        else:
            img = plt.imread('/content/negative.png')
        
        plt.imshow(img)
        plt.axis('off')
        plt.show()
        
        # Adjust the height of the output widget based on the image size
        output.layout.height = 'auto'

# Function to handle clicking on a sample tweet
def on_tweet_click(b):
    tweet_input.value = b.description  # Set the clicked tweet in the input field

# Function to show random sample tweets from the dataset with clickable buttons
def show_sample_tweets(b):
    with sample_output:
        clear_output()  # Clear previous output
        sample_tweets = tweets.sample(5)
        tweet_buttons = []
        for _, row in sample_tweets.iterrows():
            tweet_text = row['text']
            button = widgets.Button(
                description=tweet_text, 
                layout=widgets.Layout(width='100%', height='auto')
            )
            button.on_click(on_tweet_click)
            tweet_buttons.append(button)
        
        tweet_box = widgets.VBox(tweet_buttons)
        display(tweet_box)

# Input text box for entering tweets
tweet_input = widgets.Text(
    value='',
    placeholder='Type a tweet...',
    description='Tweet:',
    layout=widgets.Layout(width='70%', height='30px'),  # Adjust the size for better appearance
    style={'description_width': 'initial'}
)

# Button to analyze the tweet
analyze_button = widgets.Button(
    description="Analyze Sentiment",
    button_style='info',  # Apply some color to the button for better visual appeal
    layout=widgets.Layout(width='100%', height='40px')
)

# Label to display the result of the sentiment analysis
sentiment_label = widgets.Label(
    value="", 
    layout=widgets.Layout(width='100%', height='40px', font_size='200px')
)
# Output area to show the sentiment image
output = widgets.Output(layout=widgets.Layout(width='100%', height='auto'))

# Button to display sample tweets
sample_button = widgets.Button(
    description="Show Sample Tweets",
    button_style='primary',
    layout=widgets.Layout(width='100%', height='40px')
)

# Output area for displaying sample tweets
sample_output = widgets.Output(layout=widgets.Layout(width='100%', height='auto'))

# Event handling for buttons
analyze_button.on_click(lambda b: on_text_submit(None))  # Call the sentiment analysis function on click
sample_button.on_click(show_sample_tweets)

# Adding a container (window) to visually encapsulate the UI elements
ui_container = widgets.Box(
    [
        widgets.HTML(value="<h2 style='text-align:center;'>Real-Time Twitter Sentiment Analysis</h2>"),
        tweet_input,
        widgets.HBox([analyze_button], layout=widgets.Layout(justify_content='center')),
        widgets.HBox([sentiment_label], layout=widgets.Layout(justify_content='center')),
        widgets.HBox([output], layout=widgets.Layout(justify_content='center')),
        widgets.HBox([sample_button], layout=widgets.Layout(justify_content='center')),
        sample_output
    ],
    layout=widgets.Layout(
        display='flex',
        flex_flow='column',
        align_items='center',
        border='solid 1px #ccc',
        padding='20px',
        width='90%'
    )
)

# Display the UI inside the container
display(ui_container)

Output:

This section allows users to type a tweet and instantly get a sentiment prediction. It also has a button that shows random sample tweets with their corresponding sentiment labels.

Github code: Real_Time_Twitter_Sentiment_Analysis

Conclusion

This Real-Time Twitter Sentiment Analysis project uses machine learning to classify tweets into sentiments and provides an interactive interface for real-time predictions. You can extend this project by integrating it with live Twitter feeds or building a full web application.

Data Science
Projects
Python
Artificial Intelligence
AI
Recommended from ReadMedium