Jivan01 commited on
Commit
c1f8c52
·
verified ·
1 Parent(s): e835141

Just Upload

Browse files
Files changed (4) hide show
  1. README.md +0 -14
  2. analyzer.py +53 -0
  3. app.py +193 -0
  4. requirements.txt +6 -0
README.md CHANGED
@@ -1,14 +0,0 @@
1
- ---
2
- title: Sentiment Analysis
3
- emoji: 👁
4
- colorFrom: purple
5
- colorTo: blue
6
- sdk: streamlit
7
- sdk_version: 1.44.1
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- short_description: A powerful web application for analyzing sentiment in text d
12
- ---
13
-
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
analyzer.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from textblob import TextBlob
2
+ from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
3
+
4
+ class SentimentAnalyzer:
5
+ def __init__(self):
6
+ self.vader = SentimentIntensityAnalyzer()
7
+
8
+ def analyze_textblob(self, text):
9
+ """Analyze text sentiment using TextBlob"""
10
+ analysis = TextBlob(text)
11
+ polarity = analysis.sentiment.polarity
12
+
13
+ # sentiment category
14
+ if polarity > 0.05:
15
+ sentiment = "Positive"
16
+ emoji = "😃"
17
+ elif polarity < -0.05:
18
+ sentiment = "Negative"
19
+ emoji = "😞"
20
+ else:
21
+ sentiment = "Neutral"
22
+ emoji = "😐"
23
+
24
+ return {
25
+ "sentiment": sentiment,
26
+ "polarity": polarity,
27
+ "emoji": emoji,
28
+ "subjectivity": analysis.sentiment.subjectivity
29
+ }
30
+
31
+ def analyze_vader(self, text):
32
+ """Analyze text sentiment using VADER"""
33
+ scores = self.vader.polarity_scores(text)
34
+
35
+ # determine sentiment category based on compound score
36
+ if scores["compound"] >= 0.05:
37
+ sentiment = "Positive"
38
+ emoji = "😃"
39
+ elif scores["compound"] <= -0.05:
40
+ sentiment = "Negative"
41
+ emoji = "😞"
42
+ else:
43
+ sentiment = "Neutral"
44
+ emoji = "😐"
45
+
46
+ return {
47
+ "sentiment": sentiment,
48
+ "compound": scores["compound"],
49
+ "pos": scores["pos"],
50
+ "neu": scores["neu"],
51
+ "neg": scores["neg"],
52
+ "emoji": emoji
53
+ }
app.py ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Author: Jivan Jamdar
2
+ # Date: 2023-10-01 Time: 20:57:43PM
3
+ # Description: Streamlit app for sentiment analysis using TextBlob and VADER
4
+
5
+ import streamlit as st
6
+ import pandas as pd
7
+ import plotly.express as px
8
+ from analyzer import SentimentAnalyzer
9
+
10
+ def main():
11
+ st.set_page_config(
12
+ page_title="Sentiment Analysis App",
13
+ page_icon="📊",
14
+ layout="wide"
15
+ )
16
+
17
+ st.title("📊 Sentiment Analysis Tool")
18
+ st.write("Analyze the sentiment of tweets, product reviews, or any text!")
19
+
20
+ analyzer = SentimentAnalyzer()
21
+
22
+ # different tabs => different functionalities
23
+ tab1, tab2, tab3 = st.tabs(["Single Text Analysis", "Batch Analysis", "About"])
24
+
25
+ with tab1:
26
+ st.subheader("Single Text Analysis")
27
+
28
+ # tool selection
29
+ analysis_tool = st.radio(
30
+ "Select analysis tool:",
31
+ ["TextBlob", "VADER"],
32
+ horizontal=True
33
+ )
34
+
35
+ # text input
36
+ text_input = st.text_area(
37
+ "Enter text to analyze:",
38
+ height=150,
39
+ placeholder="Type or paste your text here..."
40
+ )
41
+
42
+ if st.button("Analyze Sentiment"):
43
+ if text_input:
44
+ with st.spinner("Analyzing..."):
45
+ if analysis_tool == "TextBlob":
46
+ result = analyzer.analyze_textblob(text_input)
47
+ method = "TextBlob"
48
+ else:
49
+ result = analyzer.analyze_vader(text_input)
50
+ method = "VADER"
51
+
52
+ # display results with columns
53
+ st.subheader("Results")
54
+ col1, col2 = st.columns(2)
55
+
56
+ with col1:
57
+ st.markdown(f"### {result['emoji']} {result['sentiment']}")
58
+ st.write(f"Analysis method: {method}")
59
+
60
+ with col2:
61
+ if method == "TextBlob":
62
+ st.metric("Polarity", f"{result['polarity']:.2f}")
63
+ st.metric("Subjectivity", f"{result['subjectivity']:.2f}")
64
+ else: # VADER
65
+ st.metric("Compound Score", f"{result['compound']:.2f}")
66
+
67
+ # detailed breakdown for VADER
68
+ if method == "VADER":
69
+ st.subheader("Sentiment Breakdown")
70
+ vader_df = pd.DataFrame({
71
+ 'Sentiment': ['Positive', 'Neutral', 'Negative'],
72
+ 'Score': [result['pos'], result['neu'], result['neg']]
73
+ })
74
+
75
+ fig = px.bar(
76
+ vader_df,
77
+ x='Sentiment',
78
+ y='Score',
79
+ color='Sentiment',
80
+ color_discrete_map={
81
+ 'Positive': '#2ECC71',
82
+ 'Neutral': '#3498DB',
83
+ 'Negative': '#E74C3C'
84
+ }
85
+ )
86
+ st.plotly_chart(fig, use_container_width=True)
87
+ else:
88
+ st.warning("Please enter some text to analyze.")
89
+
90
+ with tab2:
91
+ st.subheader("Batch Analysis")
92
+ st.write("Upload a CSV or Excel file with a column containing text to analyze multiple entries at once.")
93
+
94
+ uploaded_file = st.file_uploader("Upload your file", type=["csv", "xlsx"])
95
+
96
+ if uploaded_file is not None:
97
+ try:
98
+ if uploaded_file.name.endswith('.csv'):
99
+ df = pd.read_csv(uploaded_file)
100
+ else:
101
+ df = pd.read_excel(uploaded_file)
102
+
103
+ st.write("Preview of uploaded data:")
104
+ st.dataframe(df.head())
105
+
106
+ text_column = st.selectbox("Select the column containing text to analyze:", df.columns)
107
+ analysis_tool = st.radio(
108
+ "Select analysis tool for batch processing:",
109
+ ["TextBlob", "VADER"],
110
+ horizontal=True
111
+ )
112
+
113
+ if st.button("Run Batch Analysis"):
114
+ with st.spinner("Analyzing all entries..."):
115
+ results = []
116
+
117
+ for text in df[text_column]:
118
+ if pd.notna(text): # skip NaN values
119
+ if analysis_tool == "TextBlob":
120
+ result = analyzer.analyze_textblob(str(text))
121
+ else:
122
+ result = analyzer.analyze_vader(str(text))
123
+ results.append(result)
124
+ else:
125
+ # handle NaN values
126
+ results.append({
127
+ 'sentiment': 'Unknown',
128
+ 'emoji': '❓',
129
+ 'compound' if analysis_tool == "VADER" else 'polarity': 0
130
+ })
131
+
132
+ # create results DataFrame
133
+ results_df = pd.DataFrame(results)
134
+ df_with_sentiment = pd.concat([df, results_df], axis=1)
135
+
136
+ st.subheader("Results")
137
+ st.dataframe(df_with_sentiment)
138
+
139
+ # download button for results
140
+ st.download_button(
141
+ label="Download Results",
142
+ data=df_with_sentiment.to_csv(index=False),
143
+ file_name="sentiment_analysis_results.csv",
144
+ mime="text/csv"
145
+ )
146
+
147
+ # show summary statistics
148
+ st.subheader("Sentiment Distribution")
149
+ sentiment_counts = results_df['sentiment'].value_counts().reset_index()
150
+ sentiment_counts.columns = ['Sentiment', 'Count']
151
+
152
+ fig = px.pie(
153
+ sentiment_counts,
154
+ names='Sentiment',
155
+ values='Count',
156
+ color='Sentiment',
157
+ color_discrete_map={
158
+ 'Positive': '#2ECC71',
159
+ 'Neutral': '#3498DB',
160
+ 'Negative': '#E74C3C',
161
+ 'Unknown': '#95A5A6'
162
+ }
163
+ )
164
+ st.plotly_chart(fig, use_container_width=True)
165
+
166
+ except Exception as e:
167
+ st.error(f"Error processing the uploaded file: {str(e)}")
168
+
169
+ with tab3:
170
+ st.subheader("About This App")
171
+ st.write("""
172
+ This Sentiment Analysis App uses two popular techniques:
173
+
174
+ 1. **TextBlob**: A simple NLP library that provides a simple API for diving into common NLP tasks.
175
+ - Polarity: Score from -1 (very negative) to +1 (very positive)
176
+ - Subjectivity: Score from 0 (objective) to 1 (subjective)
177
+
178
+ 2. **VADER** (Valence Aware Dictionary and sEntiment Reasoner): A lexicon and rule-based sentiment analysis tool specifically attuned to sentiments expressed in social media.
179
+ - Compound: Normalized score from -1 (very negative) to +1 (very positive)
180
+ - Positive, Neutral, Negative: Proportions of text that fall in each category
181
+
182
+ ### When to use each tool:
183
+ - TextBlob is simpler and works well for general text
184
+ - VADER is better for social media content, slang, and emoticons
185
+
186
+ ### Limitations:
187
+ - Neither tool understands sarcasm well
188
+ - Context is often missed
189
+ - Language specific (works best with English)
190
+ """)
191
+
192
+ if __name__ == "__main__":
193
+ main()
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ streamlit>=1.24.0
2
+ textblob>=0.17.1
3
+ vaderSentiment>=3.3.2
4
+ pandas>=2.0.3
5
+ matplotlib==3.7.2
6
+ plotly>=5.15.0