Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import joblib | |
| import numpy as np | |
| from intent import predict_intent | |
| from topic_model import get_review_topic | |
| from huggingface_hub import hf_hub_download | |
| class TextPreprocessor: | |
| """Stub class to mimic the preprocessing step used when training. | |
| The original pipeline was pickled with this class defined in ``__main__`` | |
| (a notebook). When the module is imported on HuggingFace the class lives in | |
| ``app`` instead, so unpickling fails unless we make a dummy version | |
| available under the old name. | |
| """ | |
| def __init__(self): | |
| pass | |
| def fit(self, X, y=None): | |
| return self | |
| def transform(self, X): | |
| return X | |
| def fit_transform(self, X, y=None): | |
| return X | |
| def __call__(self, x): | |
| return x | |
| # register stub in __main__ so joblib can resolve the name during unpickling | |
| import __main__ | |
| __main__.TextPreprocessor = TextPreprocessor | |
| # download sentiment pipeline and other assets from the space repo | |
| pipeline_file = hf_hub_download( | |
| repo_id="Maarij-Aqeel/Customer_review_analyzer", | |
| filename="sentiment_pipeline.pkl" | |
| ) | |
| vectorizer_file = hf_hub_download( | |
| repo_id="Maarij-Aqeel/Customer_review_analyzer", | |
| filename="tfidf_vectorizer.pkl" | |
| ) | |
| nmf_file = hf_hub_download( | |
| repo_id="Maarij-Aqeel/Customer_review_analyzer", | |
| filename="nmf_model.pkl" | |
| ) | |
| try: | |
| sentiment_pipeline = joblib.load(pipeline_file) | |
| except Exception as e: # pragma: no cover - helpful when learning | |
| raise RuntimeError("could not load sentiment pipeline: %s" % e) | |
| try: | |
| vectorizer = joblib.load(vectorizer_file) | |
| nmf_model = joblib.load(nmf_file) | |
| except Exception as e: | |
| raise RuntimeError("could not load vectorizer/nmf model: %s" % e) | |
| # the pipeline predicts integer labels (-1, 0, 1) corresponding to | |
| # default negative/neutral/positive sentiment. map them to human-readable | |
| # strings for display. | |
| label_map = { | |
| -1: "negative", | |
| 0: "neutral", | |
| 1: "positive", | |
| } | |
| def analyze_review(review_text: str): | |
| """Return sentiment, intent, topic keywords, and confidence scores for a piece of text.""" | |
| if not review_text: | |
| return "", "", "" | |
| # Get sentiment prediction and confidence scores | |
| pred = sentiment_pipeline.predict([review_text])[0] | |
| sentiment = label_map.get(pred, str(pred)) | |
| # Get probability scores for all classes | |
| proba = sentiment_pipeline.predict_proba([review_text])[0] | |
| # Map probabilities to sentiment labels | |
| confidence_map = { | |
| -1: proba[0], # negative | |
| 0: proba[1], # neutral | |
| 1: proba[2], # positive | |
| } | |
| confidence_score = confidence_map.get(pred, 0.0) | |
| confidence_text = f"Sentiment: {sentiment}\nConfidence: {confidence_score:.2%}" | |
| intent = predict_intent(review_text) | |
| topic = get_review_topic(review_text, vectorizer, nmf_model) | |
| return confidence_text, intent, topic | |
| # build a simple Gradio interface with one text input and multiple outputs. | |
| iface = gr.Interface( | |
| fn=analyze_review, | |
| inputs=gr.Textbox(lines=4, placeholder="Enter a customer review...", label="Customer Review"), | |
| outputs=[ | |
| gr.Textbox(label="Sentiment & Confidence Score"), | |
| gr.Textbox(label="Predicted Intent"), | |
| gr.Textbox(label="Topic / Keywords"), | |
| ], | |
| title="Customer Review Analyzer", | |
| description=( | |
| "Enter a customer review to analyze its sentiment, predicted intent, " | |
| "identified topics, and model confidence scores. This interactive demo " | |
| "showcases how the NLP system works in a real-world setting." | |
| ), | |
| examples=[ | |
| ["I love this product! Amazing quality and fast delivery."], | |
| ["The package arrived damaged and the refund process was slow."], | |
| ["Average product, nothing special."], | |
| ], | |
| ) | |
| if __name__ == "__main__": | |
| iface.launch() | |