import gradio as gr from transformers import pipeline # --- Model Loading --- # Using the model ID you've been working with, which is fine-tuned on an English dataset (IMDB). # It's crucial that this model is indeed fine-tuned for sentiment analysis in English. MODEL_ID = "Light-Dav/sentiment-analysis-full-project" try: # Attempt to load the pipeline. This needs to be outside the function for efficiency. # The 'return_all_scores=True' is important for getting scores for all labels. sentiment_analyzer = pipeline("sentiment-analysis", model=MODEL_ID, return_all_scores=True) model_loaded_successfully = True except Exception as e: print(f"Error loading model: {e}") sentiment_analyzer = None model_loaded_successfully = False # --- Custom CSS for a unique look --- custom_css = """ body { background-color: #f0f2f5; /* Light grey background */ } .gradio-container { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); border-radius: 15px; overflow: hidden; background-color: #ffffff; /* White card background */ } h1, h2, h3 { color: #4CAF50; /* Green accents */ text-align: center; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; animation: fadeIn 1s ease-in-out; } .gr-button.primary { background-color: #4CAF50 !important; color: white !important; border-radius: 8px; transition: background-color 0.3s ease; } .gr-button.primary:hover { background-color: #45a049 !important; } .gradio-output { border: 1px solid #e0e0e0; border-radius: 10px; padding: 15px; margin-top: 20px; background-color: #f9f9f9; } .sentiment-display { text-align: center; padding: 10px; border-radius: 8px; margin-top: 15px; font-size: 1.2em; font-weight: bold; } .sentiment-positive { background-color: #e6ffe6; /* Light green */ color: #28a745; /* Darker green */ } .sentiment-negative { background-color: #ffe6e6; /* Light red */ color: #dc3545; /* Darker red */ } .sentiment-neutral { background-color: #e6f7ff; /* Light blue */ color: #007bff; /* Darker blue */ } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } """ # --- Helper Function for Sentiment Interpretation --- def interpret_sentiment(label, score): emoji = "" description = "" color_class = "" if label.lower() == "positive": # Your model might output 'LABEL_2' or 'POS' emoji = "😊" description = "This text expresses a **highly positive** sentiment." if score > 0.9 else "This text expresses a **positive** sentiment." color_class = "sentiment-positive" elif label.lower() == "negative": # Your model might output 'LABEL_0' or 'NEG' emoji = "😠" description = "This text expresses a **highly negative** sentiment." if score > 0.9 else "This text expresses a **negative** sentiment." color_class = "sentiment-negative" elif label.lower() == "neutral": # Your model might output 'LABEL_1' or 'NEUTRAL' emoji = "😐" description = "This text expresses a **neutral** sentiment." color_class = "sentiment-neutral" else: emoji = "❓" description = "Could not confidently determine sentiment." color_class = "" return f"
{description}
" # --- Sentiment Analysis Function --- def analyze_sentiment(text): if not model_loaded_successfully: return { "Overall Sentiment": "Please contact the administrator. The sentiment analysis model failed to load.
", "Confidence Scores": {}, "Raw Output": "Model loading failed." } if not text.strip(): return { "Overall Sentiment": "Start typing to analyze its sentiment.
", "Confidence Scores": {}, "Raw Output": "" } try: # The pipeline returns a list of dictionaries if return_all_scores=True # e.g., [[{'label': 'LABEL_0', 'score': 0.9}, {'label': 'LABEL_1', 'score': 0.05}]] results = sentiment_analyzer(text)[0] # Get the first (and only) list of results # Sort results by score in descending order results_sorted = sorted(results, key=lambda x: x['score'], reverse=True) # Get the top sentiment top_sentiment = results_sorted[0] label = top_sentiment['label'] score = top_sentiment['score'] # Format for Gradio Label component (Dictionary {label: score}) # This is for the 'Confidence Scores' output confidence_scores_output = {item['label']: item['score'] for item in results} # Interpret sentiment for the 'Overall Sentiment' output overall_sentiment_display = interpret_sentiment(label, score) return { "Overall Sentiment": overall_sentiment_display, "Confidence Scores": confidence_scores_output, "Raw Output": str(results) } except Exception as e: return { "Overall Sentiment": f"An error occurred during analysis: {e}
", "Confidence Scores": {}, "Raw Output": f"Error: {e}" } # --- Gradio Interface --- with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo: # Using gr.Blocks for more layout control gr.Markdown("# ✨ Sentiment Spark ✨") gr.Markdown("---") gr.Markdown("### Uncover the emotional tone of your English text instantly!") with gr.Row(): # Horizontal layout for input and outputs with gr.Column(scale=2): text_input = gr.Textbox( lines=7, placeholder="Type your English text here...", label="Your Text", interactive=True, value="This movie was absolutely brilliant! A masterpiece of storytelling and emotion." ) analyze_btn = gr.Button("Analyze Sentiment", variant="primary") # The main action button gr.Markdown("---") gr.Markdown("### Try some examples:") gr.Examples( examples=[ ["This product exceeded my expectations, truly amazing!"], ["I found the customer service to be quite disappointing and slow."], ["The weather forecast predicts light rain for tomorrow morning."], ["What a fantastic experience! Highly recommend it."], ["I'm so frustrated with this slow internet connection."], ["The meeting concluded without any major decisions."] ], inputs=text_input, cache_examples=True # Caching examples for faster loading ) with gr.Column(scale=3): gr.Markdown("## 📈 Analysis Results 📉") overall_sentiment_output = gr.HTML(label="Overall Sentiment") # Using HTML to render custom styled sentiment confidence_scores_output = gr.Label(num_top_classes=3, label="Confidence Scores") # Default Gradio Label raw_output = gr.JSON(label="Raw Model Output", visible=False) # For debugging/advanced users # --- Event Listeners --- text_input.change( fn=analyze_sentiment, inputs=text_input, outputs=[overall_sentiment_output, confidence_scores_output, raw_output], # live=True # Uncomment for live updates as user types (can be resource intensive) ) analyze_btn.click( fn=analyze_sentiment, inputs=text_input, outputs=[overall_sentiment_output, confidence_scores_output, raw_output] ) demo.launch()