GLAkavya commited on
Commit
302b32f
·
verified ·
1 Parent(s): f35a01f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +119 -139
app.py CHANGED
@@ -1,163 +1,143 @@
1
- import gradio as gr
2
  import random
 
3
  import plotly.express as px
4
  import pandas as pd
5
  from transformers import pipeline
6
  import google.generativeai as genai
7
 
8
- # ------------------------------
9
- # Setup HuggingFace Transformer
10
- # ------------------------------
11
  sentiment_model = pipeline("sentiment-analysis")
12
 
13
- # ------------------------------
14
- # Setup Gemini (Google AI Studio)
15
- # ------------------------------
16
- GEMINI_KEY = "YOUR_GEMINI_API_KEY"
17
- genai.configure(api_key=GEMINI_KEY)
18
-
19
- # Helper to call Gemini
20
- def gemini_generate(prompt):
21
- model = genai.GenerativeModel("gemini-1.5-flash")
22
- response = model.generate_content(prompt)
23
- return response.text
24
-
25
- # ------------------------------
26
- # Fake post generator with Gemini
27
- # ------------------------------
28
- def generate_posts(hashtag, n_posts, use_gemini=False):
29
- posts = []
30
-
31
- if use_gemini:
32
- prompt = f"""
33
- Generate {n_posts} short social media posts about "{hashtag}".
34
- Posts must be realistic, 1-2 sentences each, like from Twitter.
35
- Ensure balanced sentiment: mostly realistic negatives if topic is bad,
36
- some neutral, and very few positive.
37
- Return only the posts as a numbered list.
38
- """
39
- try:
40
- text = gemini_generate(prompt)
41
- posts = [line.split(". ",1)[-1] for line in text.split("\n") if line.strip()]
42
- except Exception as e:
43
- posts = [f"Error generating with Gemini: {e}"]
44
- else:
45
- sample_posts = [
46
- f"{hashtag} totally failed expectations 😞",
47
- f"Not sure how I feel about {hashtag} 🤔",
48
- f"{hashtag} is the worst thing ever 😡",
49
- f"Super excited about {hashtag} 🔥",
50
- f"People are talking about {hashtag} everywhere 🌍",
51
- f"{hashtag} campaign is the best thing this year 🎉",
52
- f"I'm disappointed with {hashtag} 💔",
53
- f"I love {hashtag}! It's amazing ❤️"
54
- ]
55
- posts = random.choices(sample_posts, k=n_posts)
56
-
57
- return posts[:n_posts]
58
-
59
- # ------------------------------
60
- # Sentiment Analysis
61
- # ------------------------------
62
- def analyze_sentiment(posts, use_gemini=False):
63
- results = []
64
-
65
- if use_gemini:
66
- # Limit Gemini analysis to 10 posts (quota safe)
67
- subset = posts[:10]
68
- prompt = f"""
69
- Analyze the sentiment of the following posts:
70
- {subset}
71
- Respond as JSON list with: post, sentiment (POSITIVE/NEGATIVE/NEUTRAL), confidence (0-1).
72
- """
73
  try:
74
- text = gemini_generate(prompt)
75
- # naive parse: fallback to HF if parsing fails
76
- if "POSITIVE" in text or "NEGATIVE" in text:
77
- for line in text.split("\n"):
78
- if line.strip():
79
- if "POSITIVE" in line:
80
- results.append({"post": line, "sentiment": "POSITIVE", "confidence": 1.0})
81
- elif "NEGATIVE" in line:
82
- results.append({"post": line, "sentiment": "NEGATIVE", "confidence": 1.0})
83
- elif "NEUTRAL" in line:
84
- results.append({"post": line, "sentiment": "NEUTRAL", "confidence": 1.0})
 
 
85
  else:
86
- raise Exception("Parsing failed")
87
- except:
88
- # fallback to HF
89
- results = [{"post": p, **sentiment_model(p)[0]} for p in posts]
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  else:
92
- results = [{"post": p, **sentiment_model(p)[0]} for p in posts]
93
-
94
- # Format uniform
95
- clean = []
96
- for r in results:
97
- label = r["label"] if "label" in r else r["sentiment"]
98
- score = r["score"] if "score" in r else r.get("confidence", 0.8)
99
- clean.append({
100
- "Post": r["post"],
101
- "Sentiment": label.upper(),
102
- "Confidence": round(score, 2)
103
- })
104
- return clean
105
-
106
- # ------------------------------
107
- # Visualization
108
- # ------------------------------
109
- def create_viz(data, viz_type, hashtag):
110
  df = pd.DataFrame(data)
