DanielKiani commited on
Commit
e04900a
·
1 Parent(s): 63b1daf

Fix: Resolve merge markers and ensure correct v2.0 state

Browse files
Files changed (3) hide show
  1. requirements.txt +0 -14
  2. scripts/app.py +0 -163
  3. scripts/main.py +0 -112
requirements.txt CHANGED
@@ -1,4 +1,3 @@
1
- <<<<<<< HEAD
2
  langchain==0.3.27
3
  langchain-community==0.3.31
4
  gradio==5.49.1
@@ -15,16 +14,3 @@ numpy==2.0.2
15
  accelerate==1.11.0
16
  aiohttp==3.13.1
17
  huggingface-hub==0.35.3
18
- =======
19
- torch==2.8.0
20
- transformers==4.56.1
21
- pytorch-lightning==2.5.5
22
- torchmetrics==1.8.2
23
- sentencepiece==0.2.1
24
- pandas==2.2.2
25
- scikit-learn==1.6.1
26
- gradio==5.44.1
27
- matplotlib==3.10.0
28
- seaborn==0.13.2
29
- wordcloud==1.9.4
30
- >>>>>>> e6de3c4338f79386345fa6e4bba5b0666ad808da
 
 
1
  langchain==0.3.27
2
  langchain-community==0.3.31
3
  gradio==5.49.1
 
14
  accelerate==1.11.0
15
  aiohttp==3.13.1
16
  huggingface-hub==0.35.3
 
 
 
 
 
 
 
 
 
 
 
 
 
scripts/app.py CHANGED
@@ -1,4 +1,3 @@
1
- <<<<<<< HEAD
2
  # app.py
3
 
4
  import gradio as gr
@@ -279,165 +278,3 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
279
  if __name__ == "__main__":
280
  chat_memory.clear() # Clear memory each time app starts
281
  demo.launch(debug=True)
