Isap31 commited on
Commit
2520be0
Β·
verified Β·
1 Parent(s): e0d5b93

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +162 -195
app.py CHANGED
@@ -4,240 +4,207 @@ from datasets import load_dataset
4
  import chromadb
5
  from chromadb.config import Settings
6
 
 
7
  print("Loading Restaurant Review Advisor...")
 
8
 
9
  # ============================================================================
10
- # COMPONENT 1: LOAD SENTIMENT MODEL FROM HUGGING FACE
11
  # ============================================================================
12
- print("[1/3] Loading fine-tuned sentiment model...")
13
 
14
- # Load YOUR trained model from Hugging Face
15
- # Replace 'Isap31' with your actual username if different
16
- sentiment_analyzer = pipeline(
17
- "sentiment-analysis",
18
- model="Isap31/restaurant-sentiment-distilbert"
19
- )
20
-
21
- print("βœ… Sentiment model loaded (94.93% accuracy)")
 
22
 
23
  # ============================================================================
24
  # COMPONENT 2: SETUP RAG SYSTEM
25
  # ============================================================================
26
- print("[2/3] Setting up RAG knowledge base...")
27
-
28
- # Load Yelp reviews dataset
29
- dataset = load_dataset("fancyzhx/yelp_polarity", split="train")
30
- sampled_reviews = dataset.shuffle(seed=42).select(range(500)) # 2000 for faster loading
31
-
32
- # Create ChromaDB collection
33
- chroma_client = chromadb.Client(Settings(
34
- anonymized_telemetry=False,
35
- allow_reset=True
36
- ))
37
-
38
- collection = chroma_client.create_collection(name="yelp_reviews")
39
-
40
- # Add reviews to vector database
41
- documents = []
42
- metadatas = []
43
- ids = []
44
-
45
- for idx, review in enumerate(sampled_reviews):
46
- if len(review['text']) >= 50:
47
- documents.append(review['text'])
48
- metadatas.append({
49
- 'sentiment': 'positive' if review['label'] == 1 else 'negative'
50
- })
51
- ids.append(f"review_{idx}")
52
-
53
- # Add to collection
54
- collection.add(
55
- documents=documents,
56
- metadatas=metadatas,
57
- ids=ids
58
- )
59
-
60
- print(f"βœ… RAG knowledge base ready with {len(documents)} reviews")
61
-
62
- # Load generation model for RAG
63
- generator = pipeline(
64
- "text2text-generation",
65
- model="google/flan-t5-small",
66
- max_length=150
67
- )
68
 
69
- print("βœ… RAG generation model loaded")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  # ============================================================================
72
- # DEFINE APPLICATION FUNCTIONS
73
  # ============================================================================
74
- print("[3/3] Setting up Gradio interface...")
75
 
76
  def analyze_sentiment(text):
77
  """Analyze sentiment of restaurant review"""
78
  if not text.strip():
79
- return "βšͺ No input", "N/A", ""
80
 
81
- result = sentiment_analyzer(text)[0]
82
- label = result['label']
83
- confidence = result['score']
84
 
85
- if label.upper() in ['POSITIVE', 'LABEL_1', '1']:
86
- return "🟒 POSITIVE", f"{confidence:.1%}", "Great review! Customer is satisfied."
87
- else:
88
- return "πŸ”΄ NEGATIVE", f"{confidence:.1%}", "Negative feedback detected."
 
 
 
 
 
 
 
 
 
 
 
89
 
90
  def rag_query(question):
91
  """RAG system - retrieve reviews and generate answer"""
92
  if not question.strip():
93
  return "Please ask a question about restaurants."
94
 
95
- # Retrieval
96
- results = collection.query(query_texts=[question], n_results=3)
97
-
98
- if not results['documents'][0]:
99
- return "I couldn't find relevant reviews for that question."
100
-
101
- # Build context
102
- review_texts = []
103
- sentiments = []
104
-
105
- for doc, metadata in zip(results['documents'][0], results['metadatas'][0]):
106
- sentiment = metadata.get('sentiment', 'unknown')
107
- sentiments.append(sentiment)
108
- review_texts.append(f"[{sentiment.upper()}] {doc}")
109
-
110
- context = "\n\n".join(review_texts)
111
 
