TicketMind-AI / app.py
Krishp1's picture
Update app.py
d316796 verified
Raw
History Blame Contribute Delete
5 kB
import torch
import streamlit as st
from transformers import DistilBertTokenizer, DistilBertForSequenceClassification
from datasets import load_dataset
# ── LABELS ─────────────────────────────
@st.cache_resource
def load_labels():
return [
"activate_my_card", "age_limit", "apple_pay_or_google_pay",
"atm_support", "automatic_top_up", "balance_not_updated_after_bank_transfer",
"balance_not_updated_after_cheque_or_cash_deposit", "beneficiary_not_allowed",
"cancel_transfer", "card_about_to_expire", "card_acceptance",
"card_arrival", "card_delivery_estimate", "card_linking",
"card_not_working", "card_payment_fee_charged", "card_payment_not_recognised",
"card_payment_wrong_exchange_rate", "card_swallowed", "cash_withdrawal_charge",
"cash_withdrawal_not_recognised", "change_pin", "compromised_card",
"contactless_not_working", "country_support", "declined_card_payment",
"declined_cash_withdrawal", "declined_transfer", "direct_debit_payment_not_recognised",
"disposable_card_limits", "edit_personal_details", "exchange_charge",
"exchange_rate", "exchange_via_app", "extra_charge_on_statement",
"failed_transfer", "fiat_currency_support", "get_disposable_virtual_card",
"get_physical_card", "getting_spare_card", "getting_virtual_card",
"lost_or_stolen_card", "lost_or_stolen_phone", "order_physical_card",
"passcode_forgotten", "pending_card_payment", "pending_cash_withdrawal",
"pending_top_up", "pending_transfer", "pin_blocked",
"receiving_money", "Refund_not_showing_up", "request_refund",
"reverted_card_payment", "supported_cards_and_currencies", "terminate_account",
"top_up_by_bank_transfer_charge", "top_up_by_card_charge", "top_up_by_cash_or_cheque",
"top_up_failed", "top_up_limits", "top_up_reverted",
"topping_up_by_card", "transaction_charged_twice", "transfer_fee_charged",
"transfer_into_account", "transfer_not_received_by_recipient", "transfer_timing",
"unable_to_verify_identity", "verify_my_identity", "verify_source_of_funds",
"verify_top_up", "virtual_card_not_working", "visa_or_mastercard",
"why_verify_identity", "wrong_amount_of_cash_received", "wrong_exchange_rate_for_cash_withdrawal"
]
# ── MODEL ──────────────────────────────
@st.cache_resource
@st.cache_resource
def load_model():
print("STEP 1: Starting")
tokenizer = DistilBertTokenizer.from_pretrained(
"Krishp1/ticketmind-model",
subfolder="best_model"
)
print("STEP 2: Tokenizer loaded")
model = DistilBertForSequenceClassification.from_pretrained(
"Krishp1/ticketmind-model",
subfolder="best_model"
)
print("STEP 3: Model loaded")
return tokenizer, model
# ── PREDICT ────────────────────────────
def predict(text, tokenizer, model, labels):
inputs = tokenizer(
text,
return_tensors="pt",
max_length=128,
padding="max_length",
truncation=True
)
with torch.no_grad():
outputs = model(**inputs)
logits = outputs.logits
probs = torch.softmax(logits, dim=1)
top5 = torch.topk(probs, 5)
results = []
for score, idx in zip(top5.values[0], top5.indices[0]):
results.append({
"category": labels[idx.item()].replace("_", " ").title(),
"confidence": round(score.item() * 100, 2)
})
return results
# ── UI ─────────────────────────────────
st.set_page_config(
page_title="Support Ticket Classifier",
page_icon="🎫",
layout="centered"
)
st.title("🎫 Customer Support Ticket Classifier")
st.markdown("Powered by fine-tuned DistilBERT on Banking77 dataset")
st.markdown("---")
labels = load_labels()
tokenizer, model = load_model()
ticket = st.text_area(
"Enter your support ticket:",
placeholder="e.g. My payment failed but money was deducted from my account",
height=120
)
if st.button("Classify Ticket", type="primary"):
if ticket.strip():
with st.spinner("Analyzing..."):
results = predict(ticket, tokenizer, model, labels)
st.markdown("### Results:")
top = results[0]
st.success(f"**Primary Category: {top['category']}** ({top['confidence']}% confidence)")
st.markdown("**Top 5 predictions:**")
for r in results:
st.progress(
r["confidence"] / 100,
text=f"{r['category']} β€” {r['confidence']}%"
)
else:
st.warning("Please enter a ticket first.")
st.markdown("---")
st.caption("Fine-tuned DistilBERT | Banking77 | Built for AI Engineer Portfolio")