282
- =======
283
- import gradio as gr
284
- import os
285
- import torch
286
- import pandas as pd
287
- import re
288
-
289
- # --- IMPORTANT ---
290
- # This script assumes you have a 'models.py' file in the same directory
291
- # containing the definitions for all model and inference classes.
292
- try:
293
- from models import (
294
- ReviewSummarizer,
295
- AspectAnalyzer,
296
- AspectExtractor,
297
- FineTunedSentimentClassifier
298
- )
299
- except ImportError:
300
- print("CRITICAL ERROR: Make sure 'models.py' exists and contains the required classes.")
301
- # Define dummy classes if imports fail, so Gradio can at least launch with an error message.
302
- class ReviewSummarizer: pass
303
- class AspectAnalyzer: pass
304
- class AspectExtractor: pass
305
- class FineTunedSentimentClassifier: pass
306
-
307
- # --- Configuration ---
308
- # --- IMPORTANT: UPDATE THIS PATH ---
309
- # You need to provide the path to the best checkpoint file that was saved
310
- # during the training of your sentiment model.
311
- SENTIMENT_CHECKPOINT_PATH = "checkpoints/sentiment-binary-best-checkpoint.ckpt" # <-- CHANGE THIS
312
-
313
- # --- Pre-defined Aspect Dictionaries for Different Product Categories ---
314
- ASPECT_DICTIONARIES = {
315
- "Phone": ['camera', 'battery', 'battery life', 'screen', 'performance', 'price', 'design'],
316
- "Coffee Maker": ['ease of use', 'design', 'noise level', 'coffee quality', 'brew time', 'cleaning'],
317
- "Book": ['plot', 'characters', 'writing style', 'pacing', 'ending'],
318
- "Default": ['quality', 'price', 'service', 'design', 'features'] # A fallback list
319
- }
320
-
321
-
322
- # --- 1. Load All Models (Global Objects) ---
323
- print("--- Initializing all models for the Gradio App ---")
324
- sentiment_classifier, summarizer, aspect_analyzer, aspect_extractor = None, None, None, None
325
- try:
326
- summarizer = ReviewSummarizer(force_cpu=True)
327
- aspect_analyzer = AspectAnalyzer(force_cpu=True)
328
- aspect_extractor = AspectExtractor(force_cpu=True)
329
-
330
- if not os.path.exists(SENTIMENT_CHECKPOINT_PATH):
331
- print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
332
- print("!!! WARNING: Sentiment checkpoint path not found or not set. !!!")
333
- print(f"!!! Please update the 'SENTIMENT_CHECKPOINT_PATH' variable in app.py")
334
- print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
335
- else:
336
- sentiment_classifier = FineTunedSentimentClassifier(
337
- checkpoint_path=SENTIMENT_CHECKPOINT_PATH, force_cpu=True
338
- )
339
- print("\n--- All models loaded successfully ---\n")
340
- except Exception as e:
341
- print(f"An error occurred during model initialization: {e}")
342
-
343
-
344
- # --- 2. Define the Core Analysis Function ---
345
- def analyze_review(review_text, product_category):
346
- if not review_text:
347
- return {"ERROR": "Please enter a review."}, "", None
348
-
349
- # --- a. Overall Sentiment Analysis ---
350
- if sentiment_classifier:
351
- sentiment_result = sentiment_classifier.classify(review_text)
352
- sentiment_output = {
353
- sentiment_result['label']: f"{sentiment_result['score']:.2f}"
354
- }
355
- else:
356
- sentiment_output = {"ERROR": "Fine-tuned model not loaded. Check path."}
357
-
358
- # --- b. Review Summarization ---
359
- if summarizer:
360
- summary_output = summarizer.summarize(review_text)
361
- else:
362
- summary_output = "ERROR: Summarizer model not loaded."
363
-
364
- # --- c. Dynamic Aspect Extraction & Analysis ---
365
- aspect_df = None
366
- if aspect_extractor and aspect_analyzer:
367
- aspect_dictionary = ASPECT_DICTIONARIES.get(product_category, ASPECT_DICTIONARIES["Default"])
368
- extracted_aspects = aspect_extractor.extract(review_text, aspect_dictionary=aspect_dictionary)
369
-
370
- if extracted_aspects:
371
- aspect_results = aspect_analyzer.analyze(review_text, extracted_aspects)
372
- aspect_df = pd.DataFrame([
373
- {'Aspect': aspect, 'Sentiment': result['sentiment'], 'Score': f"{result['score']:.2f}"}
374
- for aspect, result in aspect_results.items()
375
- ])
376
-
377
- return sentiment_output, summary_output, aspect_df
378
-
379
-
380
- # --- 3. Build the Gradio Interface ---
381
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
382
- gr.Markdown("# 🛍️ ReviewSense: Product Review Analysis Engine")
383
- gr.Markdown(
384
- "Enter a product review and select the product category. The tool will automatically "
385
- "detect relevant features and provide an overall sentiment score, a summary, and a "
386
- "breakdown of sentiment towards each feature."
387
- )
388
-
389
- with gr.Row():
390
- with gr.Column(scale=2):
391
- review_input = gr.Textbox(
392
- lines=10,
393
- label="Enter Product Review Here",
394
- placeholder="e.g., The camera is amazing, but the battery life is terrible..."
395
- )
396
- category_input = gr.Dropdown(
397
- choices=list(ASPECT_DICTIONARIES.keys()),
398
- label="Select Product Category",
399
- value="Phone"
400
- )
401
- analyze_button = gr.Button("Analyze Review", variant="primary")
402
-
403
- with gr.Column(scale=1):
404
- gr.Markdown("### Overall Sentiment")
405
- sentiment_output = gr.Label()
406
-
407
- gr.Markdown("### Generated Summary")
408
- summary_output = gr.Textbox(lines=5, label="Summary", interactive=False)
409
-
410
- gr.Markdown("### Detected Aspect Sentiments")
411
- aspect_output = gr.DataFrame(headers=["Aspect", "Sentiment", "Score"], label="Aspects", interactive=False)
412
-
413
- # Connect the button to the function
414
- analyze_button.click(
415
- fn=analyze_review,
416
- inputs=[review_input, category_input],
417
- outputs=[sentiment_output, summary_output, aspect_output]
418
- )
419
-
420
- gr.Examples(
421
- examples=[
422
- [
423
- "The camera on this phone is incredible, the pictures are professional quality. However, the battery life is a total disaster, it barely lasts half a day with light use. The screen is bright and responsive, which I love.",
424
- "Phone"
425
- ],
426
- [
427
- "I am absolutely in love with this coffee maker! It's incredibly easy to use, brews a perfect cup every single time, and the design looks fantastic on my countertop. It's also surprisingly quiet.",
428
- "Coffee Maker"
429
- ],
430
- [
431
- "An amazing story with characters that felt so real. The plot had me hooked from the first page, though I felt the ending was a bit rushed.",
432
- "Book"
433
- ]
434
- ],
435
- inputs=[review_input, category_input]
436
- )
437
-
438
-
439
- # --- 4. Launch the App ---
440
- if __name__ == "__main__":
441
- print("Launching Gradio App...")
442
- demo.launch()
443
- >>>>>>> e6de3c4338f79386345fa6e4bba5b0666ad808da
 
 
1
  # app.py
2
 
3
  import gradio as gr
 
278
  if __name__ == "__main__":
279
  chat_memory.clear() # Clear memory each time app starts
