File size: 5,954 Bytes
313ffa3
a3ffeca
008cbc7
 
bedc31f
d7039db
008cbc7
bedc31f
b39af27
5fcb1c0
313ffa3
 
f7ae4d3
d7039db
9c8d7b2
 
 
 
 
 
 
 
b39af27
 
9c8d7b2
b39af27
9c8d7b2
 
 
 
 
 
 
b39af27
9c8d7b2
 
b39af27
9c8d7b2
 
 
 
 
 
 
 
 
b39af27
9c8d7b2
 
 
b39af27
9c8d7b2
 
 
 
 
 
 
 
 
b39af27
9c8d7b2
 
 
 
cae59a3
 
 
 
 
 
 
 
313ffa3
055398c
 
9c8d7b2
cae59a3
 
 
008cbc7
 
 
9c8d7b2
cae59a3
008cbc7
 
9c8d7b2
008cbc7
b39af27
008cbc7
 
 
b39af27
 
008cbc7
 
 
 
 
 
 
9c8d7b2
 
008cbc7
9c8d7b2
b39af27
9c8d7b2
 
 
 
b39af27
9c8d7b2
 
 
b39af27
9c8d7b2
 
 
b39af27
9c8d7b2
 
 
b39af27
9c8d7b2
 
 
 
 
 
 
b39af27
9c8d7b2
 
 
 
 
 
 
008cbc7
 
 
2be2025
 
008cbc7
9c8d7b2
 
 
 
 
 
d7039db
9c8d7b2
b39af27
9c8d7b2
 
b39af27
 
 
9c8d7b2
 
 
 
 
 
313ffa3
cae59a3
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
import pickle
import xgboost as xgb
import pandas as pd
import shap
import gradio as gr
import numpy as np
import matplotlib.pyplot as plt

# Load the XGBoost model from Pickle
loaded_model = pickle.load(open("h22_xgb_Final(2).pkl", 'rb'))

# Setup SHAP Explainer for XGBoost
explainer = shap.Explainer(loaded_model)

def safe_convert(value, default, min_val, max_val):
    try:
        num = float(value)
        return max(min_val, min(num, max_val))  # Ensure within range
    except (TypeError, ValueError):
        return default  # Use default if conversion fails

# Create the main function for server
def main_func(Department, ChainScale, SupportiveGM, Merit, LearningDevelopment, WorkEnvironment, Engagement, WellBeing):
    
    # ChainScale mapping
    ChainScale_mapping = {
        'Luxury': 1,
        'Upper Midscale': 2,
        'Upper Upscale': 3,
        'Upscale': 4,
        'Independent': 5,
    }
    default_ChainScale = 4  
    ChainScale_value = ChainScale_mapping.get(ChainScale, default_ChainScale)

    # Department mapping
    department_mapping = {
        "Guest Services": 1,
        "Food and Beverage": 2,
        "Housekeeping": 3,
        "Front Office Operations": 4,
        "Guest Activities": 5,
    }
    default_department = 5  
    department_value = department_mapping.get(Department, default_department)

    LearningDevelopment = safe_convert(LearningDevelopment, 3.0, 1, 5)
    SupportiveGM = safe_convert(SupportiveGM, 3.0, 1, 5)
    Merit = safe_convert(Merit, 3.0, 1, 5)
    WorkEnvironment = safe_convert(WorkEnvironment, 3.0, 1, 5)
    Engagement = safe_convert(Engagement, 3.0, 1, 5)
    WellBeing = safe_convert(WellBeing, 3.0, 1, 5)

    new_row = pd.DataFrame({
        'Department': [int(department_value)],  
        'ChainScale': [int(ChainScale_value)],          
        'SupportiveGM': [SupportiveGM],
        'Merit': [Merit],
        'LearningDevelopment': [LearningDevelopment],
        'WorkEnvironment': [WorkEnvironment],
        'Engagement': [Engagement],
        'WellBeing': [WellBeing]
    }).astype(float)

    prob = loaded_model.predict_proba(new_row) 
    
    # Ensure probabilities return correctly
    if prob.shape[1] == 2:
        leave_prob = float(prob[0][0])
        stay_prob = float(prob[0][1])
    else:
        leave_prob = float(prob[0])
        stay_prob = 1 - leave_prob

    shap_values = explainer(new_row)

    fig, ax = plt.subplots(figsize=(8, 4))
    shap.waterfall_plot(shap.Explanation(values=shap_values.values[0],
                                         base_values=shap_values.base_values[0],
                                         data=new_row.iloc[0]))  # Fix waterfall plot
    plt.tight_layout()
    local_plot = plt.gcf()
    plt.close()

    return {"Leave": leave_prob, "Stay": stay_prob}, local_plot

