MBG0903's picture
Deploy docker Streamlit app
ca5dc6f verified
import os, json, joblib
import pandas as pd
import streamlit as st
from huggingface_hub import hf_hub_download
st.set_page_config(page_title="Wellness Package Predictor", page_icon="๐Ÿ๏ธ", layout="centered")
st.title("๐Ÿ๏ธ Wellness Tourism Package โ€” Purchase Propensity")
def get_secret(name: str, default=None):
try:
return st.secrets[name]
except Exception:
return os.getenv(name, default)
MODEL_REPO = get_secret("MODEL_REPO", "MBG0903/tourism_customer_xgb")
HF_TOKEN = get_secret("HF_TOKEN", None)
@st.cache_resource(show_spinner=True)
def load_artifacts(repo_id: str, token: str | None):
model_path = hf_hub_download(repo_id=repo_id, filename="model.joblib", token=token)
meta_path = hf_hub_download(repo_id=repo_id, filename="metadata.json", token=token)
model = joblib.load(model_path)
with open(meta_path, "r") as f:
meta = json.load(f)
return model, meta
try:
model, meta = load_artifacts(MODEL_REPO, HF_TOKEN)
except Exception as e:
st.error(f"Failed to load model artifacts from {MODEL_REPO}. Details: {e}")
st.stop()
st.caption("Model metrics (from training)")
st.json(meta.get("metrics", {}))
st.sidebar.header("Enter Customer Profile")
def i_num(label, value, minv=None, maxv=None, step=1):
return st.sidebar.number_input(label, value=value, min_value=minv, max_value=maxv, step=step)
inputs = {}
inputs["CustomerID"] = st.sidebar.text_input("CustomerID", "CUST_000001")
inputs["Age"] = i_num("Age", 32, 18, 90)
inputs["TypeofContact"] = st.sidebar.selectbox("TypeofContact", ["Company Invited","Self Inquiry"])
inputs["CityTier"] = st.sidebar.selectbox("CityTier", ["Tier 1","Tier 2","Tier 3"])
inputs["Occupation"] = st.sidebar.selectbox("Occupation", ["Salaried","Freelancer","Self Employed","Student","Retired"])
inputs["Gender"] = st.sidebar.selectbox("Gender", ["Male","Female"])
inputs["NumberOfPersonVisiting"] = i_num("NumberOfPersonVisiting", 2, 1, 10)
inputs["PreferredPropertyStar"] = i_num("PreferredPropertyStar", 4, 1, 5)
inputs["MaritalStatus"] = st.sidebar.selectbox("MaritalStatus", ["Single","Married","Divorced"])
inputs["NumberOfTrips"] = i_num("NumberOfTrips", 3, 0, 50)
inputs["Passport"] = st.sidebar.selectbox("Passport", [0,1])
inputs["OwnCar"] = st.sidebar.selectbox("OwnCar", [0,1])
inputs["NumberOfChildrenVisiting"] = i_num("NumberOfChildrenVisiting", 0, 0, 10)
inputs["Designation"] = st.sidebar.selectbox("Designation", ["Executive","Manager","Senior Manager","AVP","VP","Director"])
inputs["MonthlyIncome"] = i_num("MonthlyIncome", 70000, 0, 1_000_000, 1000)
inputs["PitchSatisfactionScore"] = i_num("PitchSatisfactionScore", 4, 1, 5)
inputs["ProductPitched"] = st.sidebar.selectbox("ProductPitched", ["Basic","Deluxe","Super Deluxe","King","Queen"])
inputs["NumberOfFollowups"] = i_num("NumberOfFollowups", 2, 0, 20)
inputs["DurationOfPitch"] = i_num("DurationOfPitch", 15, 0, 120)
df_in = pd.DataFrame([inputs])
for junk in ["Unnamed: 0", "index"]:
if junk in df_in.columns: df_in = df_in.drop(columns=[junk])
feature_order = meta.get("feature_order")
if feature_order: df_in = df_in[[c for c in feature_order if c in df_in.columns]]
threshold = float(meta.get("threshold", 0.5))
if st.button("Predict"):
try:
proba = float(model.predict_proba(df_in)[:, 1][0])
pred = int(proba >= threshold)
st.metric("Purchase Probability", f"{proba:.3f}")
st.write("Prediction:", "Will Purchase (1)" if pred else "Will Not Purchase (0)")
with st.expander("Input snapshot"): st.dataframe(df_in)
except Exception as e:
st.error(f"Prediction failed: {e}")