File size: 5,274 Bytes
abcbf29
 
92c3071
c0d3dcc
 
 
92c3071
2c11b8e
92c3071
c0d3dcc
 
 
 
2c11b8e
 
 
 
 
 
c0d3dcc
 
9636ff0
c0d3dcc
2c11b8e
 
c0d3dcc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2c11b8e
c0d3dcc
2c11b8e
c0d3dcc
92c3071
 
2c11b8e
 
 
 
 
 
 
 
 
 
 
c0d3dcc
2c11b8e
dc43483
c0d3dcc
dc43483
c0d3dcc
 
 
 
 
 
 
 
 
 
 
 
2c11b8e
c0d3dcc
 
 
 
b386996
 
 
 
 
efa2bec
 
 
 
 
 
2c11b8e
 
c0d3dcc
 
2c11b8e
c0d3dcc
 
9c30190
c0d3dcc
 
 
9636ff0
c0d3dcc
2c11b8e
 
 
c0d3dcc
 
 
2c11b8e
 
 
 
 
c0d3dcc
 
2c11b8e
 
 
c0d3dcc
9636ff0
2c11b8e
 
c0d3dcc
 
 
abcbf29
 
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
import pickle
import pandas as pd
import shap
from shap.plots._force_matplotlib import draw_additive_plot
import gradio as gr
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

# Load model
loaded_model = pickle.load(open("default_xgb.pkl", 'rb'))

# SHAP Explainer
explainer = shap.Explainer(loaded_model)

# Load images for different profiles
img_mary = Image.open("mary_profile.png")
img_james = Image.open("james_profile.png")
img_landon = Image.open("landon_profile.png")

# Define main function
def main_func(LIMIT_BAL,
              PAY_0, PAY_2, PAY_3, PAY_4, PAY_5, PAY_6,
              b1, b2, b3, b4, b5, b6,
              profile=""):

    new_row = pd.DataFrame.from_dict({
        'LIMIT_BAL': [LIMIT_BAL],
        'PAY_0': [PAY_0],
        'PAY_2': [PAY_2],
        'PAY_3': [PAY_3],
        'PAY_4': [PAY_4],
        'PAY_5': [PAY_5],
        'PAY_6': [PAY_6],
        'b1': [b1],
        'b2': [b2],
        'b3': [b3],
        'b4': [b4],
        'b5': [b5],
        'b6': [b6]
    })

    prob = loaded_model.predict_proba(new_row)[0][1]

    shap_values = explainer(new_row)
    plt.figure(figsize=(10, 6))
    shap.plots.bar(shap_values[0], max_display=10, show=False)
    plt.tight_layout()
    local_plot = plt.gcf()
    plt.close()

    # Select image based on profile
    if profile == "Mary":
        image = img_mary
    elif profile == "James":
        image = img_james
    elif profile == "Landon":
        image = img_landon
    else:
        image = None

    return {"No Default": 1 - float(prob), "Default": float(prob)}, local_plot, image

# UI Text
title = "**Credit Card Default Risk Predictor** ๐Ÿ“Š"
description1 = """
This app uses financial data such as credit limits, repayment behavior, and bill balances to estimate the probability that a person may **default on their next credit payment**.
"""
description2 = """
To use the app, either adjust the values or click one of the examples. Then click on **Analyze** to get predictions and interpretations. ๐Ÿ”
"""

# Launch Gradio app
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():
            LIMIT_BAL = gr.Slider(label="Credit Limit (LIMIT_BAL)", minimum=10000, maximum=1000000, value=150000, step=5000)
            PAY_0 = gr.Slider(label="PAY_0 (Most recent payment status)", minimum=-2, maximum=8, value=0, step=1)
            PAY_2 = gr.Slider(label="PAY_2", minimum=-2, maximum=8, value=-1, step=1)
            PAY_3 = gr.Slider(label="PAY_3", minimum=-2, maximum=8, value=-1, step=1)
            PAY_4 = gr.Slider(label="PAY_4", minimum=-2, maximum=8, value=-1, step=1)
            PAY_5 = gr.Slider(label="PAY_5", minimum=-2, maximum=8, value=-1, step=1)
            PAY_6 = gr.Slider(label="PAY_6", minimum=-2, maximum=8, value=-1, step=1)
            b1 = gr.Slider(label="Balance 1 (b1)", minimum=-100000, maximum=100000, value=5000, step=1000)
            b2 = gr.Slider(label="Balance 2 (b2)", minimum=-100000, maximum=100000, value=4500, step=1000)
            b3 = gr.Slider(label="Balance 3 (b3)", minimum=-100000, maximum=100000, value=4700, step=1000)
            b4 = gr.Slider(label="Balance 4 (b4)", minimum=-100000, maximum=100000, value=4300, step=1000)
            b5 = gr.Slider(label="Balance 5 (b5)", minimum=-100000, maximum=100000, value=4000, step=1000)
            b6 = gr.Slider(label="Balance 6 (b6)", minimum=-100000, maximum=100000, value=3900, step=1000)
            profile_input = gr.Textbox(visible=False)

            submit_btn = gr.Button("Analyze")

        with gr.Column(visible=True, scale=1, min_width=600):
            label = gr.Label(label="Predicted Default Risk")
            local_plot = gr.Plot(label="SHAP Explanation Plot")
            profile_image = gr.Image(label="Customer Profile Image", width=400, height=400)

            submit_btn.click(
                main_func,
                [LIMIT_BAL,
                 PAY_0, PAY_2, PAY_3, PAY_4, PAY_5, PAY_6,
                 b1, b2, b3, b4, b5, b6,
                 profile_input],
                [label, local_plot, profile_image],
                api_name="Default_Risk"
            )

    gr.Markdown("""### Example inputs to try: 3 credit profiles
- Mary: Did not miss payments in last 6 months, with a decreasing remaining balance and credit limit = 200,000. 
- James: Constantly missed payments in last 6 months, with an increasing remaining balance and credit limit = 80,000. 
- Landon: Missed payments in early months, with high fluctuations in remaining balance and credit limit = 300,000.
    """)
    gr.Examples(
        examples=[
            [200000, -1, -1, -1, -1, -1, -1, 7500, 10000, 12500, 15000, 17500, 20000, "Mary"],
            [80000, 2, 2, 2, 3, 2, 2, 20000, 17500, 15500, 12500, 10000, 7500, "James"],
            [300000, -1, 1, -1, 1, 2, 2, 15000, 20000, 0, 10000, 25000, 10000, "Landon"]
        ],
        inputs=[LIMIT_BAL, PAY_0, PAY_2, PAY_3, PAY_4, PAY_5, PAY_6,
                b1, b2, b3, b4, b5, b6, profile_input],
        outputs=[label, local_plot, profile_image],
        fn=main_func,
        cache_examples=True
    )

demo.launch()