import streamlit as st
from transformers import pipeline
import nltk
# Download NLTK data for sentence tokenization
nltk.download('punkt_tab')
# Load the Hugging Face pipelines
classifier = pipeline("zero-shot-classification", model="MoritzLaurer/DeBERTa-v3-base-mnli-fever-anli")
sentiment_analyzer = pipeline("sentiment-analysis", model="SarahMakk/CustomModel_amazon_sentiment_moshew_128_10k")
# Define the categories for customer feedback
CATEGORIES = ["Pricing", "Feature", "Customer Service", "Delivery", "Quality"]
# Define the fixed confidence threshold
CONFIDENCE_THRESHOLD = 0.8
# Custom CSS for background colors
st.markdown(
"""
""",
unsafe_allow_html=True
)
# Streamlit app UI
# Title with icon
st.markdown(
"""
📢 Customer Feedback Categorization with Sentiment Analysis
""",
unsafe_allow_html=True
)
# Description with background color
st.markdown(
"""
This app uses Hugging Face models to detect the topics and intent of customer feedback
and determine the sentiment (positive👍 or negative👎) for each relevant category.
A single feedback may belong to multiple categories, such as Pricing, Feature, and Customer Service.
""",
unsafe_allow_html=True
)
# Input text box for customer feedback with background color
feedback_input = st.text_area(
"Enter customer feedback:",
placeholder="Type your feedback here...",
height=200
)
# Classify button
if st.button("Classify Feedback"):
if not feedback_input.strip():
st.error("Please provide valid feedback text.")
else:
# Split the feedback into sentences
sentences = nltk.sent_tokenize(feedback_input)
if not sentences:
st.error("Could not split feedback into sentences.")
st.stop()
# Dictionary to store results for each category
category_results = {category: [] for category in CATEGORIES}
# Process each sentence
for sentence in sentences:
# Perform zero-shot classification on the sentence
classification_result = classifier(sentence, CATEGORIES, multi_label=True)
# Get categories with scores above the threshold
for label, score in zip(classification_result["labels"], classification_result["scores"]):
if score >= CONFIDENCE_THRESHOLD:
# Perform sentiment analysis on the sentence
sentiment_result = sentiment_analyzer(sentence)
raw_label = sentiment_result[0]["label"]
sentiment_score = round(sentiment_result[0]["score"], 4)
# Map the raw label to NEGATIVE or POSITIVE
if raw_label == "LABEL_0":
sentiment_label = "NEGATIVE"
sentiment_icon = "👎" # Thumbs-down icon for negative
sentiment_color = "red" # Red color for negative
elif raw_label == "LABEL_1":
sentiment_label = "POSITIVE"
sentiment_icon = "👍" # Thumbs-up icon for positive
sentiment_color = "green" # Green color for positive
else:
sentiment_label = raw_label # Fallback in case of unexpected label
# Store the result for the category
category_results[label].append({
"sentence": sentence,
"confidence": round(score, 4),
"sentiment": sentiment_label,
"sentiment_score": sentiment_score,
"sentiment_icon": sentiment_icon,
"sentiment_color": sentiment_color
})
# Check if there are any relevant categories
st.subheader("Categorized Feedback with Sentiment Analysis")
found_categories = False
for i, (category, results) in enumerate(category_results.items()):
if results: # If the category has any sentences
found_categories = True
st.write(f"### **{category}**")
for result in results:
st.write(f"- **Sentence**: {result['sentence']}")
st.write(f" - Confidence: {result['confidence']}")
# Use st.markdown with HTML to display the sentiment with icon and color
st.markdown(
f" - Sentiment: {result['sentiment_icon']} "
f"{result['sentiment']} "
f"(Score: {result['sentiment_score']})",
unsafe_allow_html=True
)
# Add a horizontal divider after each category (except the last one)
if i < len(category_results) - 1 and any(category_results[cat] for cat in list(category_results.keys())[i+1:]):
st.markdown("---") # Horizontal line to separate categories
if not found_categories:
st.warning("No categories met the confidence threshold of 0.8.")