Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -10,126 +10,127 @@ toxicity_pipeline = pipeline("text-classification", model="martin-ha/toxic-comme
|
|
10 |
|
11 |
EMO_THRESHOLD = 0.05 # include even lower confidence emotions
|
12 |
|
13 |
-
#
|
14 |
-
|
15 |
-
"joy":
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
}
|
22 |
|
23 |
-
|
24 |
-
RECOMMENDATIONS = {
|
25 |
-
"joy": "Keep enjoying and share your happiness with others!",
|
26 |
-
"sadness": "Take some rest, talk to a friend, or write your feelings down.",
|
27 |
-
"anger": "Take a deep breath, drink a glass of water, or go for a short walk.",
|
28 |
-
"fear": "Try relaxation techniques, deep breathing, or focus on what you can control.",
|
29 |
-
"surprise": "Reflect on the situation calmly before reacting.",
|
30 |
-
"disgust": "Step away from the situation and clear your mind for a moment."
|
31 |
-
}
|
32 |
-
|
33 |
-
# Map emotions to numeric polarity for final sentiment
|
34 |
-
EMO_SENTIMENT_MAPPING = {
|
35 |
-
"joy": 1,
|
36 |
-
"surprise": 0.5,
|
37 |
-
"sadness": -1,
|
38 |
-
"anger": -1,
|
39 |
-
"fear": -1,
|
40 |
-
"disgust": -1
|
41 |
-
}
|
42 |
-
|
43 |
-
def create_visualization(emotions, toxicity):
|
44 |
-
labels = list(emotions.keys()) + list(toxicity.keys())
|
45 |
-
scores = list(emotions.values()) + list(toxicity.values())
|
46 |
-
colors = ['#4CAF50' if e in ["joy","surprise"] else '#F44336' for e in labels]
|
47 |
-
|
48 |
fig, ax = plt.subplots(figsize=(8,5))
|
49 |
-
|
|
|
|
|
50 |
ax.set_xlim(0,1)
|
51 |
ax.set_xlabel("Confidence Score")
|
52 |
-
ax.set_title("
|
53 |
plt.tight_layout()
|
54 |
-
|
55 |
buf = BytesIO()
|
56 |
plt.savefig(buf, format="png")
|
57 |
buf.seek(0)
|
58 |
plt.close()
|
59 |
-
|
60 |
-
return f'<img src="data:image/png;base64,{img_base64}" style="max-width:100%;">'
|
61 |
|
62 |
def analyze_text(text):
|
63 |
-
#
|
64 |
-
|
65 |
-
emotions = {e["label"].lower(): e["score"] for e in
|
66 |
-
|
67 |
-
#
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
72 |
details = ""
|
73 |
-
|
74 |
-
|
75 |
-
neutral_count = 0
|
76 |
|
77 |
for i, (emo, score) in enumerate(emotions.items(), 1):
|
78 |
-
|
79 |
-
|
80 |
-
|
|
|
|
|
81 |
|
82 |
-
if polarity > 0
|
83 |
-
emo_label = "Positive"
|
84 |
-
positive_count += 1
|
85 |
-
elif polarity < 0:
|
86 |
-
emo_label = "Negative"
|
87 |
-
negative_count += 1
|
88 |
-
else:
|
89 |
-
emo_label = "Neutral"
|
90 |
-
neutral_count += 1
|
91 |
-
|
92 |
-
details += f"Emotion {i}: {emo.capitalize()} ({emo_label}, Confidence: {score:.2f})\n"
|
93 |
-
details += f"Underlying emotions: {underlying}\n"
|
94 |
-
details += f"Recommendation: {recommendation}\n\n"
|
95 |
-
|
96 |
-
# Final sentiment conclusion based on counts
|
97 |
-
total_emotions = len(emotions)
|
98 |
-
if total_emotions > 0:
|
99 |
-
positive_percent = positive_count / total_emotions
|
100 |
-
negative_percent = negative_count / total_emotions
|
101 |
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
elif
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
else:
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
|
|
|
|
125 |
|
126 |
-
# Gradio interface
|
127 |
iface = gr.Interface(
|
128 |
fn=analyze_text,
|
129 |
-
inputs=gr.Textbox(label="
|
130 |
-
outputs=[
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
)
|
134 |
|
135 |
iface.launch()
|
|
|
10 |
|
11 |
EMO_THRESHOLD = 0.05 # include even lower confidence emotions
|
12 |
|
13 |
+
# Expanded emotion mapping
|
14 |
+
EMOTION_MAPPING = {
|
15 |
+
"joy": {
|
16 |
+
"underlying": ["Relief", "Contentment", "Pride", "Love", "Gratitude", "Hope"],
|
17 |
+
"recommendation": "Keep enjoying and share your happiness with others!",
|
18 |
+
"polarity": 1
|
19 |
+
},
|
20 |
+
"sadness": {
|
21 |
+
"underlying": ["Loneliness", "Grief", "Disappointment", "Shame", "Helplessness", "Regret"],
|
22 |
+
"recommendation": "Consider talking to someone or journaling about your feelings.",
|
23 |
+
"polarity": -1
|
24 |
+
},
|
25 |
+
"anger": {
|
26 |
+
"underlying": ["Frustration", "Injustice", "Betrayal", "Resentment"],
|
27 |
+
"recommendation": "Try deep breathing or physical activity to release tension.",
|
28 |
+
"polarity": -1
|
29 |
+
},
|
30 |
+
"fear": {
|
31 |
+
"underlying": ["Anxiety", "Insecurity", "Dread", "Worry"],
|
32 |
+
"recommendation": "Focus on what you can control and practice grounding techniques.",
|
33 |
+
"polarity": -1
|
34 |
+
},
|
35 |
+
"disappointment": {
|
36 |
+
"underlying": ["Letdown", "Unmet expectations", "Discouragement"],
|
37 |
+
"recommendation": "Acknowledge the feeling, then refocus on what you can influence.",
|
38 |
+
"polarity": -1
|
39 |
+
},
|
40 |
+
"pride": {
|
41 |
+
"underlying": ["Accomplishment", "Self-worth", "Achievement"],
|
42 |
+
"recommendation": "Celebrate your success while staying humble.",
|
43 |
+
"polarity": 1
|
44 |
+
}
|
45 |
}
|
46 |
|
47 |
+
def create_visualization(emotions):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
fig, ax = plt.subplots(figsize=(8,5))
|
49 |
+
colors = ['#4CAF50' if EMOTION_MAPPING.get(e, {}).get('polarity', 0) > 0
|
50 |
+
else '#F44336' for e in emotions.keys()]
|
51 |
+
ax.barh(list(emotions.keys()), list(emotions.values()), color=colors)
|
52 |
ax.set_xlim(0,1)
|
53 |
ax.set_xlabel("Confidence Score")
|
54 |
+
ax.set_title("Emotion Analysis")
|
55 |
plt.tight_layout()
|
56 |
+
|
57 |
buf = BytesIO()
|
58 |
plt.savefig(buf, format="png")
|
59 |
buf.seek(0)
|
60 |
plt.close()
|
61 |
+
return f'<img src="data:image/png;base64,{base64.b64encode(buf.read()).decode("utf-8")}">'
|
|
|
62 |
|
63 |
def analyze_text(text):
|
64 |
+
# Emotion detection
|
65 |
+
emo_results = emotion_pipeline(text, top_k=None)
|
66 |
+
emotions = {e["label"].lower(): e["score"] for e in emo_results if e["score"] > EMO_THRESHOLD}
|
67 |
+
|
68 |
+
# Manual override for specific emotions
|
69 |
+
if "disappointment" in text.lower():
|
70 |
+
emotions["disappointment"] = max(emotions.get("disappointment", 0), 0.7)
|
71 |
+
if "pride" in text.lower():
|
72 |
+
emotions["pride"] = max(emotions.get("pride", 0), 0.8)
|
73 |
+
|
74 |
+
# Generate detailed analysis
|
75 |
details = ""
|
76 |
+
positive_emotions = []
|
77 |
+
negative_emotions = []
|
|
|
78 |
|
79 |
for i, (emo, score) in enumerate(emotions.items(), 1):
|
80 |
+
emotion_data = EMOTION_MAPPING.get(emo, {
|
81 |
+
"underlying": ["Unknown"],
|
82 |
+
"recommendation": "This emotion is complex. Reflect on its source.",
|
83 |
+
"polarity": 0
|
84 |
+
})
|
85 |
|
86 |
+
polarity = "Positive" if emotion_data["polarity"] > 0 else "Negative" if emotion_data["polarity"] < 0 else "Neutral"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
|
88 |
+
details += f"Emotion {i}: {emo.capitalize()} ({polarity}, Confidence: {score:.2f})\n"
|
89 |
+
details += f"Underlying: {', '.join(emotion_data['underlying'])}\n"
|
90 |
+
details += f"Recommendation: {emotion_data['recommendation']}\n\n"
|
91 |
+
|
92 |
+
if emotion_data["polarity"] > 0:
|
93 |
+
positive_emotions.append(emo)
|
94 |
+
elif emotion_data["polarity"] < 0:
|
95 |
+
negative_emotions.append(emo)
|
96 |
+
|
97 |
+
# Generate balanced conclusion
|
98 |
+
conclusion = "\n=== Final Analysis ===\n"
|
99 |
+
|
100 |
+
if positive_emotions:
|
101 |
+
conclusion += f"Positive emotions detected: {', '.join(positive_emotions)}\n"
|
102 |
+
if negative_emotions:
|
103 |
+
conclusion += f"Negative emotions detected: {', '.join(negative_emotions)}\n"
|
104 |
+
|
105 |
+
# Final recommendation blending
|
106 |
+
if positive_emotions and not negative_emotions:
|
107 |
+
final_rec = "Enjoy this positive moment fully!"
|
108 |
+
elif negative_emotions and not positive_emotions:
|
109 |
+
final_rec = "Consider reaching out for support if these feelings persist."
|
110 |
+
elif positive_emotions and negative_emotions:
|
111 |
+
final_rec = "You're experiencing mixed emotions. Acknowledge both sides - celebrate the positive while addressing the negative."
|
112 |
else:
|
113 |
+
final_rec = "The emotional tone is neutral or complex."
|
114 |
+
|
115 |
+
conclusion += f"\nFinal Recommendation: {final_rec}"
|
116 |
+
|
117 |
+
visualization = create_visualization(emotions)
|
118 |
+
return details + conclusion, visualization
|
119 |
|
|
|
120 |
iface = gr.Interface(
|
121 |
fn=analyze_text,
|
122 |
+
inputs=gr.Textbox(label="Your Text", placeholder="I feel proud but also disappointed..."),
|
123 |
+
outputs=[
|
124 |
+
gr.Textbox(label="Detailed Analysis"),
|
125 |
+
gr.HTML(label="Emotion Visualization")
|
126 |
+
],
|
127 |
+
title="Advanced Emotion Analyzer",
|
128 |
+
description="Detects complex emotional states including underlying emotions and provides balanced recommendations.",
|
129 |
+
examples=[
|
130 |
+
["I'm proud of my work but disappointed with the recognition"],
|
131 |
+
["I feel joyful yet anxious about the future"],
|
132 |
+
["This situation makes me both hopeful and fearful"]
|
133 |
+
]
|
134 |
)
|
135 |
|
136 |
iface.launch()
|