112
- # Augmentation & Generation
113
- prompt = f"""Based on these customer reviews, answer the question concisely.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  Reviews:
115
  {context}
 
116
  Question: {question}
117
- Answer:"""
118
-
119
- answer = generator(prompt, max_length=150)[0]['generated_text']
120
-
121
- # Format response
122
- response = f"**Generated Answer:**\n{answer}\n\n"
123
- response += f"**Based on:** {len(results['documents'][0])} customer reviews "
124
- response += f"({sentiments.count('positive')} positive, {sentiments.count('negative')} negative)"
125
-
126
- return response
127
 
128
- def complete_advisor(user_input, mode):
129
- """Main function - routes to appropriate component"""
130
- if not user_input.strip():
131
- return "Please enter text or a question."
132
-
133
- if mode == "Sentiment Analysis":
134
- sentiment, confidence, interpretation = analyze_sentiment(user_input)
135
- return f"**Sentiment:** {sentiment}\n**Confidence:** {confidence}\n\n{interpretation}"
136
-
137
- elif mode == "Knowledge Query (RAG)":
138
- return rag_query(user_input)
139
-
140
- else: # Complete Analysis
141
- sentiment, confidence, interpretation = analyze_sentiment(user_input)
142
- rag_answer = rag_query(user_input)
143
 
144
- result = f"## πŸ“Š Sentiment Analysis\n"
145
- result += f"**Result:** {sentiment}\n"
146
- result += f"**Confidence:** {confidence}\n"
147
- result += f"**Interpretation:** {interpretation}\n\n"
148
- result += f"## πŸ€– RAG Knowledge System\n\n{rag_answer}"
149
 
150
- return result
 
151
 
152
  # ============================================================================
153
  # CREATE GRADIO INTERFACE
154
  # ============================================================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
- with gr.Blocks(theme=gr.themes.Soft(), title="Restaurant Review Advisor") as demo:
157
- gr.HTML('''
158
- <h1 style="text-align: center; background: linear-gradient(90deg, #f093fb 0%, #f5576c 100%);
159
- -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-size: 3em;">
160
- β˜• Restaurant Review Advisor
161
- </h1>
162
- ''')
163
- gr.HTML('<p style="text-align: center; font-size: 1.3em; color: #666;">Fine-Tuned Sentiment Analysis + RAG Knowledge System</p>')
164
-
165
- with gr.Row():
166
- with gr.Column(scale=2):
167
- gr.Markdown("""
168
- ### 🎯 System Overview
169
-
170
- **Component 1:** Fine-tuned DistilBERT sentiment model
171
- - Trained on 50,000 Yelp reviews
172
- - **Accuracy: 94.93%**
173
- - Binary classification (Positive/Negative)
174
-
175
- **Component 2:** RAG System with Yelp Reviews
176
- - Retrieval: ChromaDB vector search
177
- - Documents: 2,000+ real customer reviews
178
- - Generation: FLAN-T5 language model
179
-
180
- **Component 3:** Integrated Gradio Interface
181
- - Three analysis modes
182
- - Real-time processing
183
- - Public deployment
184
- """)
185
-
186
- gr.Markdown("---")
187
-
188
- with gr.Row():
189
- with gr.Column():
190
- mode = gr.Radio(
191
- choices=["Sentiment Analysis", "Knowledge Query (RAG)", "Complete Analysis"],
192
- value="Sentiment Analysis",
193
- label="πŸŽ›οΈ Select Mode"
194
- )
195
-
196
- user_input = gr.Textbox(
197
- lines=4,
198
- placeholder="Enter restaurant review or question...",
199
- label="πŸ“ Input"
200
- )
201
-
202
- submit_btn = gr.Button("πŸš€ Analyze", variant="primary", size="lg")
203
-
204
- with gr.Column():
205
- output = gr.Markdown(label="πŸ“Š Results")
206
-
207
- gr.Markdown("---")
208
- gr.Markdown("### πŸ’‘ Try These Examples:")
209
-
210
- gr.Examples(
211
- examples=[
212
- ["This restaurant exceeded all expectations! The service was impeccable and food was divine.", "Sentiment Analysis"],
213
- ["Worst dining experience ever. Cold food, rude staff, and overpriced.", "Sentiment Analysis"],
214
- ["What do customers say about food quality at restaurants?", "Knowledge Query (RAG)"],
215
- ["Are portions typically good at restaurants?", "Knowledge Query (RAG)"],
216
- ["The ambiance was perfect! What do people say about restaurant atmosphere?", "Complete Analysis"],
217
- ],
218
- inputs=[user_input, mode]
219
- )
220
-
221
- submit_btn.click(
222
- fn=complete_advisor,
223
- inputs=[user_input, mode],
224
- outputs=output
225
- )
226
-
227
- gr.Markdown("""
228
- ---
229
- ### πŸ“š Technical Details
230
-
231
- **Model:** [Isap31/restaurant-sentiment-distilbert](https://huggingface.co/Isap31/restaurant-sentiment-distilbert)
232
- **Dataset:** [Yelp Review Polarity](https://huggingface.co/datasets/fancyzhx/yelp_polarity)
233
- **Framework:** Hugging Face Transformers, ChromaDB, Gradio
234
- **GitHub:** [Restaurant Review Advisor](https://github.com/Isap31/Restaurant-review-advisor-Final-Project-452)
235
-
236
- **INFO 452 Final Project** | Fall 2025 | VCU
237
- """)
238
 
