Kalsang1's picture
Update app.py
fff1638 verified
import pickle
import pandas as pd
import shap
import gradio as gr
import matplotlib.pyplot as plt
# Load model + SHAP
model = pickle.load(open("salar_xgb_team.pkl", "rb"))
explainer = shap.Explainer(model)
# Education map
education_map = {
"Preschool": 1, "1st-4th": 2, "5th-6th": 3, "7th-8th": 4, "9th": 5,
"10th": 6, "11th": 7, "12th": 8, "HS-grad": 9, "Some-college": 10,
"Assoc-voc": 11, "Assoc-acdm": 12, "Bachelors": 13, "Masters": 14,
"Prof-school": 15, "Doctorate": 16
}
def predict_user_profile(age, education_label, sex, capital_gain, capital_loss, hours_per_week):
education_num = education_map.get(education_label, 9)
sex_binary = 0 if sex == "Male" else 1
df = pd.DataFrame([{
"age": age,
"education-num": education_num,
"sex": sex_binary,
"capital-gain": capital_gain,
"capital-loss": capital_loss,
"hours-per-week": hours_per_week
}])
prob = model.predict_proba(df)[0]
shap_values = explainer(df)
predicted_class = int(prob[1] > 0.5)
confidence = prob[1] if predicted_class else prob[0]
# Confidence bar
level = int(confidence * 10)
bar = "๐ŸŸฉ" * level + "โฌœ" * (10 - level)
# Short user story
story = (
f"๐Ÿ“˜ **Meet your profile**: A {age}-year-old {'woman' if sex_binary else 'man'} "
f"with {education_label} education, working {hours_per_week} hrs/week "
f"and reporting gains/losses of ${capital_gain}/{capital_loss}."
)
# Insight summary
result = f"๐Ÿ”ฎ **Prediction**: {'> $50K' if predicted_class else 'โ‰ค $50K'}\n"
result += f"๐Ÿ“Š **Confidence**: {confidence:.2%}\n\n"
result += f"{bar} Confidence Meter\n\n"
result += f"{story}"
# Explanation from SHAP
sorted_features = sorted(zip(df.columns, shap_values.values[0]), key=lambda x: abs(x[1]), reverse=True)
top_feature = sorted_features[0][0].replace('-', ' ').capitalize()
direction = "increased" if sorted_features[0][1] > 0 else "reduced"
meaning = f"๐Ÿ’ก *Your {top_feature} likely {direction} your predicted income.*"
# Optional: add a tip
tip = (
"๐Ÿ’ฌ Tip: Consider exploring upskilling programs for higher income opportunities!" if predicted_class == 0
else "๐Ÿ’ฌ Tip: Keep optimizing your time and gain strategy for even higher returns!"
)
# SHAP plot
plt.figure(figsize=(6, 3))
shap.plots.bar(shap_values[0], max_display=6, show=False)
plt.tight_layout()
fig = plt.gcf()
plt.close()
return {"โ‰ค $50K": round(prob[0], 2), "> $50K": round(prob[1], 2)}, fig, f"{result}\n\n{meaning}\n\n{tip}"
# App layout
with gr.Blocks(title="๐Ÿง  Group 5 | Income Story Predictor") as demo:
gr.Markdown("## ๐Ÿง  Group 5 | Income Story Predictor")
gr.Markdown("Welcome to your **Income Story** โ€” enter your details and discover your predicted earnings path, confidence level, and key factors influencing it.")
with gr.Row():
with gr.Column(scale=1):
summary = gr.Textbox(label="Prediction Summary", lines=8, interactive=False)
result_label = gr.Label(label="Class Probabilities")
shap_plot = gr.Plot(label="Key Feature Contributions")
with gr.Column(scale=1):
age = gr.Slider(18, 100, step=1, label="๐ŸŽ‚ Age", value=35)
education_label = gr.Dropdown(list(education_map.keys()), label="๐ŸŽ“ Education Level", value="HS-grad")
sex = gr.Radio(["Male", "Female"], label="๐Ÿง Sex", value="Male")
capital_gain = gr.Number(label="๐Ÿ“ˆ Capital Gain", value=0)
capital_loss = gr.Number(label="๐Ÿ“‰ Capital Loss", value=0)
hours_per_week = gr.Slider(1, 100, step=1, label="โŒ› Hours per Week", value=40)
analyze = gr.Button("โœจ Tell My Income Story")
analyze.click(
fn=predict_user_profile,
inputs=[age, education_label, sex, capital_gain, capital_loss, hours_per_week],
outputs=[result_label, shap_plot, summary]
)
gr.Markdown("---")
gr.Markdown("Group 5 :)")
demo.launch()