Jivan01's picture
Just Upload
c1f8c52 verified
Raw
History Blame Contribute Delete
8.37 kB
# Author: Jivan Jamdar
# Date: 2023-10-01 Time: 20:57:43PM
# Description: Streamlit app for sentiment analysis using TextBlob and VADER
import streamlit as st
import pandas as pd
import plotly.express as px
from analyzer import SentimentAnalyzer
def main():
st.set_page_config(
page_title="Sentiment Analysis App",
page_icon="📊",
layout="wide"
)
st.title("📊 Sentiment Analysis Tool")
st.write("Analyze the sentiment of tweets, product reviews, or any text!")
analyzer = SentimentAnalyzer()
# different tabs => different functionalities
tab1, tab2, tab3 = st.tabs(["Single Text Analysis", "Batch Analysis", "About"])
with tab1:
st.subheader("Single Text Analysis")
# tool selection
analysis_tool = st.radio(
"Select analysis tool:",
["TextBlob", "VADER"],
horizontal=True
)
# text input
text_input = st.text_area(
"Enter text to analyze:",
height=150,
placeholder="Type or paste your text here..."
)
if st.button("Analyze Sentiment"):
if text_input:
with st.spinner("Analyzing..."):
if analysis_tool == "TextBlob":
result = analyzer.analyze_textblob(text_input)
method = "TextBlob"
else:
result = analyzer.analyze_vader(text_input)
method = "VADER"
# display results with columns
st.subheader("Results")
col1, col2 = st.columns(2)
with col1:
st.markdown(f"### {result['emoji']} {result['sentiment']}")
st.write(f"Analysis method: {method}")
with col2:
if method == "TextBlob":
st.metric("Polarity", f"{result['polarity']:.2f}")
st.metric("Subjectivity", f"{result['subjectivity']:.2f}")
else: # VADER
st.metric("Compound Score", f"{result['compound']:.2f}")
# detailed breakdown for VADER
if method == "VADER":
st.subheader("Sentiment Breakdown")
vader_df = pd.DataFrame({
'Sentiment': ['Positive', 'Neutral', 'Negative'],
'Score': [result['pos'], result['neu'], result['neg']]
})
fig = px.bar(
vader_df,
x='Sentiment',
y='Score',
color='Sentiment',
color_discrete_map={
'Positive': '#2ECC71',
'Neutral': '#3498DB',
'Negative': '#E74C3C'
}
)
st.plotly_chart(fig, use_container_width=True)
else:
st.warning("Please enter some text to analyze.")
with tab2:
st.subheader("Batch Analysis")
st.write("Upload a CSV or Excel file with a column containing text to analyze multiple entries at once.")
uploaded_file = st.file_uploader("Upload your file", type=["csv", "xlsx"])
if uploaded_file is not None:
try:
if uploaded_file.name.endswith('.csv'):
df = pd.read_csv(uploaded_file)
else:
df = pd.read_excel(uploaded_file)
st.write("Preview of uploaded data:")
st.dataframe(df.head())
text_column = st.selectbox("Select the column containing text to analyze:", df.columns)
analysis_tool = st.radio(
"Select analysis tool for batch processing:",
["TextBlob", "VADER"],
horizontal=True
)
if st.button("Run Batch Analysis"):
with st.spinner("Analyzing all entries..."):
results = []
for text in df[text_column]:
if pd.notna(text): # skip NaN values
if analysis_tool == "TextBlob":
result = analyzer.analyze_textblob(str(text))
else:
result = analyzer.analyze_vader(str(text))
results.append(result)
else:
# handle NaN values
results.append({
'sentiment': 'Unknown',
'emoji': '❓',
'compound' if analysis_tool == "VADER" else 'polarity': 0
})
# create results DataFrame
results_df = pd.DataFrame(results)
df_with_sentiment = pd.concat([df, results_df], axis=1)
st.subheader("Results")
st.dataframe(df_with_sentiment)
# download button for results
st.download_button(
label="Download Results",
data=df_with_sentiment.to_csv(index=False),
file_name="sentiment_analysis_results.csv",
mime="text/csv"
)
# show summary statistics
st.subheader("Sentiment Distribution")
sentiment_counts = results_df['sentiment'].value_counts().reset_index()
sentiment_counts.columns = ['Sentiment', 'Count']
fig = px.pie(
sentiment_counts,
names='Sentiment',
values='Count',
color='Sentiment',
color_discrete_map={
'Positive': '#2ECC71',
'Neutral': '#3498DB',
'Negative': '#E74C3C',
'Unknown': '#95A5A6'
}
)
st.plotly_chart(fig, use_container_width=True)
except Exception as e:
st.error(f"Error processing the uploaded file: {str(e)}")
with tab3:
st.subheader("About This App")
st.write("""
This Sentiment Analysis App uses two popular techniques:
1. **TextBlob**: A simple NLP library that provides a simple API for diving into common NLP tasks.
- Polarity: Score from -1 (very negative) to +1 (very positive)
- Subjectivity: Score from 0 (objective) to 1 (subjective)
2. **VADER** (Valence Aware Dictionary and sEntiment Reasoner): A lexicon and rule-based sentiment analysis tool specifically attuned to sentiments expressed in social media.
- Compound: Normalized score from -1 (very negative) to +1 (very positive)
- Positive, Neutral, Negative: Proportions of text that fall in each category
### When to use each tool:
- TextBlob is simpler and works well for general text
- VADER is better for social media content, slang, and emoticons
### Limitations:
- Neither tool understands sarcasm well
- Context is often missed
- Language specific (works best with English)
""")
if __name__ == "__main__":
main()