# Create the UI
title = "**Mod 3 Team 5: Employee Turnover Predictor & Interpreter**"
description1 = """
This app predicts whether an employee intends to stay or leave based on satisfaction factors and department.
"""

description2 = """
To use the app, adjust the values of the employee satisfaction factors and click on Analyze.
"""

with gr.Blocks(title=title) as demo:
    gr.Markdown(f"## {title}")
    gr.Markdown(description1)
    gr.Markdown("""---""")
    gr.Markdown(description2)
    gr.Markdown("""---""")
    
    with gr.Row():      
        with gr.Column():
            Department = gr.Radio(
                ["Guest Services", "Food and Beverage", "Housekeeping", "Front Office Operations", "Guest Activities"],
                label="Department", 
                value="Guest Services"
            )
            ChainScale = gr.Dropdown(
                ["Luxury", "Upper Midscale", "Upper Upscale", "Upscale", "Independent"],
                label="ChainScale", 
                value="Upper Upscale"
            )
            SupportiveGM = gr.Slider(
                label="SupportiveGM Score", minimum=1, maximum=5, value=4, step=0.1,
                interactive=True
            )
            Merit = gr.Slider(
                label="Merit Score", minimum=1, maximum=5, value=4, step=0.1,
                interactive=True
            )
            LearningDevelopment = gr.Slider(
                label="Learning and Development Score", minimum=1, maximum=5, value=4, step=0.1,
                interactive=True
            )
            WorkEnvironment = gr.Slider(
                label="Work Environment Score", minimum=1, maximum=5, value=4, step=0.1,
                interactive=True
            )
            Engagement = gr.Slider(
                label="Engagement Score", minimum=1, maximum=5, value=4, step=0.1,
                interactive=True
            )
            WellBeing = gr.Slider(
                label="Well-Being Score", minimum=1, maximum=5, value=4, step=0.1,
                interactive=True
            )
            submit_btn = gr.Button("Analyze")
        
        with gr.Column(visible=True, scale=1, min_width=600) as output_col:
            label = gr.Label(label="Predicted Intent to Stay vs Leave")
            local_plot = gr.Plot(label='SHAP Waterfall Analysis')

    submit_btn.click(
        main_func,
        [Department, ChainScale, SupportiveGM, Merit, LearningDevelopment, WorkEnvironment, Engagement, WellBeing],
        [label, local_plot],
        api_name="Employee_Turnover"
    )
    
    gr.Markdown("### Click on any of the examples below to see how it works:")
    
    gr.Examples(
        [
            ["Guest Services", "Upper Upscale", 2.5, 3.0, 2.8, 3.5, 4.0, 3.5],  
            ["Food and Beverage", "Upper Upscale", 3.5, 4.0, 4.2, 4.5, 4.5, 4.2],  
            ["Housekeeping", "Upper Upscale", 5.0, 4.8, 5.0, 4.7, 5.0, 4.8]  
        ],
        [Department, ChainScale, SupportiveGM, Merit, LearningDevelopment, WorkEnvironment, Engagement, WellBeing],
        [label, local_plot],
        main_func,
        cache_examples=True
    )

demo.launch()