Ahmad-01's picture
Update app.py
1cf9263 verified
import pandas as pd
import gradio as gr
import re
from sentence_transformers import SentenceTransformer
from sklearn.neighbors import NearestNeighbors
# -------------------------------
# Load dataset
# -------------------------------
df = pd.read_csv("food_order_cleaned.csv")
df['rating'] = pd.to_numeric(df['rating'], errors='coerce')
df['search_text'] = (
df['restaurant_name'].astype(str) +
" | " + df['cuisine_type'].astype(str) +
" | " + df['rating'].astype(str)
)
# -------------------------------
# Rule-based functions
# -------------------------------
def find_by_cuisine(cuisine, limit=10):
mask = df['cuisine_type'].str.strip().str.lower() == cuisine.strip().lower()
cols = ['restaurant_name','cuisine_type','cost_of_the_order','rating']
return df.loc[mask, cols].head(limit)
def best_rated_by_cuisine(cuisine, top_n=10):
mask = df['cuisine_type'].str.strip().str.lower() == cuisine.strip().lower()
subset = df[mask].dropna(subset=['rating']).sort_values('rating', ascending=False)
cols = ['restaurant_name','cuisine_type','cost_of_the_order','rating']
return subset[cols].head(top_n)
def cheapest_high_rated(max_cost=None, min_rating=4.0, top_n=10):
subset = df.dropna(subset=['rating'])
subset = subset[subset['rating'] >= min_rating]
if max_cost:
subset = subset[subset['cost_of_the_order'] <= max_cost]
subset = subset.sort_values('cost_of_the_order')
cols = ['restaurant_name','cuisine_type','cost_of_the_order','rating']
return subset[cols].head(top_n)
def personalized_recall(customer_id, day):
mask = (
df['customer_id'].astype(str) == str(customer_id)
) & (
df['day_of_the_week'].str.lower() == day.lower()
)
cols = ['order_id','restaurant_name','cuisine_type','cost_of_the_order','rating','day_of_the_week']
return df.loc[mask, cols]
# -------------------------------
# Semantic Search
# -------------------------------
model = SentenceTransformer("all-MiniLM-L6-v2")
corpus_embeddings = model.encode(df["search_text"].tolist(), show_progress_bar=True)
nn = NearestNeighbors(n_neighbors=10, metric="cosine").fit(corpus_embeddings)
def semantic_search(query, k=5):
q_emb = model.encode([query])
dists, idxs = nn.kneighbors(q_emb, n_neighbors=k)
results = df.iloc[idxs[0]].copy()
results["score"] = 1 - dists[0]
cols = ['restaurant_name','cuisine_type','cost_of_the_order','rating','score']
return results[cols]
# -------------------------------
# Query Router
# -------------------------------
def handle_query(message, customer_id=""):
text = message.lower()
# 1. cuisine search
if "find" in text and "restaurant" in text:
for cuisine in df["cuisine_type"].str.lower().unique():
if cuisine in text:
return find_by_cuisine(cuisine).to_html(index=False)
return semantic_search(message).to_html(index=False)
# 2. best-rated query
if "best" in text:
for cuisine in df["cuisine_type"].str.lower().unique():
if cuisine in text:
return best_rated_by_cuisine(cuisine).to_html(index=False)
return semantic_search(message).to_html(index=False)
# 3. cheap places
if "cheap" in text or "value" in text:
return cheapest_high_rated().to_html(index=False)
# 4. personalized recall
if "what did i order" in text:
m = re.search(r"on (\w+)", text)
if not customer_id:
return "Please enter customer_id."
if not m:
return "Please specify the day (e.g., Tuesday)"
day = m.group(1)
r = personalized_recall(customer_id, day)
if r.empty:
return "No matching records."
return r.to_html(index=False)
return semantic_search(message).to_html(index=False)
# -------------------------------
# CHATBOT FUNCTION (DICTIONARY FORMAT)
# -------------------------------
def chatbot_fn(history, message, customer_id):
reply_html = handle_query(message, customer_id)
# append user message
history.append({"role": "user", "content": message})
# append assistant message
history.append({"role": "assistant", "content": "Here are the results 👇"})
return history, "", reply_html
# -------------------------------
# INTERFACE
# -------------------------------
with gr.Blocks() as demo:
gr.Markdown("## 🍽️ Restaurant Guide Chatbot")
chat = gr.Chatbot(label="Chat History") # no type arg
html_out = gr.HTML(label="Search Results")
with gr.Row():
msg = gr.Textbox(placeholder="Ask me anything…")
cid = gr.Textbox(label="Customer ID (optional)")
btn = gr.Button("Send")
btn.click(
chatbot_fn,
inputs=[chat, msg, cid],
outputs=[chat, msg, html_out]
)
demo.launch()