sdf299 commited on
Commit
8edd645
Β·
verified Β·
1 Parent(s): 7cb30ee

Update app_spaces.py

Browse files
Files changed (1) hide show
  1. app_spaces.py +241 -170
app_spaces.py CHANGED
@@ -1,171 +1,242 @@
1
- import gradio as gr
2
- import pandas as pd
3
- from transformers import pipeline
4
- import warnings
5
- import os
6
- warnings.filterwarnings("ignore")
7
-
8
- # Initialize the models
9
- print("Loading ABSA models for Hugging Face Spaces...")
10
- token_classifier = pipeline(
11
- model="sdf299/abte-restaurants-distilbert-base-uncased",
12
- aggregation_strategy="simple"
13
- )
14
-
15
- classifier = pipeline(
16
- model="sdf299/absa-restaurants-distilbert-base-uncased"
17
- )
18
- print("Models loaded successfully!")
19
-
20
- def analyze_sentiment(sentence):
21
- """
22
- Perform aspect-based sentiment analysis on the input sentence.
23
-
24
- Args:
25
- sentence (str): Input sentence to analyze
26
-
27
- Returns:
28
- tuple: (formatted_results, aspects_summary, detailed_dataframe)
29
- """
30
- if not sentence.strip():
31
- return "Please enter a sentence to analyze.", "", pd.DataFrame()
32
-
33
- try:
34
- # Extract aspects using token classifier
35
- results = token_classifier(sentence)
36
-
37
- if not results:
38
- return "No aspects found in the sentence.", "", pd.DataFrame()
39
-
40
- # Get unique aspects
41
- aspects = list(set([result['word'] for result in results]))
42
-
43
- # Analyze sentiment for each aspect
44
- detailed_results = []
45
- formatted_output = f"**Input Sentence:** {sentence}\n\n**Analysis Results:**\n\n"
46
-
47
- for aspect in aspects:
48
- # Classify sentiment for this aspect
49
- sentiment_result = classifier(f'{sentence} [SEP] {aspect}')
50
-
51
- # Extract sentiment label and confidence
52
- sentiment_label = sentiment_result[0]['label']
53
- confidence = sentiment_result[0]['score']
54
-
55
- # Format the result
56
- formatted_output += f"🎯 **Aspect:** {aspect}\n"
57
- formatted_output += f" **Sentiment:** {sentiment_label} (Confidence: {confidence:.3f})\n\n"
58
-
59
- # Store for dataframe
60
- detailed_results.append({
61
- 'Aspect': aspect,
62
- 'Sentiment': sentiment_label,
63
- 'Confidence': f"{confidence:.3f}"
64
- })
65
-
66
- # Create summary
67
- aspects_summary = f"**Identified Aspects:** {', '.join(aspects)}"
68
-
69
- # Create dataframe for tabular view
70
- df = pd.DataFrame(detailed_results)
71
-
72
- return formatted_output, aspects_summary, df
73
-
74
- except Exception as e:
75
- error_msg = f"Error during analysis: {str(e)}"
76
- return error_msg, "", pd.DataFrame()
77
-
78
- # Create the Gradio interface
79
- with gr.Blocks(
80
- title="🍽️ Restaurant Review Analyzer - ABSA",
81
- theme=gr.themes.Soft(),
82
- css="""
83
- .gradio-container {
84
- font-family: 'Arial', sans-serif;
85
- max-width: 1200px;
86
- }
87
- .main-header {
88
- text-align: center;
89
- margin-bottom: 30px;
90
- }
91
- """
92
- ) as demo:
93
-
94
- gr.HTML("""
95
- <div class="main-header">
96
- <h1>🍽️ Restaurant Review Analyzer</h1>
97
- <h3>Aspect-Based Sentiment Analysis</h3>
98
- <p>Analyze restaurant reviews to identify specific aspects (food, service, atmosphere, etc.) and their associated sentiments.</p>
99
- <p><em>Powered by DistilBERT models fine-tuned on restaurant reviews</em></p>
100
- </div>
101
- """)
102
-
103
- with gr.Row():
104
- with gr.Column(scale=2):
105
- # Input section
106
- sentence_input = gr.Textbox(
107
- label="Enter Restaurant Review",
108
- placeholder="e.g., The services here is wonderful, but I hate the food. However, I still love the atmosphere here.",
109
- lines=3,
110
- max_lines=5
111
- )
112
-
113
- analyze_btn = gr.Button("πŸ” Analyze Sentiment", variant="primary", size="lg")
114
-
115
- # Example sentences
116
- gr.Examples(
117
- examples=[
118
- ["The services here is wonderful, but I hate the food. However, I still love the atmosphere here."],
119
- ["The food was amazing and the staff was very friendly, but the restaurant was too noisy."],
120
- ["Great location and delicious pizza, but the service was slow and the prices are too high."],
121
- ["The ambiance is perfect for a romantic dinner, excellent wine selection, but the dessert was disappointing."],
122
- ["Fast service and good value for money, but the food quality could be better."],
123
- ["Excellent sushi and attentive waiters, though the wait time was quite long."],
124
- ["Beautiful decor and reasonable prices, but the pasta was overcooked."]
125
- ],
126
- inputs=sentence_input,
127
- label="Try these examples:"
128
- )
129
-
130
- with gr.Column(scale=3):
131
- # Output section
132
- with gr.Tab("πŸ“Š Detailed Results"):
133
- results_output = gr.Markdown(label="Analysis Results")
134
-
135
- with gr.Tab("πŸ“‹ Quick Summary"):
136
- aspects_output = gr.Markdown(label="Aspects Summary")
137
-
138
- with gr.Tab("πŸ“ˆ Data Table"):
139
- table_output = gr.Dataframe(
140
- label="Results Table",
141
- headers=["Aspect", "Sentiment", "Confidence"]
142
- )
143
-
144
- # Event handlers
145
- analyze_btn.click(
146
- fn=analyze_sentiment,
147
- inputs=[sentence_input],
148
- outputs=[results_output, aspects_output, table_output]
149
- )
150
-
151
- sentence_input.submit(
152
- fn=analyze_sentiment,
153
- inputs=[sentence_input],
154
- outputs=[results_output, aspects_output, table_output]
155
- )
156
-
157
- # Footer with model information
158
- gr.HTML("""
159
- <div style="text-align: center; margin-top: 30px; padding: 20px; border-top: 1px solid #eee;">
160
- <p><strong>Models Used:</strong></p>
161
- <p>πŸ”€ Aspect Extraction: <a href="https://huggingface.co/sdf299/abte-restaurants-distilbert-base-uncased" target="_blank">sdf299/abte-restaurants-distilbert-base-uncased</a></p>
162
- <p>😊 Sentiment Classification: <a href="https://huggingface.co/sdf299/absa-restaurants-distilbert-base-uncased" target="_blank">sdf299/absa-restaurants-distilbert-base-uncased</a></p>
163
- <p style="margin-top: 15px; font-size: 0.9em; color: #666;">
164
- This app demonstrates aspect-based sentiment analysis for restaurant reviews using fine-tuned DistilBERT models.
165
- </p>
166
- </div>
167
- """)
168
-
169
- # Launch the app
170
- if __name__ == "__main__":
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  demo.launch()
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ from transformers import pipeline
4
+ import warnings
5
+ import os
6
+ warnings.filterwarnings("ignore")
7
+
8
+ # Initialize the models
9
+ print("Loading ABSA models for Hugging Face Spaces...")
10
+ token_classifier = pipeline(
11
+ model="sdf299/abte-restaurants-distilbert-base-uncased",
12
+ aggregation_strategy="simple"
13
+ )
14
+
15
+ classifier = pipeline(
16
+ model="sdf299/absa-restaurants-distilbert-base-uncased"
17
+ )
18
+ print("Models loaded successfully!")
19
+
20
+ def get_sentiment_color(sentiment_label):
21
+ """Return color based on sentiment label."""
22
+ sentiment_lower = sentiment_label.lower()
23
+ if 'positive' in sentiment_lower:
24
+ return "#28a745", "🟒" # Green
25
+ elif 'negative' in sentiment_lower:
26
+ return "#dc3545", "πŸ”΄" # Red
27
+ else:
28
+ return "#6c757d", "βšͺ" # Gray for neutral
29
+
30
+ def analyze_sentiment(sentence):
31
+ """
32
+ Perform aspect-based sentiment analysis on the input sentence.
33
+
34
+ Args:
35
+ sentence (str): Input sentence to analyze
36
+
37
+ Returns:
38
+ tuple: (formatted_results, aspects_summary, detailed_dataframe)
39
+ """
40
+ if not sentence.strip():
41
+ return "Please enter a sentence to analyze.", "", pd.DataFrame()
42
+
43
+ try:
44
+ # Extract aspects using token classifier
45
+ results = token_classifier(sentence)
46
+
47
+ if not results:
48
+ return "No aspects found in the sentence.", "", pd.DataFrame()
49
+
50
+ # Get unique aspects
51
+ aspects = list(set([result['word'] for result in results]))
52
+
53
+ # Analyze sentiment for each aspect
54
+ detailed_results = []
55
+ formatted_output = f"**πŸ“ Input Sentence:** {sentence}\n\n"
56
+ formatted_output += "## 🎯 Analysis Results:\n\n"
57
+
58
+ # Count sentiments for summary
59
+ sentiment_counts = {'positive': 0, 'negative': 0, 'neutral': 0}
60
+
61
+ for aspect in aspects:
62
+ # Classify sentiment for this aspect
63
+ sentiment_result = classifier(f'{sentence} [SEP] {aspect}')
64
+
65
+ # Extract sentiment label and confidence
66
+ sentiment_label = sentiment_result[0]['label']
67
+ confidence = sentiment_result[0]['score']
68
+
69
+ # Get color and emoji for this sentiment
70
+ color, emoji = get_sentiment_color(sentiment_label)
71
+
72
+ # Count sentiments
73
+ if 'positive' in sentiment_label.lower():
74
+ sentiment_counts['positive'] += 1
75
+ elif 'negative' in sentiment_label.lower():
76
+ sentiment_counts['negative'] += 1
77
+ else:
78
+ sentiment_counts['neutral'] += 1
79
+
80
+ # Format the result with colors
81
+ formatted_output += f'<div style="margin: 15px 0; padding: 15px; border-left: 4px solid {color}; background-color: {color}15; border-radius: 5px;">'
82
+ formatted_output += f'<strong style="color: {color};">{emoji} Aspect: {aspect}</strong><br>'
83
+ formatted_output += f'<span style="color: {color}; font-weight: bold;">Sentiment: {sentiment_label}</span> '
84
+ formatted_output += f'<span style="color: #666; font-size: 0.9em;">(Confidence: {confidence:.3f})</span>'
85
+ formatted_output += '</div>\n\n'
86
+
87
+ # Store for dataframe with colored styling
88
+ detailed_results.append({
89
+ 'Aspect': aspect,
90
+ 'Sentiment': sentiment_label,
91
+ 'Confidence': f"{confidence:.3f}",
92
+ 'Color': color,
93
+ 'Emoji': emoji
94
+ })
95
+
96
+ # Create colorful summary
97
+ aspects_summary = "## πŸ“Š Summary:\n\n"
98
+ aspects_summary += f"**πŸ” Total Aspects Found:** {len(aspects)}\n\n"
99
+
100
+ # Add sentiment breakdown
101
+ if sentiment_counts['positive'] > 0:
102
+ aspects_summary += f"🟒 **Positive:** {sentiment_counts['positive']} aspects\n\n"
103
+ if sentiment_counts['negative'] > 0:
104
+ aspects_summary += f"πŸ”΄ **Negative:** {sentiment_counts['negative']} aspects\n\n"
105
+ if sentiment_counts['neutral'] > 0:
106
+ aspects_summary += f"βšͺ **Neutral:** {sentiment_counts['neutral']} aspects\n\n"
107
+
108
+ aspects_summary += f"**πŸ“ Identified Aspects:** {', '.join(aspects)}"
109
+
110
+ # Create dataframe for tabular view (simplified for table)
111
+ df_data = []
112
+ for result in detailed_results:
113
+ df_data.append({
114
+ 'Aspect': result['Aspect'],
115
+ 'Sentiment': f"{result['Emoji']} {result['Sentiment']}",
116
+ 'Confidence': result['Confidence']
117
+ })
118
+ df = pd.DataFrame(df_data)
119
+
120
+ return formatted_output, aspects_summary, df
121
+
122
+ except Exception as e:
123
+ error_msg = f"❌ **Error during analysis:** {str(e)}\n\nPlease try again with a different sentence."
124
+ return error_msg, "", pd.DataFrame()
125
+
126
+ # Create the Gradio interface
127
+ with gr.Blocks(
128
+ title="🍽️ Restaurant Review Analyzer - ABSA",
129
+ theme=gr.themes.Soft(),
130
+ css="""
131
+ .gradio-container {
132
+ font-family: 'Arial', sans-serif;
133
+ max-width: 1200px;
134
+ }
135
+ .main-header {
136
+ text-align: center;
137
+ margin-bottom: 30px;
138
+ }
139
+ .sentiment-positive {
140
+ color: #28a745 !important;
141
+ background-color: #d4edda;
142
+ border-color: #c3e6cb;
143
+ }
144
+ .sentiment-negative {
145
+ color: #dc3545 !important;
146
+ background-color: #f8d7da;
147
+ border-color: #f5c6cb;
148
+ }
149
+ .sentiment-neutral {
150
+ color: #6c757d !important;
151
+ background-color: #f8f9fa;
152
+ border-color: #dee2e6;
153
+ }
154
+ """
155
+ ) as demo:
156
+
157
+ gr.HTML("""
158
+ <div class="main-header">
159
+ <h1>🍽️ Restaurant Review Analyzer</h1>
160
+ <h3>🎨 Colorful Aspect-Based Sentiment Analysis</h3>
161
+ <p>Analyze restaurant reviews to identify specific aspects and their sentiments with beautiful color coding!</p>
162
+ <div style="margin: 15px 0; padding: 10px; background-color: #f8f9fa; border-radius: 8px; border: 1px solid #dee2e6;">
163
+ <p style="margin: 5px 0;"><strong>🎨 Color Guide:</strong></p>
164
+ <span style="color: #28a745; font-weight: bold;">🟒 Positive</span> |
165
+ <span style="color: #dc3545; font-weight: bold;">πŸ”΄ Negative</span> |
166
+ <span style="color: #6c757d; font-weight: bold;">βšͺ Neutral</span>
167
+ </div>
168
+ <p><em>Powered by DistilBERT models fine-tuned on restaurant reviews</em></p>
169
+ </div>
170
+ """)
171
+
172
+ with gr.Row():
173
+ with gr.Column(scale=2):
174
+ # Input section
175
+ sentence_input = gr.Textbox(
176
+ label="🍽️ Enter Restaurant Review",
177
+ placeholder="e.g., The services here is wonderful, but I hate the food. However, I still love the atmosphere here.",
178
+ lines=3,
179
+ max_lines=5
180
+ )
181
+
182
+ analyze_btn = gr.Button("πŸ” Analyze Sentiment", variant="primary", size="lg")
183
+
184
+ # Example sentences
185
+ gr.Examples(
186
+ examples=[
187
+ ["The services here is wonderful, but I hate the food. However, I still love the atmosphere here."],
188
+ ["The food was amazing and the staff was very friendly, but the restaurant was too noisy."],
189
+ ["Great location and delicious pizza, but the service was slow and the prices are too high."],
190
+ ["The ambiance is perfect for a romantic dinner, excellent wine selection, but the dessert was disappointing."],
191
+ ["Fast service and good value for money, but the food quality could be better."],
192
+ ["Excellent sushi and attentive waiters, though the wait time was quite long."],
193
+ ["Beautiful decor and reasonable prices, but the pasta was overcooked."],
194
+ ["Outstanding customer service and fresh ingredients, highly recommend this place!"],
195
+ ["Terrible experience - rude staff, cold food, and dirty tables. Never coming back."]
196
+ ],
197
+ inputs=sentence_input,
198
+ label="πŸ’‘ Try these examples:"
199
+ )
200
+
201
+ with gr.Column(scale=3):
202
+ # Output section
203
+ with gr.Tab("🎨 Colorful Results"):
204
+ results_output = gr.HTML(label="Visual Analysis Results")
205
+
206
+ with gr.Tab("πŸ“Š Summary Dashboard"):
207
+ aspects_output = gr.Markdown(label="Quick Summary")
208
+
209
+ with gr.Tab("πŸ“ˆ Data Table"):
210
+ table_output = gr.Dataframe(
211
+ label="Results Table",
212
+ headers=["Aspect", "Sentiment", "Confidence"]
213
+ )
214
+
215
+ # Event handlers
216
+ analyze_btn.click(
217
+ fn=analyze_sentiment,
218
+ inputs=[sentence_input],
219
+ outputs=[results_output, aspects_output, table_output]
220
+ )
221
+
222
+ sentence_input.submit(
223
+ fn=analyze_sentiment,
224
+ inputs=[sentence_input],
225
+ outputs=[results_output, aspects_output, table_output]
226
+ )
227
+
228
+ # Footer with model information
229
+ gr.HTML("""
230
+ <div style="text-align: center; margin-top: 30px; padding: 20px; border-top: 1px solid #eee;">
231
+ <p><strong>πŸ€– Models Used:</strong></p>
232
+ <p>πŸ”€ Aspect Extraction: <a href="https://huggingface.co/sdf299/abte-restaurants-distilbert-base-uncased" target="_blank">sdf299/abte-restaurants-distilbert-base-uncased</a></p>
233
+ <p>😊 Sentiment Classification: <a href="https://huggingface.co/sdf299/absa-restaurants-distilbert-base-uncased" target="_blank">sdf299/absa-restaurants-distilbert-base-uncased</a></p>
234
+ <p style="margin-top: 15px; font-size: 0.9em; color: #666;">
235
+ ✨ This app demonstrates colorful aspect-based sentiment analysis for restaurant reviews using fine-tuned DistilBERT models.
236
+ </p>
237
+ </div>
238
+ """)
239
+
240
+ # Launch the app
241
+ if __name__ == "__main__":
242
  demo.launch()