Spaces:
Running
on
Zero
Running
on
Zero
import gradio as gr | |
from transformers import pipeline | |
import pandas as pd | |
import spaces | |
# Load dataset | |
from datasets import load_dataset | |
ds = load_dataset('ZennyKenny/demo_customer_nps') | |
df = pd.DataFrame(ds['train']) | |
# Initialize model pipeline | |
from huggingface_hub import login | |
import os | |
# Login using the API key stored as an environment variable | |
hf_api_key = os.getenv("API_KEY") | |
login(token=hf_api_key) | |
classifier = pipeline("text-classification", model="distilbert/distilbert-base-uncased-finetuned-sst-2-english") | |
generator = pipeline("text2text-generation", model="google/flan-t5-base") | |
# Function to classify customer comments | |
def classify_comments(categories): | |
global df # Ensure we're modifying the global DataFrame | |
sentiments = [] | |
assigned_categories = [] | |
for comment in df['customer_comment']: | |
# Classify sentiment | |
sentiment = classifier(comment)[0]['label'] | |
# Generate category | |
category_str = ', '.join(categories) | |
prompt = f"What category best describes this comment? '{comment}' Please answer using only the name of the category: {category_str}." | |
category = generator(prompt, max_length=30)[0]['generated_text'] | |
assigned_categories.append(category) | |
sentiments.append(sentiment) | |
df['comment_sentiment'] = sentiments | |
df['comment_category'] = assigned_categories | |
return df.to_html(index=False) # Return all fields with appended sentiment and category | |
# Function to add a category | |
def add_category(categories, new_category): | |
if new_category.strip() != "" and len(categories) < 5: # Limit to 5 categories | |
categories.append(new_category.strip()) | |
return categories, "", f"**Categories:**\n" + "\n".join([f"- {cat}" for cat in categories]) | |
# Function to reset categories | |
def reset_categories(): | |
return [], "**Categories:**\n- None" | |
# Function to load data from uploaded CSV | |
def load_data(file): | |
global df # Ensure we're modifying the global DataFrame | |
if file is not None: | |
file.seek(0) # Reset file pointer | |
if file.name.endswith('.csv'): | |
custom_df = pd.read_csv(file, encoding='utf-8') | |
else: | |
return "Error: Uploaded file is not a CSV." | |
# Check for required columns | |
required_columns = ['customer_comment'] | |
if not all(col in custom_df.columns for col in required_columns): | |
return f"Error: Uploaded CSV must contain the following column: {', '.join(required_columns)}" | |
df = custom_df | |
return "Custom CSV loaded successfully!" | |
else: | |
return "No file uploaded." | |
# Function to use template categories | |
def use_template(): | |
template_categories = ["Product Experience", "Customer Support", "Price of Service", "Other"] | |
return template_categories, f"**Categories:**\n" + "\n".join([f"- {cat}" for cat in template_categories]) | |
# Gradio Interface | |
with gr.Blocks() as nps: | |
# State to store categories | |
categories = gr.State([]) | |
# App title | |
gr.Markdown("# π Customer Comment Classifier π") | |
# Short explanation | |
gr.Markdown(""" | |
This app classifies customer comments into categories and assigns sentiment labels (Positive/Negative). | |
You can upload your own dataset or use the provided template. The app will append the generated | |
`comment_sentiment` and `comment_category` fields to your dataset. | |
""") | |
# File upload and instructions | |
with gr.Row(): | |
with gr.Column(scale=1): | |
uploaded_file = gr.File(label="π Upload CSV", type="filepath", scale=1) | |
with gr.Column(scale=1): | |
gr.Markdown(""" | |
**π Instructions:** | |
- Upload a CSV file with at least one column: `customer_comment`. | |
- If you don't have your own data, click **Use Template** to load a sample dataset. | |
""") | |
template_btn = gr.Button("β¨ Use Template", size="sm") | |
gr.Markdown("---") | |
# Category section | |
with gr.Row(): | |
with gr.Column(scale=1): | |
# Category input and buttons | |
category_input = gr.Textbox(label="π New Category", placeholder="Enter category name", scale=1) | |
with gr.Row(): | |
add_category_btn = gr.Button("β Add Category", size="sm") | |
reset_btn = gr.Button("π Reset Categories", size="sm") | |
# Category display | |
category_status = gr.Markdown("**π Categories:**\n- None") | |
with gr.Column(scale=1): | |
gr.Markdown(""" | |
**π Instructions:** | |
- Enter a category name and click **Add Category** to add it to the list. | |
- Click **Reset Categories** to clear the list. | |
- The `customer_comment` field will be categorized based on the categories you provide. | |
""") | |
gr.Markdown("---") | |
# Classify button and output | |
with gr.Row(): | |
with gr.Column(scale=1): | |
classify_btn = gr.Button("π Classify", size="sm") | |
with gr.Column(scale=3): # Center the container and make it 75% of the window width | |
output = gr.HTML() | |
# Event handlers | |
add_category_btn.click( | |
fn=add_category, | |
inputs=[categories, category_input], | |
outputs=[categories, category_input, category_status] | |
) | |
reset_btn.click( | |
fn=reset_categories, | |
outputs=[categories, category_status] | |
) | |
uploaded_file.change( | |
fn=load_data, | |
inputs=uploaded_file, | |
outputs=output | |
) | |
template_btn.click( | |
fn=use_template, | |
outputs=[categories, category_status] | |
) | |
classify_btn.click( | |
fn=classify_comments, | |
inputs=categories, | |
outputs=output | |
) | |
nps.launch(share=True) |