Spaces:
Build error
Build error
File size: 8,373 Bytes
c1f8c52 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | # 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() |