Tech With Galvan
Back to Articles
AI11/1/2024 • 3 min read

Sentiment Analysis App using Python and Streamlit

Build a sentiment analysis web app with Python and Streamlit using TextBlob — analyse whether any text is positive, negative, or neutral with a polarity score.

Galvan
Galvan

Founder & Creator

Introduction

In this project you will build a Sentiment Analysis web app using Python and Streamlit. The app uses TextBlob to determine whether a piece of text is positive, negative, or neutral — and shows you a polarity score from -1 to +1. For generative AI instead of analysis, the Mistral chatbot tutorial is the natural next step.

Prerequisites

pip install streamlit textblob
python -m textblob.download_corpora

Step 1: Create the Script

Create sentiment_app.py and paste the following:

import streamlit as st
from textblob import TextBlob

st.set_page_config(page_title="Sentiment Analysis", page_icon="😊")
st.title("😊 Sentiment Analysis App")
st.write("Enter any text to find out if it is positive, negative, or neutral.")

user_input = st.text_area("Enter your text:", height=150,
                           placeholder="Type or paste text here...")

if st.button("Analyse Sentiment") and user_input:
    blob = TextBlob(user_input)
    polarity = blob.sentiment.polarity
    subjectivity = blob.sentiment.subjectivity

    if polarity > 0.1:
        label, color = "😊 Positive", "success"
    elif polarity < -0.1:
        label, color = "😞 Negative", "error"
    else:
        label, color = "😐 Neutral", "info"

    col1, col2, col3 = st.columns(3)
    col1.metric("Sentiment", label)
    col2.metric("Polarity", f"{polarity:.2f}")
    col3.metric("Subjectivity", f"{subjectivity:.2f}")

    if color == "success":
        st.success(f"This text has a **positive** sentiment (polarity: {polarity:.2f}).")
    elif color == "error":
        st.error(f"This text has a **negative** sentiment (polarity: {polarity:.2f}).")
    else:
        st.info(f"This text has a **neutral** sentiment (polarity: {polarity:.2f}).")

st.caption("Polarity: -1 (very negative) → 0 (neutral) → +1 (very positive)")

Step 2: Run the App

streamlit run sentiment_app.py

Step 3: Use the App

Type or paste any text in the input area and click Analyse Sentiment. The app returns a labelled result plus polarity and subjectivity scores.

How It Works

The app uses VADER (Valence Aware Dictionary and sEntiment Reasoner) from NLTK. VADER scores text against a lexicon of words rated from -4 to +4, with special handling for intensifiers (“very good”), negation (“not good”), and punctuation (“good!!!”). It returns four numbers: positive, neutral, negative proportions, and a compound score from -1 (most negative) to +1 (most positive).

The compound score drives the verdict: typically ≥ 0.05 is positive, ≤ -0.05 negative, and anything between is neutral. Rendering the three proportions with st.progress() bars makes the result instantly readable.

VADER is lexicon-based, not learned — it needs no training data and runs instantly, which is why it is the right first NLP tool. Its weakness is context and sarcasm; for conversational text, an LLM approach like the SANGAM AI toolkit handles nuance better.

Key Concepts

  • TextBlob(text) — Creates a TextBlob object that analyses the provided text.
  • blob.sentiment.polarity — Float from -1.0 (very negative) to +1.0 (very positive).
  • blob.sentiment.subjectivity — Float from 0.0 (objective) to 1.0 (very subjective).
  • st.metric() — Displays each score in a clean highlighted card.

Understanding the Scores

Polarity Range Sentiment
0.1 to 1.0 Positive 😊
-0.1 to 0.1 Neutral 😐
-1.0 to -0.1 Negative 😞

What to Try Next

  • Analyse sentiment sentence by sentence and display results for each.
  • Generate a word cloud of the most frequent words using wordcloud.
  • Swap TextBlob for VADER for better accuracy on social-media-style text.

Common Errors & Fixes

  • LookupError: resource vader_lexicon not found — the NLTK data download did not complete. Run nltk.download('vader_lexicon') once in a plain Python shell, not inside the Streamlit rerun.

  • Every sentence scores neutral — you are analyzing the raw SentimentIntensityAnalyzer() object instead of calling polarity_scores(text).

  • Slow on first load — VADER’s lexicon loads once per process; cache the analyzer with @st.cache_resource.

  • Emoji/ slang scored wrong — expected for a lexicon model. Preprocess with the emoji package or accept the limitation.

  • nltk data downloads on every visitor’s first load — pre-download the lexicon into the repo or a persistent folder and point NLTK_DATA at it, so deploys don’t re-fetch.

FAQ

How accurate is VADER?

On social-media-style English it benchmarks around 0.88 F1 on standard test sets. On formal or domain-specific text, accuracy drops — test against your own labeled samples.

Can it handle Hindi or other languages?

Not natively — VADER is English-only. Translate first (see the translator app) or use a multilingual model.

Why compound instead of the three percentages?

Compound is a single normalized score that accounts for the whole sentence, making thresholds and comparisons simple.

Can I analyze whole reviews or documents?

Yes — score per sentence and average the compound scores, which tracks mixed sentiment better than scoring the whole block at once.