Spaces:
Runtime error
Runtime error
File size: 7,174 Bytes
e079e4a 9d2e560 e079e4a 96a4474 00ee6a6 e079e4a 9d2e560 e079e4a 9d2e560 e079e4a 9ff8060 e079e4a 00ee6a6 e079e4a 00ee6a6 e079e4a 9d2e560 e079e4a 00ee6a6 e079e4a 9ff8060 e079e4a 9d2e560 e079e4a 9d2e560 e079e4a 9ff8060 e079e4a b0434f5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
import gradio as gr
import pandas as pd
import numpy as np
import pickle
from haversine import haversine, Unit
from sklearn.preprocessing import LabelEncoder
import matplotlib.pyplot as plt
import os
# --- Function to load data and model (cached for performance) ---
def load_data_and_model():
"""Loads all necessary data files and the trained model."""
try:
vendors = pd.read_csv('vendors.csv')
train_customers = pd.read_csv('train_customers.csv')
train_locations = pd.read_csv('train_locations.csv')
# --- FIX: Robustly convert 'id' column to string to avoid ValueError ---
# First, try to convert to numeric, coercing errors to NaN
vendors['id'] = pd.to_numeric(vendors['id'], errors='coerce')
# Fill any NaNs that were created with a placeholder (e.g., -1)
vendors['id'] = vendors['id'].fillna(-1)
# Finally, convert the entire column to string
vendors['id'] = vendors['id'].astype(str)
with open('restaurant_recommender_model.pkl', 'rb') as f:
model = pickle.load(f)
le = LabelEncoder()
vendors['vendor_category_en'] = vendors['vendor_category_en'].fillna('Unknown')
vendors['vendor_category_encoded'] = le.fit_transform(vendors['vendor_category_en'])
train_customers['dob'] = pd.to_datetime(train_customers['dob'], errors='coerce')
train_customers['age'] = (pd.to_datetime('now', utc=True) - train_customers['dob'].dt.tz_localize('UTC')).dt.days / 365.25
train_customers['age'] = train_customers['age'].fillna(train_customers['age'].median())
return vendors, train_customers, train_locations, model
except FileNotFoundError as e:
gr.Warning(f"File not found: {e}. Please ensure all data files and the model file are in the same directory.")
return None, None, None, e
# Load data and model once
vendors, customers, locations, model = load_data_and_model()
if vendors is None:
raise FileNotFoundError("Application cannot start. Required files are missing.")
# --- Core Function for What-If Analysis ---
def run_what_if_analysis(selected_vendor_id):
"""
Simulates a hypothetical change and returns the baseline and new scores,
along with a plot for visualization.
"""
random_customer_loc = locations.sample(1).iloc[0]
random_customer = customers[customers['CID'] == random_customer_loc['CID']].iloc[0]
selected_vendor = vendors[vendors['id'] == str(selected_vendor_id)].iloc[0]
cust_loc = (random_customer_loc['latitude'], random_customer_loc['longitude'])
vendor_loc = (selected_vendor['latitude'], selected_vendor['longitude'])
distance_km = haversine(cust_loc, vendor_loc, unit=Unit.KILOMETERS)
base_features = [
distance_km,
selected_vendor['vendor_category_encoded'],
random_customer['age']
]
base_score = model.predict_proba([base_features])[:, 1][0]
hypo_score = base_score
fig, ax = plt.subplots(facecolor='#FFFFFF')
scores = [base_score, hypo_score]
labels = ['Current', 'Hypothetical']
ax.bar(labels, scores, color=['#7FD2C8', '#FF9F9F'])
ax.set_ylim(0, 1)
ax.set_title("Recommendation Score Comparison")
ax.set_ylabel("Predicted Score")
return f"{base_score:.4f}", f"{hypo_score:.4f}", fig
# --- Core Function for New Location Analysis ---
def run_new_location_analysis(selected_vendor_id, new_cust_lat, new_cust_lon):
"""
Simulates a new customer location and returns the predicted score and distance.
"""
random_customer = customers.sample(1).iloc[0]
selected_vendor = vendors[vendors['id'] == str(selected_vendor_id)].iloc[0]
cust_loc = (new_cust_lat, new_cust_lon)
vendor_loc = (selected_vendor['latitude'], selected_vendor['longitude'])
new_distance_km = haversine(cust_loc, vendor_loc, unit=Unit.KILOMETERS)
new_loc_features = [
new_distance_km,
selected_vendor['vendor_category_encoded'],
random_customer['age']
]
new_loc_score = model.predict_proba([new_loc_features])[:, 1][0]
return f"Distance to new location: {new_distance_km:.2f} km", f"Predicted Score: {new_loc_score:.4f}"
# --- Gradio UI with a Creative Theme ---
css = """
h1 {
text-align: center;
font-family: 'Arial', sans-serif;
color: #333;
}
.gr-box {
border-color: #7FD2C8 !important;
}
"""
with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
gr.HTML("<h1 style='color: #FF6347;'>🍔 Foodie's Forecast: A/B Test Simulator</h1>")
gr.Markdown("""
Welcome, restaurant owner! This tool helps you understand how small changes to your profile can impact your visibility and potential for new orders. Use the sections below to run your own experiments.
""")
with gr.Row():
with gr.Column(scale=1):
vendor_dropdown = gr.Dropdown(vendors['id'].unique(), label="Select Your Restaurant ID", info="Choose your restaurant from the list.")
with gr.Column(scale=2):
gr.Image("https://i.imgur.com/5SgBv1S.png", container=False)
gr.Markdown("---")
with gr.Tab("What-If Analysis: Adjust Your Profile"):
gr.Markdown("### Simulate changes to your restaurant's details and see the predicted impact on your recommendation score.")
with gr.Row():
rating_slider = gr.Slider(0, 5, value=4.0, step=0.1, label="Vendor Rating", info="What if your rating increased or decreased?", interactive=False)
delivery_charge_slider = gr.Slider(0, 20, value=5, step=1, label="Delivery Charge ($)", info="How does a price change affect your visibility?", interactive=False)
with gr.Row():
btn_what_if = gr.Button("Run What-If Analysis", variant="primary")
with gr.Row():
output_current = gr.Textbox(label="Current Predicted Score")
output_hypo = gr.Textbox(label="Hypothetical Predicted Score")
gr.Plot(label="Score Comparison", elem_id="plot_what_if")
btn_what_if.click(
fn=run_what_if_analysis,
inputs=[vendor_dropdown],
outputs=[output_current, output_hypo, gr.Plot(label="Score Comparison")]
)
with gr.Tab("New Customer Location Analysis"):
gr.Markdown("### What would happen if a new customer moved to a different area?")
with gr.Row():
lat_input = gr.Number(label="New Customer Latitude", value=30.0)
lon_input = gr.Number(label="New Customer Longitude", value=31.0)
with gr.Row():
btn_new_loc = gr.Button("Analyze New Location", variant="secondary")
with gr.Row():
output_distance = gr.Textbox(label="Distance to Restaurant")
output_new_score = gr.Textbox(label="Predicted Score for New Location")
btn_new_loc.click(
fn=run_new_location_analysis,
inputs=[vendor_dropdown, lat_input, lon_input],
outputs=[output_distance, output_new_score]
)
# Launch the app
demo.launch(share=True) |