111
 
112
- if viz_type == "Bar":
 
113
  fig = px.bar(df, x="Sentiment", title=f"Sentiment Distribution for {hashtag}")
114
- elif viz_type == "Pie":
 
 
115
  fig = px.pie(df, names="Sentiment", title=f"Sentiment Share for {hashtag}")
116
- elif viz_type == "Line":
117
- fig = px.line(df, y="Confidence", title=f"Sentiment Confidence Trend for {hashtag}")
118
- elif viz_type == "Area":
119
- fig = px.area(df, y="Confidence", title=f"Sentiment Rolling Area for {hashtag}")
120
  else:
121
- fig = px.histogram(df, x="Sentiment", title=f"Sentiment Histogram for {hashtag}")
122
-
123
- return fig
124
 
125
- # ------------------------------
126
- # Main App Function
127
- # ------------------------------
128
- def run_analysis(hashtag, n_posts, viz_type, use_gemini):
129
- posts = generate_posts(hashtag, n_posts, use_gemini)
130
- data = analyze_sentiment(posts, use_gemini)
131
- fig = create_viz(data, viz_type, hashtag)
132
- return pd.DataFrame(data), fig
133
 
134
- # ------------------------------
135
  # Gradio UI
136
- # ------------------------------
137
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange", secondary_hue="purple")) as demo:
138
- gr.HTML("""
139
- <div style="text-align:center; padding:20px; color:white;">
140
- <h1 style="font-size:40px; background: linear-gradient(90deg, #ff8c00, #e94057, #8a2be2);
141
- -webkit-background-clip: text; -webkit-text-fill-color: transparent;">
142
- 🚀 Social Media Sentiment Analyzer</h1>
143
- <p style="font-size:18px;">Stream posts • Analyze moods • Visualize trends</p>
144
- </div>
145
- """)
146
 
147
  with gr.Row():
148
  with gr.Column(scale=1):
149
- hashtag = gr.Textbox(label="Enter Hashtag", placeholder="#gla")
150
- n_posts = gr.Slider(5, 50, step=1, value=20, label="Number of Posts")
151
- viz_type = gr.Dropdown(["Bar", "Pie", "Line", "Area"], value="Bar", label="Choose Visualization")
152
- use_gemini = gr.Checkbox(label="Use Gemini Advanced Analysis")
153
- run_btn = gr.Button("🚀 Run Analysis", variant="primary")
154
-
155
  with gr.Column(scale=2):
156
- output_table = gr.Dataframe(headers=["Post", "Sentiment", "Confidence"], label="Posts & Sentiments")
157
- output_plot = gr.Plot(label="Visualization")
158
-
159
- run_btn.click(fn=run_analysis,
160
- inputs=[hashtag, n_posts, viz_type, use_gemini],
161
- outputs=[output_table, output_plot])
162
-
163
- demo.launch()
 
 
 
 
 
 
 
1
+ import os
2
  import random
3
+ import gradio as gr
4
  import plotly.express as px
5
  import pandas as pd
6
  from transformers import pipeline
7
  import google.generativeai as genai
8
 
9
+ # -----------------------------
10
+ # Load Hugging Face Sentiment Model
11
+ # -----------------------------
12
  sentiment_model = pipeline("sentiment-analysis")
13
 
