Soundaryasos's picture
Update app.py
1bc7958 verified
raw
history blame
6.85 kB
import streamlit as st
from transformers import pipeline
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
import numpy as np
import pandas as pd
from datetime import datetime, timedelta
import plotly.express as px
from sklearn.linear_model import LinearRegression
from wordcloud import WordCloud
import base64
from io import BytesIO
# Initialize sentiment models
bert_sentiment = pipeline("sentiment-analysis")
vader_analyzer = SentimentIntensityAnalyzer()
# Generate sample past sentiment data
dates = [datetime.today() - timedelta(days=i) for i in range(14)]
sentiment_scores = np.random.uniform(-1, 1, len(dates))
df = pd.DataFrame({"Date": dates, "Sentiment Score": sentiment_scores})
# Train a regression model
X = np.array(range(len(df))).reshape(-1, 1)
y = df["Sentiment Score"]
model = LinearRegression()
model.fit(X, y)
# Predict for next 7 days
future_dates = [datetime.today() + timedelta(days=i) for i in range(1, 8)]
X_future = np.array(range(len(df), len(df) + 7)).reshape(-1, 1)
predictions = model.predict(X_future)
future_df = pd.DataFrame({"Date": future_dates, "Predicted Sentiment": predictions})
# Generate Word Cloud
def generate_wordcloud(text):
wordcloud = WordCloud(width=800, height=400, background_color='white').generate(text)
img = BytesIO()
wordcloud.to_image().save(img, format='PNG')
return base64.b64encode(img.getvalue()).decode()
# Streamlit app setup
st.title("Interactive Sentiment Analysis Dashboard")
# Sidebar for navigation and settings
st.sidebar.header("Sentiment Analysis Controls")
st.sidebar.subheader("Input")
user_input = st.sidebar.text_input('Enter text for sentiment analysis')
# Display explanation and detailed sentiment scores
def display_sentiment_analysis(vader_score, bert_result):
st.subheader("Sentiment Analysis Results:")
st.write(f"**VADER Sentiment Score**: {vader_score:.2f}")
st.write(f"**BERT Sentiment**: {bert_result['label']} ({bert_result['score']:.2f})")
# Display sentiment breakdown in a bar chart
sentiment_data = {'Positive': max(0, vader_score), 'Negative': min(0, vader_score), 'Neutral': 1 - abs(vader_score)}
sentiment_df = pd.DataFrame(list(sentiment_data.items()), columns=["Sentiment", "Score"])
# Color graphs based on sentiment (if negative, turn red)
bar_colors = ['green' if sentiment == 'Positive' else 'red' for sentiment in sentiment_df['Sentiment']]
st.bar_chart(sentiment_df.set_index("Sentiment"), color=bar_colors)
# Generate and display the word cloud
wordcloud_img = f'data:image/png;base64,{generate_wordcloud(user_input)}'
st.image(wordcloud_img, use_column_width=True)
# Explanation of Sentiment Analysis
st.write("""
- **VADER Sentiment Score**: This is a numerical value that indicates the overall sentiment of the text.
Positive values indicate positive sentiment, negative values indicate negative sentiment, and values close to zero indicate neutral sentiment.
- **BERT Sentiment**: This is another model's analysis, where it categorizes the text as 'Positive', 'Negative', or 'Neutral' with a confidence score.
- The bar chart visually shows the balance between positive, negative, and neutral sentiments in your text.
""")
# Analyze sentiment on button click
if st.sidebar.button('Analyze Sentiment'):
if user_input:
with st.spinner('Analyzing text...'):
# VADER sentiment analysis
vader_score = vader_analyzer.polarity_scores(user_input)['compound']
# BERT sentiment analysis
bert_result = bert_sentiment(user_input)[0]
# Display sentiment analysis details
display_sentiment_analysis(vader_score, bert_result)
else:
st.warning("Please enter some text for analysis.")
# Section for past sentiment trends
st.subheader("Past Sentiment Trends (Last 14 Days)")
fig1 = px.line(df, x='Date', y='Sentiment Score', title='Past Sentiment Trends', markers=True, line_shape='spline')
fig1.update_traces(line_color='red' if df['Sentiment Score'].mean() < 0 else 'green')
st.plotly_chart(fig1)
# Section for future sentiment predictions
st.subheader("Sentiment Prediction for Next 7 Days")
fig2 = px.line(future_df, x='Date', y='Predicted Sentiment', title='Sentiment Prediction for Next 7 Days', markers=True, line_shape='spline')
fig2.update_traces(line_color='red' if future_df['Predicted Sentiment'].mean() < 0 else 'green')
st.plotly_chart(fig2)
# Sentiment Distribution Pie Chart
st.subheader("Sentiment Distribution")
fig3 = px.pie(values=[sum(df['Sentiment Score'] > 0), sum(df['Sentiment Score'] <= 0)],
names=['Positive', 'Negative'], title='Sentiment Distribution', hole=0.3)
fig3.update_traces(marker=dict(colors=['green', 'red']))
st.plotly_chart(fig3)
# Histogram of Sentiment Scores (Distribution)
st.subheader("Sentiment Score Distribution (Past 14 Days)")
fig4 = px.histogram(df, x='Sentiment Score', nbins=20, title="Sentiment Score Distribution")
fig4.update_traces(marker_color='red' if df['Sentiment Score'].mean() < 0 else 'green')
st.plotly_chart(fig4)
# Time-Series Heatmap for Sentiment Over Time
st.subheader("Sentiment Heatmap (Past 14 Days)")
df['Day'] = df['Date'].dt.dayofweek
df['Hour'] = df['Date'].dt.hour
heatmap_data = df.pivot('Day', 'Hour', 'Sentiment Score')
fig5 = px.imshow(heatmap_data, title="Heatmap of Sentiment Over Time", labels={'x': 'Hour of Day', 'y': 'Day of Week'})
fig5.update_traces(colorscale='reds' if df['Sentiment Score'].mean() < 0 else 'greens')
st.plotly_chart(fig5)
# Scatter plot of Sentiment over Time
st.subheader("Sentiment Scatter Plot (Past 14 Days)")
fig6 = px.scatter(df, x='Date', y='Sentiment Score', title='Sentiment Over Time')
fig6.update_traces(marker=dict(color='red' if df['Sentiment Score'].mean() < 0 else 'green'))
st.plotly_chart(fig6)
# Rolling average of Sentiment (7-day window)
st.subheader("Rolling Average of Sentiment (7-Day Window)")
df['Rolling Avg Sentiment'] = df['Sentiment Score'].rolling(window=7).mean()
fig7 = px.line(df, x='Date', y='Rolling Avg Sentiment', title="Rolling Average of Sentiment (7-Day Window)")
fig7.update_traces(line_color='red' if df['Rolling Avg Sentiment'].mean() < 0 else 'green')
st.plotly_chart(fig7)
# Display top comments and posts (Mock Data)
st.subheader("Top Comments and Posts")
top_comments = [
"I love this! So uplifting!",
"This is terrible, I can't believe this happened.",
"I'm not sure how I feel about this, it's mixed.",
"What a great day, everything is going well!",
"This is so frustrating, why does this always happen?"
]
for comment in top_comments:
st.write(f"- {comment}")
# Reset button to clear inputs and visualizations
if st.sidebar.button('Reset Analysis'):
st.experimental_rerun()