kedasu's picture
Update app.py
f45e918 verified
Raw
History Blame Contribute Delete
4.18 kB
import pandas as pd
import gradio as gr
import matplotlib.pyplot as plt
import io
from PIL import Image
from transformers import pipeline
# ----------------------------
# Load AI Models
# ----------------------------
sentiment_model = pipeline(
"sentiment-analysis",
model="distilbert-base-uncased-finetuned-sst-2-english"
)
theme_model = pipeline(
"zero-shot-classification",
model="valhalla/distilbart-mnli-12-3"
)
THEMES = [
"product quality",
"delivery",
"price",
"packaging",
"taste",
"customer service"
]
# ----------------------------
# Analyze One Review
# ----------------------------
def analyze_review(text):
text = str(text)[:512]
sentiment_result = sentiment_model(text)[0]
label = sentiment_result["label"]
confidence = round(sentiment_result["score"] * 100, 1)
theme_result = theme_model(text, THEMES)
top_theme = theme_result["labels"][0]
theme_score = round(theme_result["scores"][0] * 100, 1)
return label, confidence, top_theme, theme_score
# ----------------------------
# Build Charts
# ----------------------------
def build_chart(df):
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
sentiment_counts = df["Sentiment"].value_counts()
color_map = {
"POSITIVE": "#22c55e",
"NEGATIVE": "#ef4444",
"NEUTRAL": "#94a3b8"
}
colors = [color_map.get(label, "#94a3b8") for label in sentiment_counts.index]
ax1.pie(
sentiment_counts.values,
labels=sentiment_counts.index,
autopct="%1.0f%%",
colors=colors,
startangle=90,
wedgeprops=dict(width=0.5)
)
ax1.set_title("Sentiment Split")
theme_counts = df["Top Theme"].value_counts()
ax2.barh(theme_counts.index, theme_counts.values)
ax2.set_title("Top Themes")
ax2.invert_yaxis()
plt.tight_layout()
buf = io.BytesIO()
plt.savefig(buf, format="png")
plt.close(fig)
buf.seek(0)
return Image.open(buf)
# ----------------------------
# Analyze Uploaded Excel File
# ----------------------------
def analyze_excel(file):
df = pd.read_excel(file.name)
if "review_text" not in df.columns:
if "Text" in df.columns:
df = df.rename(columns={"Text": "review_text"})
else:
return (
None,
"❌ Excel file must contain a 'review_text' or 'Text' column.",
None
)
df = df.dropna(subset=["review_text"])
results = []
for _, row in df.iterrows():
label, confidence, theme, theme_confidence = analyze_review(
row["review_text"]
)
results.append(
{
"Review": str(row["review_text"])[:100] + "...",
"Sentiment": label,
"Confidence %": confidence,
"Top Theme": theme,
"Theme Confidence %": theme_confidence
}
)
output_df = pd.DataFrame(results)
positive_pct = round(
(output_df["Sentiment"] == "POSITIVE").mean() * 100,
1
)
summary = (
f"✅ Successfully analyzed {len(output_df)} reviews.\n"
f"Positive Reviews: {positive_pct}%"
)
chart = build_chart(output_df)
return output_df, summary, chart
# ----------------------------
# Gradio UI
# ----------------------------
with gr.Blocks(title="Customer Feedback Analyzer") as app:
gr.Markdown(
"""
# 🧠 AI Customer Feedback Analyzer
Upload an Excel (.xlsx) file containing customer reviews.
The app automatically predicts:
- Sentiment
- Confidence
- Top Theme
- Theme Confidence
"""
)
file_input = gr.File(
label="Upload Excel File (.xlsx)",
file_types=[".xlsx"]
)
analyze_button = gr.Button("Analyze")
summary_output = gr.Textbox(label="Summary")
chart_output = gr.Image(label="Charts")
table_output = gr.Dataframe(label="Analysis Results")
analyze_button.click(
analyze_excel,
inputs=file_input,
outputs=[
table_output,
summary_output,
chart_output
]
)
app.launch()