14
+ # -----------------------------
15
+ # Configure Gemini (Key from Secrets)
16
+ # -----------------------------
17
+ GEMINI_KEY = os.getenv("GEMINI_API_KEY") # add in Hugging Face Secrets
18
+ if GEMINI_KEY:
19
+ genai.configure(api_key=GEMINI_KEY)
20
+
21
+ # -----------------------------
22
+ # Fake Post Generator (simulate Twitter)
23
+ # -----------------------------
24
+ def generate_fake_posts(hashtag, n=20):
25
+ templates = [
26
+ f"I love {hashtag}! It's amazing ❤️",
27
+ f"I'm disappointed with {hashtag} 💔",
28
+ f"{hashtag} totally failed expectations 😠",
29
+ f"Not sure how I feel about {hashtag} 🤔",
30
+ f"People are talking about {hashtag} everywhere 🌍",
31
+ f"{hashtag} campaign is the best thing this year 🎉",
32
+ f"Super excited about {hashtag} 🔥",
33
+ f"{hashtag} is the worst thing ever 😡"
34
+ ]
35
+ return random.choices(templates, k=n)
36
+
37
+ # -----------------------------
38
+ # Run HuggingFace Analysis
39
+ # -----------------------------
40
+ def analyze_with_hf(posts):
41
+ results = sentiment_model(posts)
42
+ sentiments = []
43
+ for post, res in zip(posts, results):
44
+ sentiments.append({
45
+ "Post": post,
46
+ "Sentiment": res["label"],
47
+ "Confidence": round(res["score"], 2)
48
+ })
49
+ return sentiments
50
+
51
+ # -----------------------------
52
+ # Run Gemini Advanced Analysis
53
+ # -----------------------------
54
+ def analyze_with_gemini(posts):
55
+ if not GEMINI_KEY:
56
+ return analyze_with_hf(posts) # fallback
57
+
58
+ sentiments = []
59
+ for post in posts:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  try:
61
+ prompt = f"""Classify the sentiment of this social media post as Positive, Negative, or Neutral.
62
+ Return only JSON with 'label' and 'confidence' between 0 and 1.
63
+
64
+ Post: "{post}"
65
+ """
66
+ response = genai.GenerativeModel("gemini-1.5-flash").generate_content(prompt)
67
+
68
+ # crude parse
69
+ text = response.text.strip()
70
+ if "Positive" in text:
71
+ label = "POSITIVE"
72
+ elif "Negative" in text:
73
+ label = "NEGATIVE"
74
  else:
75
+ label = "NEUTRAL"
 
 
 
76
 
77
+ sentiments.append({
78
+ "Post": post,
79
+ "Sentiment": label,
80
+ "Confidence": 0.95 # Gemini usually doesn’t return prob, we keep 0.95
81
+ })
82
+ except:
83
+ sentiments.append({
84
+ "Post": post,
85
+ "Sentiment": "NEUTRAL",
86
+ "Confidence": 0.5
87
+ })
88
+ return sentiments
89
+
90
+ # -----------------------------
91
+ # Main Function
92
+ # -----------------------------
93
+ def run_analysis(hashtag, n_posts, vis_type, use_gemini):
94
+ posts = generate_fake_posts(hashtag, n_posts)
95
+ if use_gemini:
96
+ data = analyze_with_gemini(posts)
97
  else:
98
+ data = analyze_with_hf(posts)
99
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  df = pd.DataFrame(data)
101
 
102
+ # Chart
103
+ if vis_type == "Bar":
104
  fig = px.bar(df, x="Sentiment", title=f"Sentiment Distribution for {hashtag}")
105
+ elif vis_type == "Line":
106
+ fig = px.line(df, y="Confidence", title=f"Sentiment Rolling Trend for {hashtag}")
107
+ elif vis_type == "Pie":
108
  fig = px.pie(df, names="Sentiment", title=f"Sentiment Share for {hashtag}")
 
 
 
 
109
  else:
110
+ fig = px.scatter(df, x="Sentiment", y="Confidence", title=f"Scatter of Sentiments for {hashtag}")
 
 
111
 
112
+ return df, fig
 
 
 
 
 
 
 
113
 
114
+ # -----------------------------
115
  # Gradio UI
116
+ # -----------------------------
117
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange", secondary_hue="blue")) as demo:
118
+ gr.Markdown("<h1 style='text-align:center;'>🚀 Social Media Sentiment Analyzer</h1>")
119
+ gr.Markdown("<p style='text-align:center;'>Stream posts · Analyze moods · Visualize trends</p>")
 
 
 
 
 
 
120
 
121
  with gr.Row():
122
  with gr.Column(scale=1):
123
+ hashtag = gr.Textbox(label="Enter Hashtag", value="#gla")
124
+ n_posts = gr.Slider(5, 50, value=20, step=1, label="Number of Posts")
125
+ vis_type = gr.Dropdown(["Bar", "Line", "Pie", "Scatter"], label="Choose Visualization", value="Bar")
126
+ use_gemini = gr.Checkbox(label="Use Gemini Advanced Analysis", value=False)
127
+ run_btn = gr.Button("🔍 Run Analysis", variant="primary")
128
+
129
  with gr.Column(scale=2):
130
+ output_table = gr.Dataframe(headers=["Post", "Sentiment", "Confidence"], wrap=True)
131
+ output_plot = gr.Plot()
132
+
133
+ run_btn.click(
134
+ fn=run_analysis,
135
+ inputs=[hashtag, n_posts, vis_type, use_gemini],
136
+ outputs=[output_table, output_plot]
137
+ )
138
+
139
+ # -----------------------------
140
+ # Launch App
141
+ # -----------------------------
142
+ if __name__ == "__main__":
143
+ demo.launch()