Dhrubob's picture
Update app.py
a2e6bf6 verified
raw
history blame
5.28 kB
import gradio as gr
from transformers import pipeline
import pandas as pd
from datetime import datetime
import os
# ----------------------------------------------------
# Load pretrained Hugging Face emotion model
# ----------------------------------------------------
model_name = "superb/hubert-large-superb-er"
emotion_classifier = pipeline("audio-classification", model=model_name)
# Emotion mapping
EMOTION_MAP = {
"ang": ("Angry", "😑"),
"hap": ("Happy", "πŸ˜„"),
"neu": ("Neutral", "😐"),
"sad": ("Sad", "😒"),
"exc": ("Excited", "🀩"),
"fru": ("Frustrated", "😀"),
"fea": ("Fearful", "😨"),
"sur": ("Surprised", "😲"),
"dis": ("Disgusted", "🀒"),
}
# ----------------------------------------------------
# Setup data storage
# ----------------------------------------------------
os.makedirs("data", exist_ok=True)
CSV_PATH = "data/customer_complaints_emotion.csv"
ORDER_ISSUES = [
"Late Delivery",
"Damaged Package",
"Wrong Product Delivered",
"Missing Items",
"Rude Delivery Staff",
"Payment Issue",
"Return/Refund Request",
"Order Cancelled Automatically",
"Other Complaint"
]
# ----------------------------------------------------
# Priority estimation
# ----------------------------------------------------
def get_priority(label, score):
if label in ["Angry", "Frustrated", "Fearful", "Disgusted"] and score >= 60:
return "πŸ”΄ High Priority"
elif label in ["Sad", "Surprised", "Excited"] and score >= 50:
return "🟠 Medium Priority"
else:
return "🟒 Low Priority"
# ----------------------------------------------------
# Main analysis function
# ----------------------------------------------------
def analyze_complaint(audio_file, complaint_type, order_id):
if audio_file is None or not complaint_type or not order_id:
return (
"⚠️ Please upload an audio complaint, select issue type, and enter Order ID.",
"",
None
)
# Run model
results = emotion_classifier(audio_file)
results = sorted(results, key=lambda x: x['score'], reverse=True)
top = results[0]
label, emoji = EMOTION_MAP.get(top['label'], (top['label'], "🎭"))
score = round(top['score'] * 100, 2)
priority = get_priority(label, score)
# Dashboard summary (markdown)
summary = f"""
### 🎯 Detected Emotion: {emoji} **{label.upper()} ({score}%)**
### ⚑ Priority Level: {priority}
---
**Complaint Type:** {complaint_type}
**Order ID:** {order_id}
**Timestamp:** {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
"""
# Detailed emotion breakdown
breakdown = "### πŸ“Š Emotion Breakdown\n"
for r in results:
lbl, emo = EMOTION_MAP.get(r['label'], (r['label'], "🎭"))
scr = round(r['score'] * 100, 2)
bar = "β–ˆ" * int(scr / 5)
breakdown += f"{emo} **{lbl}**: {scr}% \n{bar}\n\n"
# Save log to CSV
df = pd.DataFrame({
"datetime": [datetime.now().strftime("%Y-%m-%d %H:%M:%S")],
"order_id": [order_id],
"complaint_type": [complaint_type],
"emotion": [label],
"score": [score],
"priority": [priority]
})
if os.path.exists(CSV_PATH):
df.to_csv(CSV_PATH, mode="a", header=False, index=False)
else:
df.to_csv(CSV_PATH, index=False)
# Display updated log
try:
log_df = pd.read_csv(CSV_PATH).tail(10)
except:
log_df = pd.DataFrame()
return summary, breakdown, log_df
# ----------------------------------------------------
# Gradio Interface with Blocks
# ----------------------------------------------------
with gr.Blocks(theme=gr.themes.Soft(), title="Customer Complaint Emotion Analyzer") as app:
gr.Markdown(
"""
# 🎧 Customer Complaint Emotion Analyzer
Analyze customer **voice complaints** to detect emotional tone and **auto-prioritize** based on urgency.
Ideal for logistics, delivery, and supply chain customer service operations.
---
"""
)
with gr.Row():
audio_input = gr.Audio(type="filepath", label="πŸŽ™οΈ Upload Complaint Audio")
complaint_type = gr.Dropdown(ORDER_ISSUES, label="🚚 Complaint Type", interactive=True)
order_id = gr.Textbox(label="πŸ“¦ Order ID / Reference Number", placeholder="e.g., ORD123456")
analyze_btn = gr.Button("πŸ” Analyze Complaint", variant="primary")
with gr.Row():
summary_output = gr.Markdown(label="Summary")
breakdown_output = gr.Markdown(label="Detailed Breakdown")
with gr.Accordion("πŸ“ Recent Complaint Logs (Last 10 Entries)", open=False):
log_table = gr.Dataframe(headers=["datetime", "order_id", "complaint_type", "emotion", "score", "priority"], interactive=False)
analyze_btn.click(
fn=analyze_complaint,
inputs=[audio_input, complaint_type, order_id],
outputs=[summary_output, breakdown_output, log_table],
)
gr.Markdown("---")
gr.Markdown("πŸ‘¨β€πŸ’Ό **Developed for Supply Chain Customer Service Emotion Monitoring.**")
# ----------------------------------------------------
# Run app
# ----------------------------------------------------
if __name__ == "__main__":
app.launch()