239
  print("βœ… Gradio interface ready!")
 
240
 
241
  # Launch
242
  if __name__ == "__main__":
243
- demo.launch()
 
4
  import chromadb
5
  from chromadb.config import Settings
6
 
7
+ print("="*70)
8
  print("Loading Restaurant Review Advisor...")
9
+ print("="*70)
10
 
11
  # ============================================================================
12
+ # COMPONENT 1: LOAD SENTIMENT MODEL
13
  # ============================================================================
14
+ print("\n[1/3] Loading fine-tuned sentiment model...")
15
 
16
+ try:
17
+ sentiment_analyzer = pipeline(
18
+ "sentiment-analysis",
19
+ model="Isap31/restaurant-sentiment-distilbert"
20
+ )
21
+ print("βœ… Sentiment model loaded (94.93% accuracy)")
22
+ except Exception as e:
23
+ print(f"Error loading sentiment model: {e}")
24
+ sentiment_analyzer = None
25
 
26
  # ============================================================================
27
  # COMPONENT 2: SETUP RAG SYSTEM
28
  # ============================================================================
29
+ print("\n[2/3] Setting up RAG knowledge base...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ try:
32
+ # Load dataset
33
+ dataset = load_dataset("fancyzhx/yelp_polarity", split="train")
34
+ sampled_reviews = dataset.shuffle(seed=42).select(range(500)) # Reduced for stability
35
+
36
+ # Create ChromaDB
37
+ chroma_client = chromadb.Client(Settings(
38
+ anonymized_telemetry=False,
39
+ allow_reset=True
40
+ ))
41
+
42
+ collection = chroma_client.create_collection(name="yelp_reviews")
43
+
44
+ # Add reviews
45
+ documents = []
46
+ metadatas = []
47
+ ids = []
48
+
49
+ for idx, review in enumerate(sampled_reviews):
50
+ if len(review['text']) >= 50:
51
+ documents.append(review['text'])
52
+ metadatas.append({'sentiment': 'positive' if review['label'] == 1 else 'negative'})
53
+ ids.append(f"review_{idx}")
54
+
55
+ collection.add(documents=documents, metadatas=metadatas, ids=ids)
56
+
57
+ print(f"βœ… RAG knowledge base ready with {len(documents)} reviews")
58
+
59
+ # Load generation model
60
+ generator = pipeline("text2text-generation", model="google/flan-t5-small", max_length=150)
61
+ print("βœ… RAG generation model loaded")
62
+
63
+ rag_ready = True
64
+ except Exception as e:
65
+ print(f"Error setting up RAG: {e}")
66
+ rag_ready = False
67
+ collection = None
68
+ generator = None
69
 
70
  # ============================================================================
71
+ # DEFINE FUNCTIONS
72
  # ============================================================================
73
+ print("\n[3/3] Setting up application...")
74
 
75
  def analyze_sentiment(text):
76
  """Analyze sentiment of restaurant review"""
77
  if not text.strip():
78
+ return "βšͺ No input provided"
79
 
80
+ if sentiment_analyzer is None:
81
+ return "❌ Sentiment model not loaded"
 
82
 
83
+ try:
84
+ result = sentiment_analyzer(text)[0]
85
+ label = result['label']
86
+ confidence = result['score']
87
+
88
+ if label.upper() in ['POSITIVE', 'LABEL_1', '1']:
89
+ sentiment = f"🟒 POSITIVE ({confidence:.1%} confidence)"
90
+ interpretation = "Great review! Customer is satisfied."
91
+ else:
92
+ sentiment = f"πŸ”΄ NEGATIVE ({confidence:.1%} confidence)"
93
+ interpretation = "Negative feedback detected."
94
+
95
+ return f"{sentiment}\n\n{interpretation}"
96
+ except Exception as e:
97
+ return f"❌ Error: {str(e)}"
98
 
99
  def rag_query(question):
100
  """RAG system - retrieve reviews and generate answer"""
101
  if not question.strip():
102
  return "Please ask a question about restaurants."
103
 
104
+ if not rag_ready:
105
+ return "❌ RAG system not loaded"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
 
107
+ try:
108
+ # Retrieval
109
+ results = collection.query(query_texts=[question], n_results=3)
110
+
111
+ if not results['documents'][0]:
112
+ return "I couldn't find relevant reviews for that question."
113
+
114
+ # Build context
115
+ review_texts = []
116
+ sentiments = []
117
+
118
+ for doc, metadata in zip(results['documents'][0], results['metadatas'][0]):
119
+ sentiment = metadata.get('sentiment', 'unknown')
120
+ sentiments.append(sentiment)
121
+ review_texts.append(f"[{sentiment.upper()}] {doc}")
122
+
123
+ context = "\n\n".join(review_texts)
124
+
125
+ # Generate
126
+ prompt = f"""Based on these customer reviews, answer the question concisely.
127
+
128
  Reviews:
129
  {context}
130
+
131
  Question: {question}
 
 
 
 
 
 
 
 
 
 
132
 
133
+ Answer:"""
134
+
135
+ answer = generator(prompt, max_length=150)[0]['generated_text']
136
+
137
+ # Format response
138
+ response = f"**Generated Answer:**\n{answer}\n\n"
139
+ response += f"**Based on:** {len(results['documents'][0])} customer reviews "
140
+ response += f"({sentiments.count('positive')} positive, {sentiments.count('negative')} negative)"
 
 
 
 
 
 
 
141
 
142
+ return response
 
 
 
 
143
 
144
+ except Exception as e:
145
+ return f"❌ Error: {str(e)}"
146
 
147
  # ============================================================================
148
  # CREATE GRADIO INTERFACE
149
  # ============================================================================
150
+ print("\nCreating Gradio interface...")
151
+
152
+ # Create the interface
153
+ demo = gr.Interface(
154
+ fn=analyze_sentiment,
155
+ inputs=gr.Textbox(
156
+ lines=3,
157
+ placeholder="Enter restaurant review...",
158
+ label="Review Text"
159
+ ),
160
+ outputs=gr.Textbox(label="Sentiment Analysis Result"),
161
+ title="🍽️ Restaurant Review Advisor",
162
+ description="""
163
+ **Fine-Tuned Sentiment Analysis + RAG Knowledge System**
164
+
165
+ Component 1: DistilBERT sentiment model (94.93% accuracy)
166
+ Component 2: RAG system with 500+ Yelp reviews
167
+ Component 3: Gradio interface
168
+
169
+ Enter a restaurant review to analyze its sentiment!
170
+ """,
171
+ examples=[
172
+ ["This restaurant exceeded all expectations! The service was impeccable and food was divine."],
173
+ ["Worst dining experience ever. Cold food, rude staff, and overpriced."],
174
+ ["The ambiance was nice, but the food was just okay."],
175
+ ],
176
+ theme=gr.themes.Soft()
177
+ )
178
 
179
+ # Create RAG interface
180
+ demo_rag = gr.Interface(
181
+ fn=rag_query,
182
+ inputs=gr.Textbox(
183
+ lines=2,
184
+ placeholder="Ask a question about restaurants...",
185
+ label="Question"
186
+ ),
187
+ outputs=gr.Textbox(label="RAG Answer"),
188
+ title="πŸ” Restaurant Knowledge Query (RAG)",
189
+ description="Ask questions about restaurants and get answers based on real customer reviews!",
190
+ examples=[
191
+ ["What do customers say about food quality at restaurants?"],
192
+ ["Are portions typically good at restaurants?"],
193
+ ["What about customer service?"],
194
+ ],
195
+ theme=gr.themes.Soft()
196
+ )
197
+
198
+ # Combine with tabs
199
+ app = gr.TabbedInterface(
200
+ [demo, demo_rag],
201
+ ["Sentiment Analysis", "RAG Knowledge Query"],
202
+ title="β˜• Restaurant Review Advisor - INFO 452 Final Project"
203
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
  print("βœ… Gradio interface ready!")
206
+ print("="*70)
207
 
208
  # Launch
209
  if __name__ == "__main__":
210
+ app.launch()