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()