Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,83 +1,125 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
import pandas as pd
|
| 3 |
import numpy as np
|
|
|
|
|
|
|
| 4 |
from sklearn.feature_extraction.text import TfidfVectorizer
|
| 5 |
from sklearn.ensemble import RandomForestClassifier
|
| 6 |
-
from sklearn.
|
|
|
|
| 7 |
|
| 8 |
-
# 1. SETUP
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
try:
|
| 12 |
-
df = pd.read_csv('messages_emojis.csv').dropna(subset=['content'])
|
| 13 |
-
except:
|
| 14 |
-
# Fallback dummy data for demonstration if file is missing
|
| 15 |
-
data = {
|
| 16 |
-
'content': ["I love this!", "That is so scary", "Hahaha so funny", "I agree", "I am sad"],
|
| 17 |
-
'emoji': ["โค๏ธ", "๐ฎ", "๐", "๐", "๐ข"]
|
| 18 |
-
}
|
| 19 |
-
df = pd.DataFrame(data)
|
| 20 |
-
|
| 21 |
-
sent_map = {'โค๏ธ':'Pos', '๐':'Pos', '๐':'Pos', '๐ฏ':'Pos', '๐ข':'Neg', '๐ญ':'Neg', '๐ฎ':'Neu'}
|
| 22 |
-
intent_map = {'โค๏ธ':'Emotion', '๐':'Agreement', '๐':'Emotion', '๐ฎ':'Surprise'}
|
| 23 |
-
|
| 24 |
-
get_sent = lambda x: sent_map.get(x, 'Neutral')
|
| 25 |
-
get_intent = lambda x: intent_map.get(x, 'Other')
|
| 26 |
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
|
| 34 |
-
#
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
X = tfidf.fit_transform(dataset.data)
|
| 38 |
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
|
| 43 |
-
# 3. CHAT LOGIC
|
| 44 |
def predict_all(text):
|
| 45 |
vec = tfidf.transform([text])
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
| 50 |
|
|
|
|
| 51 |
def chat_response(message, history):
|
| 52 |
-
|
| 53 |
|
| 54 |
-
#
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
]
|
| 60 |
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
for
|
| 64 |
-
|
|
|
|
| 65 |
|
| 66 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
-
|
| 69 |
-
#
|
| 70 |
-
|
| 71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
theme="soft",
|
| 79 |
-
avatar_images=[user_avatar, bot_avatar]
|
| 80 |
-
)
|
| 81 |
|
| 82 |
-
|
| 83 |
-
demo.launch()
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import pandas as pd
|
| 3 |
import numpy as np
|
| 4 |
+
import time
|
| 5 |
+
import random
|
| 6 |
from sklearn.feature_extraction.text import TfidfVectorizer
|
| 7 |
from sklearn.ensemble import RandomForestClassifier
|
| 8 |
+
from sklearn.svm import SVC
|
| 9 |
+
from sklearn.naive_bayes import MultinomialNB
|
| 10 |
|
| 11 |
+
# 1. SETUP DATA AND MAPPINGS (From your Notebook)
|
| 12 |
+
SENT_MAP = {'โค๏ธ':'Pos', '๐':'Pos', '๐':'Pos', '๐ฏ':'Pos', '๐ข':'Neg', '๐ญ':'Neg', '๐ฎ':'Neu'}
|
| 13 |
+
INTENT_MAP = {'โค๏ธ':'Emotion', '๐':'Agreement', '๐':'Emotion', '๐ฎ':'Surprise'}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
+
def get_sent(emoji): return SENT_MAP.get(emoji, 'Neutral')
|
| 16 |
+
def get_intent(emoji): return INTENT_MAP.get(emoji, 'Other')
|
| 17 |
+
|
| 18 |
+
# Mock Data for training (As the CSV isn't provided, we use a small seed set)
|
| 19 |
+
# In your Space, you can replace this by loading your actual CSV
|
| 20 |
+
data = {
|
| 21 |
+
'content': ["I love this!", "That is so sad", "Wow really?", "I agree with you", "LMAO", "I am angry"],
|
| 22 |
+
'emoji': ["โค๏ธ", "๐ข", "๐ฎ", "๐", "๐", "๐ข"]
|
| 23 |
+
}
|
| 24 |
+
df = pd.DataFrame(data)
|
| 25 |
+
df['sentiment'] = df['emoji'].apply(get_sent)
|
| 26 |
+
df['intent'] = df['emoji'].apply(get_intent)
|
| 27 |
+
|
| 28 |
+
# 2. TRAIN MODELS
|
| 29 |
+
tfidf = TfidfVectorizer(max_features=1000)
|
| 30 |
+
X = tfidf.fit_transform(df['content'])
|
| 31 |
+
|
| 32 |
+
# Emoji Models
|
| 33 |
+
model_rf_emoji = RandomForestClassifier().fit(X, df['emoji'])
|
| 34 |
+
model_svm_emoji = SVC(probability=True).fit(X, df['emoji'])
|
| 35 |
+
model_nb_emoji = MultinomialNB().fit(X, df['emoji'])
|
| 36 |
|
| 37 |
+
# Sentiment & Intent Models (Using Random Forest as base)
|
| 38 |
+
model_sent = RandomForestClassifier().fit(X, df['sentiment'])
|
| 39 |
+
model_intent = RandomForestClassifier().fit(X, df['intent'])
|
|
|
|
| 40 |
|
| 41 |
+
# 3. HELPER FUNCTIONS
|
| 42 |
+
def get_avatar(name):
|
| 43 |
+
return f"https://api.dicebear.com/7.x/avataaars/svg?seed={name}"
|
| 44 |
|
|
|
|
| 45 |
def predict_all(text):
|
| 46 |
vec = tfidf.transform([text])
|
| 47 |
+
return {
|
| 48 |
+
"Random Forest": model_rf_emoji.predict(vec)[0],
|
| 49 |
+
"SVM": model_svm_emoji.predict(vec)[0],
|
| 50 |
+
"Naive Bayes": model_nb_emoji.predict(vec)[0],
|
| 51 |
+
"Sentiment": model_sent.predict(vec)[0],
|
| 52 |
+
"Intent": model_intent.predict(vec)[0]
|
| 53 |
+
}
|
| 54 |
|
| 55 |
+
# 4. CHAT LOGIC
|
| 56 |
def chat_response(message, history):
|
| 57 |
+
preds = predict_all(message)
|
| 58 |
|
| 59 |
+
# User's message with reactions
|
| 60 |
+
# We format reactions as a small row at the bottom
|
| 61 |
+
reactions_html = f"""
|
| 62 |
+
<div style='display: flex; gap: 5px; margin-top: 8px; font-size: 0.8em;'>
|
| 63 |
+
<span title='RF: {preds["Random Forest"]} | SVM: {preds["SVM"]} | NB: {preds["Naive Bayes"]}'
|
| 64 |
+
style='background: #f0f2f5; padding: 2px 8px; border-radius: 12px; cursor: help;'>
|
| 65 |
+
{preds["Random Forest"]} {preds["SVM"]} {preds["Naive Bayes"]}
|
| 66 |
+
</span>
|
| 67 |
+
</div>
|
| 68 |
+
"""
|
| 69 |
+
history.append({"role": "user", "content": message + reactions_html})
|
| 70 |
+
yield history
|
| 71 |
+
|
| 72 |
+
# Simulate group chat replies
|
| 73 |
+
bots = [
|
| 74 |
+
{"name": "The Forester (RF)", "avatar": get_avatar("Forester")},
|
| 75 |
+
{"name": "The Maverick (SVM)", "avatar": get_avatar("Maverick")},
|
| 76 |
+
{"name": "The Sage (NB)", "avatar": get_avatar("Sage")}
|
| 77 |
]
|
| 78 |
|
| 79 |
+
random.shuffle(bots)
|
| 80 |
+
|
| 81 |
+
for bot in bots:
|
| 82 |
+
# Random delay for typing simulation
|
| 83 |
+
time.sleep(random.uniform(0.5, 1.5))
|
| 84 |
|
| 85 |
+
bot_msg = f"**Sentiment:** {preds['Sentiment']} \n**Intent:** {preds['Intent']}"
|
| 86 |
+
history.append({
|
| 87 |
+
"role": "assistant",
|
| 88 |
+
"content": bot_msg,
|
| 89 |
+
"metadata": {"title": bot["name"]},
|
| 90 |
+
"avatar": bot["avatar"]
|
| 91 |
+
})
|
| 92 |
+
yield history
|
| 93 |
+
|
| 94 |
+
# 5. UI CONSTRUCTION
|
| 95 |
+
custom_css = """
|
| 96 |
+
.gradio-container { background-color: #e5ddd5; } /* WhatsApp Background */
|
| 97 |
+
.message-row { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
|
| 98 |
+
"""
|
| 99 |
|
| 100 |
+
with gr.Blocks(css=custom_css) as demo:
|
| 101 |
+
gr.Markdown("# ๐ฑ Multi-Model Emoji Group Chat")
|
| 102 |
+
gr.Markdown("Type a message to see how different models react and respond based on sentiment and intent.")
|
| 103 |
+
|
| 104 |
+
chatbot = gr.Chatbot(
|
| 105 |
+
bubble_full_width=False,
|
| 106 |
+
show_label=False,
|
| 107 |
+
type="messages",
|
| 108 |
+
avatar_images=(None, "https://api.dicebear.com/7.x/avataaars/svg?seed=User")
|
| 109 |
+
)
|
| 110 |
+
|
| 111 |
+
with gr.Row():
|
| 112 |
+
txt = gr.Textbox(
|
| 113 |
+
show_label=False,
|
| 114 |
+
placeholder="Type a message...",
|
| 115 |
+
scale=4
|
| 116 |
+
)
|
| 117 |
+
submit_btn = gr.Button("Send", variant="primary")
|
| 118 |
|
| 119 |
+
# Hooking up logic
|
| 120 |
+
txt.submit(chat_response, [txt, chatbot], [chatbot])
|
| 121 |
+
submit_btn.click(chat_response, [txt, chatbot], [chatbot])
|
| 122 |
+
txt.submit(lambda: "", None, [txt]) # Clear textbox
|
| 123 |
+
submit_btn.click(lambda: "", None, [txt])
|
|
|
|
|
|
|
|
|
|
| 124 |
|
| 125 |
+
demo.launch()
|
|
|