File size: 3,617 Bytes
4db667a
f1735e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4db667a
f1735e2
 
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
import streamlit as st
import pandas as pd
import numpy as np
import joblib
import xgboost as xgb

st.set_page_config(
    page_title="Customer Satisfaction Prediction",
    page_icon="👤",
    layout="centered")

st.title("👤 Customer Satisfaction Prediction")
st.markdown("""
Enter the key financial details below to predict if a specific customer will be **Satisfied** or **Unsatisfied**.
*Note: Only the top influential features are shown for manual input. Others are set to default values.*
""")

# Model
@st.cache_resource
def load_model():
    try:
        model = joblib.load('src/xgb_model.pkl')
        return model
    except FileNotFoundError:
        st.error("Model file (xgb_model.pkl) not found.")
        return None

model = load_model()

# Features
if model:
    booster = model.get_booster()
    all_features = booster.feature_names
    
    importance_map = booster.get_score(importance_type='gain')
    sorted_features = sorted(importance_map.items(), key=lambda x: x[1], reverse=True)
    top_feature_names = [f[0] for f in sorted_features[:10]] # Top 10 features
    
    if 'var15' not in top_feature_names and 'var15' in all_features:
        top_feature_names.insert(0, 'var15')

# User Input 

st.sidebar.header("Customer Profile")
st.sidebar.write("Adjust the values below:")

user_inputs = {}

if model:
    for col in top_feature_names:
        label = col
        default_val = 0.0
        min_val = 0.0
        max_val = 1000000.0
        step = 1.0
        
        if col == 'var15':
            label = "Customer Age"
            default_val = 23.0
            min_val = 5.0
            max_val = 105.0
        elif col == 'saldo_var30':
            label = "Account Balance"
            default_val = 0.0
        elif col == 'var38':
            label = "Mortgage Value"
            default_val = 117310.97 
        
        val = st.sidebar.number_input(
            label=label,
            min_value=float(min_val) if col == 'var15' else None,
            value=float(default_val),
            step=step)
        user_inputs[col] = val

# Prediction 

col1, col2 = st.columns([1, 2])

with col1:
    st.image("https://cdn-icons-png.flaticon.com/512/1077/1077114.png", width=150)

with col2:
    st.subheader("Predict")
    predict_btn = st.button("Calculate Satisfaction Score", type="primary")

if predict_btn and model:
    input_data = {feature: 0 for feature in all_features}
    
    for key, value in user_inputs.items():
        if key in input_data:
            input_data[key] = value
            
    if 'var3' in input_data and 'var3' not in user_inputs:
        input_data['var3'] = 2
            
    df_single = pd.DataFrame([input_data])
    
    df_single = df_single[all_features]
    
    with st.spinner("Analyzing customer profile..."):
        prob = model.predict_proba(df_single)[:, 1][0]
        prediction = (prob > 0.5).astype(int)
        
    st.divider()
    
    col_res1, col_res2 = st.columns(2)
    
    col_res1.metric(
        label="Unhappiness Probability", 
        value=f"{prob:.2%}",
        delta="High Risk" if prob > 0.5 else "Low Risk",
        delta_color="inverse")
    
    if prediction == 0:
        col_res2.success("✅ Prediction: **SATISFIED** (Happy)")
        st.balloons()
    else:
        col_res2.error("⚠️ Prediction: **UNSATISFIED** (Unhappy)")
        st.warning("This customer is at high risk of churning or filing a complaint.")

    with st.expander("See raw input data used for model"):
        st.write(df_single)

elif not model:
    st.warning("Please upload the 'xgb_model.pkl' file to the Space.")