280
  demo.launch(debug=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
scripts/main.py CHANGED
@@ -1,4 +1,3 @@
1
- <<<<<<< HEAD
2
  # main.py
3
 
4
  import torch
@@ -211,114 +210,3 @@ if __name__ == "__main__":
211
  print("\n--- Chat session ended. ---")
212
 
213
  print("\n--- Local Execution Finished ---")
214
- =======
215
- import os
216
- import torch
217
- import pandas as pd
218
-
219
- try:
220
- from data_prepare import ReviewDataset, ReviewDataModule
221
- from models import SentimentClassifier, ReviewSummarizer, AspectAnalyzer, FineTunedSentimentClassifier, AspectExtractor
222
- except ImportError:
223
- print("CRITICAL ERROR: Make sure 'review_summarizer.py', 'aspect_extractor.py', and 'sentiment_classifier_model.py' are in the same directory.")
224
- exit()
225
-
226
- # --- Configuration ---
227
- # --- IMPORTANT: UPDATE THIS PATH ---
228
- # You need to provide the path to the best checkpoint file that was saved
229
- # during the training of your sentiment model.
230
- SENTIMENT_CHECKPOINT_PATH = "checkpoints/sentiment-binary-best-checkpoint.ckpt"
231
-
232
- # --- Pre-defined Aspect Dictionaries for Different Product Categories ---
233
- ASPECT_DICTIONARIES = {
234
- "Phone": ['camera', 'battery', 'battery life', 'screen', 'performance', 'price', 'design'],
235
- "Coffee Maker": ['ease of use', 'design', 'noise level', 'coffee quality', 'brew time', 'cleaning'],
236
- "Book": ['plot', 'characters', 'writing style', 'pacing', 'ending'],
237
- "Default": ['quality', 'price', 'service', 'design', 'features'] # A fallback list
238
- }
239
-
240
- def main():
241
- """
242
- Main function to run the command-line review analysis tool.
243
- """
244
- # --- 1. Load All Models ---
245
- print("--- Initializing all models ---")
246
- sentiment_classifier, summarizer, aspect_analyzer, aspect_extractor = None, None, None, None
247
- try:
248
- summarizer = ReviewSummarizer(force_cpu=True)
249
- aspect_analyzer = AspectAnalyzer(force_cpu=True)
250
- aspect_extractor = AspectExtractor(force_cpu=True)
251
-
252
- if not os.path.exists(SENTIMENT_CHECKPOINT_PATH):
253
- print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
254
- print("!!! WARNING: Sentiment checkpoint path not found or not set. !!!")
255
- print(f"!!! Please update the 'SENTIMENT_CHECKPOINT_PATH' variable in main.py")
256
- print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
257
- else:
258
- sentiment_classifier = FineTunedSentimentClassifier(
259
- checkpoint_path=SENTIMENT_CHECKPOINT_PATH, force_cpu=True
260
- )
261
- print("\n--- All models loaded successfully ---\n")
262
- except Exception as e:
263
- print(f"An error occurred during model initialization: {e}")
264
- return
265
-
266
- # --- 2. Interactive Loop ---
267
- while True:
268
- print("\n==================================================")
269
- print(" Product Review Analysis Tool ")
270
- print("==================================================")
271
-
272
- # Get user input
273
- review_text = input("Enter the product review text (or type 'quit' to exit):\n> ")
274
- if review_text.lower() == 'quit':
275
- break
276
-
277
- print("\nAvailable Product Categories:")
278
- for i, category in enumerate(ASPECT_DICTIONARIES.keys(), 1):
279
- print(f"{i}. {category}")
280
-
281
- category_choice = input(f"Select a product category (1-{len(ASPECT_DICTIONARIES)}):\n> ")
282
- try:
283
- category_idx = int(category_choice) - 1
284
- product_category = list(ASPECT_DICTIONARIES.keys())[category_idx]
285
- except (ValueError, IndexError):
286
- print("Invalid choice. Using 'Default' category.")
287
- product_category = "Default"
288
-
289
- # --- 3. Run Analysis ---
290
- print("\n--- Analyzing Review... ---")
291
-
292
- # a. Overall Sentiment
293
- sentiment_result = sentiment_classifier.classify(review_text)
294
-
295
- # b. Summary
296
- summary_result = summarizer.summarize(review_text)
297
-
298
- # c. Aspect Extraction and Analysis
299
- aspect_dictionary = ASPECT_DICTIONARIES.get(product_category)
300
- extracted_aspects = aspect_extractor.extract(review_text, aspect_dictionary)
301
- aspect_results = None
302
- if extracted_aspects:
303
- aspect_results = aspect_analyzer.analyze(review_text, extracted_aspects)
304
-
305
- # --- 4. Display Results ---
306
- print("\n-------------------- ANALYSIS RESULTS --------------------")
307
- print(f"\n[ Overall Sentiment ]")
308
- print(f" - Sentiment: {sentiment_result['label']} (Score: {sentiment_result['score']:.2f})")
309
-
310
- print(f"\n[ Generated Summary ]")
311
- print(f" - {summary_result}")
312
-
313
- print(f"\n[ Detected Aspect Sentiments ]")
314
- if aspect_results:
315
- for aspect, result in aspect_results.items():
316
- print(f" - {aspect.title()}: {result['sentiment']} (Score: {result['score']:.2f})")
317
- else:
318
- print(" - No relevant aspects from the dictionary were detected in the review.")
319
- print("----------------------------------------------------------")
320
-
321
-
322
- if __name__ == "__main__":
323
- main()
324
- >>>>>>> e6de3c4338f79386345fa6e4bba5b0666ad808da
 
 
1
  # main.py
2
 
3
  import torch
 
210
  print("\n--- Chat session ended. ---")
211
 
212
  print("\n--- Local Execution Finished ---")