Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from transformers import pipeline | |
| import torch | |
| import shutil | |
| from pathlib import Path | |
| from plotly.subplots import make_subplots | |
| import plotly.graph_objects as go | |
| print("Loading model from Hugging Face Hub...") | |
| MODEL_NAME = "facebook/bart-large-mnli" | |
| emotion_classifier = pipeline( | |
| "zero-shot-classification", | |
| model=MODEL_NAME, | |
| device=0 if torch.cuda.is_available() else -1, | |
| ) | |
| print(f"Model '{MODEL_NAME}' loaded from Hugging Face Hub") | |
| cache_dir = Path(".gradio") / "cached_examples" | |
| if cache_dir.exists(): | |
| shutil.rmtree(cache_dir, ignore_errors=True) | |
| EMOTIONS = [ | |
| "admiration", | |
| "adoration", | |
| "aesthetic appreciation", | |
| "amusement", | |
| "anger", | |
| "anxiety", | |
| "awe", | |
| "awkwardness", | |
| "boredom", | |
| "calmness", | |
| "confusion", | |
| "craving", | |
| "disgust", | |
| "empathic pain", | |
| "entrancement", | |
| "excitement", | |
| "fear", | |
| "horror", | |
| "interest", | |
| "joy", | |
| "nostalgia", | |
| "relief", | |
| "romance", | |
| "sadness", | |
| "satisfaction", | |
| "sexual desire", | |
| "surprise", | |
| ] | |
| def analyze_emotions(text: str): | |
| """Return percentage breakdown across the requested emotions plus chart.""" | |
| if not text or not text.strip(): | |
| return "Please enter some text", create_empty_table(), create_empty_chart() | |
| trimmed = text.strip()[:512] | |
| result = emotion_classifier( | |
| trimmed, candidate_labels=EMOTIONS, multi_label=True | |
| ) | |
| scores = dict(zip(result["labels"], result["scores"])) | |
| total = sum(scores.values()) or 1.0 | |
| normalized = {label: score / total for label, score in scores.items()} | |
| dominant = max(normalized, key=normalized.get) | |
| summary = f"Dominant emotion: {dominant.title()} ({normalized[dominant] * 100:.1f}%)" | |
| sorted_rows = sorted( | |
| ((label.title(), round(normalized.get(label, 0) * 100, 2)) for label in EMOTIONS), | |
| key=lambda row: row[1], | |
| reverse=True, | |
| ) | |
| chart = build_emotion_chart(normalized) | |
| return summary, sorted_rows, chart | |
| def create_empty_table(): | |
| return [[label.title(), 0.0] for label in EMOTIONS] | |
| def create_empty_chart(): | |
| fig = go.Figure() | |
| fig.update_layout( | |
| template="plotly_white", | |
| xaxis=dict(visible=False), | |
| yaxis=dict(visible=False), | |
| paper_bgcolor="rgba(255,255,255,0.95)", | |
| plot_bgcolor="rgba(255,255,255,0.95)", | |
| annotations=[ | |
| dict( | |
| text="Emotion chart will appear here after analysis.", | |
| x=0.5, | |
| y=0.5, | |
| showarrow=False, | |
| font=dict(size=14, color="#475569", family="Arial, sans-serif"), | |
| ) | |
| ], | |
| height=420, | |
| ) | |
| return fig | |
| def build_emotion_chart(score_dict): | |
| if not score_dict: | |
| return create_empty_chart() | |
| sorted_pairs = sorted(score_dict.items(), key=lambda item: item[1], reverse=True) | |
| top_pairs = sorted_pairs[:6] | |
| labels = [label.title() for label, _ in top_pairs] | |
| values = [round(score * 100, 2) for _, score in top_pairs] | |
| colors = [ | |
| "#2563eb", | |
| "#1d4ed8", | |
| "#3b82f6", | |
| "#60a5fa", | |
| "#93c5fd", | |
| "#dbeafe", | |
| ] | |
| fig = make_subplots( | |
| rows=1, | |
| cols=2, | |
| specs=[[{"type": "polar"}, {"type": "xy"}]], | |
| subplot_titles=("Radar View", "Bar View"), | |
| ) | |
| # Radar chart | |
| radar_labels = labels + labels[:1] | |
| radar_values = values + values[:1] | |
| fig.add_trace( | |
| go.Scatterpolar( | |
| r=radar_values, | |
| theta=radar_labels, | |
| fill="toself", | |
| name="Top Emotions", | |
| fillcolor="rgba(37, 99, 235, 0.25)", | |
| line=dict(color="#2563eb", width=2.5), | |
| marker=dict(size=6, color="#2563eb"), | |
| ), | |
| row=1, | |
| col=1, | |
| ) | |
| # Bar chart | |
| fig.add_trace( | |
| go.Bar( | |
| x=values[::-1], | |
| y=labels[::-1], | |
| orientation="h", | |
| marker=dict( | |
| color=values[::-1], | |
| colorscale=[[0, "#dbeafe"], [0.5, "#60a5fa"], [1, "#2563eb"]], | |
| showscale=True, | |
| colorbar=dict(title="%", len=0.4, y=0.3), | |
| line=dict(color="#1d4ed8", width=1), | |
| ), | |
| name="Percent", | |
| text=[f"{v:.1f}%" for v in values[::-1]], | |
| textposition="outside", | |
| ), | |
| row=1, | |
| col=2, | |
| ) | |
| fig.update_layout( | |
| template="plotly_white", | |
| height=420, | |
| showlegend=False, | |
| margin=dict(l=40, r=40, t=60, b=40), | |
| paper_bgcolor="rgba(255,255,255,0.95)", | |
| plot_bgcolor="rgba(255,255,255,0.95)", | |
| font=dict(family="Arial, sans-serif", size=11, color="#0f172a"), | |
| polar=dict( | |
| radialaxis=dict( | |
| visible=True, | |
| range=[0, max(60, max(values) + 10)], | |
| tickfont=dict(size=10, color="#475569"), | |
| gridcolor="rgba(148,163,184,0.3)", | |
| linecolor="#cbd5e1", | |
| ), | |
| angularaxis=dict( | |
| direction="clockwise", | |
| tickfont=dict(size=10, color="#0f172a"), | |
| linecolor="#cbd5e1", | |
| ), | |
| bgcolor="rgba(255,255,255,0.95)", | |
| ), | |
| xaxis=dict( | |
| title=dict(text="Percent (%)", font=dict(size=12, color="#0f172a")), | |
| tickfont=dict(size=10, color="#475569"), | |
| gridcolor="rgba(148,163,184,0.2)", | |
| linecolor="#cbd5e1", | |
| ), | |
| yaxis=dict( | |
| tickfont=dict(size=10, color="#0f172a"), | |
| gridcolor="rgba(148,163,184,0.2)", | |
| linecolor="#cbd5e1", | |
| ), | |
| ) | |
| return fig | |
| def clear_fields(): | |
| return "", "", create_empty_table(), create_empty_chart() | |
| examples = [ | |
| ["Zahir Knows a lot of things but he unables to share it with others. but he is a good person."], | |
| ["The weather is pleaseant in kunming."], | |
| ["Zahir always gives me a hard time."], | |
| ["I'm not sure how I feel about this. It has both good and bad aspects."], | |
| ["The customer service was terrible and the product arrived damaged."], | |
| ["I appreciate your help, but there is still some confusion."], | |
| ] | |
| with gr.Blocks(title="Emotion Analysis") as demo: | |
| gr.Markdown( | |
| """ | |
| # Emotion Analysis App | |
| Enter text and the model will estimate the percentage across 27 nuanced emotions | |
| (from admiration and amusement to romance, sexual desire, and surprise). | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(): | |
| text_input = gr.Textbox( | |
| label="Enter text", | |
| placeholder="Type your text here...", | |
| lines=5, | |
| ) | |
| analyze_btn = gr.Button("Analyze", variant="primary") | |
| clear_btn = gr.Button("Clear") | |
| with gr.Column(): | |
| sentiment_output = gr.Textbox(label="Summary", interactive=False) | |
| confidence_output = gr.Dataframe( | |
| headers=["Emotion", "Percent (%)"], | |
| datatype=["str", "number"], | |
| label="Emotion Breakdown (%)", | |
| interactive=False, | |
| ) | |
| chart_output = gr.Plot(label="Emotion Comparison") | |
| gr.Examples( | |
| examples=examples, | |
| inputs=text_input, | |
| outputs=[sentiment_output, confidence_output, chart_output], | |
| fn=analyze_emotions, | |
| cache_examples=False, | |
| ) | |
| gr.Markdown( | |
| """ | |
| --- | |
| **Model**: `facebook/bart-large-mnli` (zero-shot classification) | |
| **Emotions**: Admiration, Adoration, Aesthetic Appreciation, Amusement, Anger, Anxiety, Awe, Awkwardness, Boredom, Calmness, Confusion, Craving, Disgust, Empathic Pain, Entrancement, Excitement, Fear, Horror, Interest, Joy, Nostalgia, Relief, Romance, Sadness, Satisfaction, Sexual Desire, Surprise | |
| --- | |
| **Developed by**: SUDIPTA ROY | |
| """ | |
| ) | |
| analyze_btn.click( | |
| fn=analyze_emotions, | |
| inputs=text_input, | |
| outputs=[sentiment_output, confidence_output, chart_output], | |
| ) | |
| text_input.submit( | |
| fn=analyze_emotions, | |
| inputs=text_input, | |
| outputs=[sentiment_output, confidence_output, chart_output], | |
| ) | |
| clear_btn.click( | |
| fn=clear_fields, | |
| inputs=None, | |
| outputs=[text_input, sentiment_output, confidence_output, chart_output], | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch(share=True) | |