CoolFace
Apppublic

Tryfonas/Module1_Final_Assignment

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py125 linesDownload Raw Back to root
1import streamlit as st
2import pandas as pd
3import numpy as np
4import joblib
5import shap
6import xgboost as xgb
7
8# Load the saved model and preprocessing objects
9model_xgb = joblib.load('model_xgb.joblib')
10scaler = joblib.load('scaler.joblib')
11ohe = joblib.load('ohe.joblib')
12
13# Extract the unique values for 'country' and 'sector' from the OneHotEncoder (ohe) object
14unique_sectors = ohe.categories_[0]  
15
16# Define a mapping of encoded values to repayment interval labels
17repayment_interval_mapping = {0: '๐Ÿš… Bullet Repayment Interval', 1: '๐Ÿช™ Irregular Repayment Interval', 2: '๐Ÿ“… Monthly Repayment Interval'}
18
19# Title with emojis and colors
20st.markdown("<h1 style='text-align: center; color: blue;'>๐Ÿ“Š Loan Repayment Interval Prediction for Phillipines(๐Ÿ‡ต๐Ÿ‡ญ)๐Ÿ“ˆ</h1>", unsafe_allow_html=True)
21
22# Input Features Section with emojis and description
23st.write("## ๐ŸŽฏ Input Features")
24st.markdown("Please select the variables to predict the repayment interval based on historical data. The model assumes that all loans used for training were successfully repaid. Kindly provide the following information:")
25
26# User input fields using unique country and sector values from the OneHotEncoder object
27sector = st.selectbox('๐Ÿข Sector', unique_sectors)
28funded_amount = st.number_input('๐Ÿ’ฐ Funded Amount', min_value=0, max_value=20000, value=1000, step=50)
29lender_count = st.number_input('๐Ÿ‘ฅ Lender Count', min_value=1, max_value=200, value=2, step=1)
30
31# Create a sample observation from the user input
32sample_listing = pd.DataFrame({
33    'sector': [sector],
34    'funded_amount': [funded_amount],
35    'lender_count': [lender_count],
36})
37
38# Separate categorical and numerical features
39cat_features = ['sector']
40num_features = ['funded_amount', 'lender_count']
41
42# Get the feature names from the OneHotEncoder
43ohe_feature_names = ohe.get_feature_names_out(cat_features)
44
45# Combine numerical feature names with encoded categorical feature names
46feature_names = np.concatenate([num_features, ohe_feature_names])
47
48# One-hot encode categorical features
49X_cat = pd.DataFrame(ohe.transform(sample_listing[cat_features]), columns=ohe_feature_names)
50
51# Scale numerical features
52X_num = pd.DataFrame(scaler.transform(sample_listing[num_features]), columns=num_features)
53
54# Combine processed features
55X_processed = pd.concat([X_num, X_cat], axis=1)
56
57# Make a prediction (returns the encoded value)
58predicted_encoded_repayment_interval = model_xgb.predict(X_processed)[0]
59
60# Map the encoded value back to the actual repayment interval label
61predicted_repayment_interval = repayment_interval_mapping.get(int(predicted_encoded_repayment_interval), "Unknown")
62
63# Display the actual repayment interval label with more style
64st.title("โœ… Predicted Repayment Interval:")
65st.markdown(f"<h2 style='color:green;'>{predicted_repayment_interval}</h2>", unsafe_allow_html=True)
66
67# Explanation for SHAP force plots
68st.write("## ๐Ÿ” SHAP Explanation")
69st.markdown("The following SHAP plot explains the model's decision for the predicted repayment interval. This visualization helps you understand the key features that influenced the model's prediction. The red features push the result higher and the blue ones push it lower.")
70
71# SHAP explanations
72explainer = shap.TreeExplainer(model_xgb)
73shap_values = explainer.shap_values(X_processed)
74
75# Function to add background color to SHAP plots
76def add_background(html_content):
77    white_background_style = "<style>body { background-color: white; }</style>"
78    return white_background_style + html_content
79
80# Generate and display SHAP force plot based on the predicted repayment interval
81if predicted_encoded_repayment_interval == 0:
82    st.write("### ๐Ÿš… SHAP Force Plot for Bullet Repayment Interval")
83    shap_html_path_0 = "shap_force_plot_class_0.html"
84    shap.save_html(shap_html_path_0, shap.force_plot(
85        explainer.expected_value[0],
86        shap_values[0][:, 0],
87        X_processed.iloc[0, :].values,
88        feature_names,
89        show=False,
90        matplotlib=False
91    ))
92    with open(shap_html_path_0, 'r', encoding='utf-8') as f:
93        shap_html_0 = f.read()
94    st.components.v1.html(add_background(shap_html_0), height=130)
95
96elif predicted_encoded_repayment_interval == 1:
97    st.write("### ๐Ÿช™ SHAP Force Plot for Irregular Repayment Interval")
98    shap_html_path_1 = "shap_force_plot_class_1.html"
99    shap.save_html(shap_html_path_1, shap.force_plot(
100        explainer.expected_value[1],
101        shap_values[0][:, 1],
102        X_processed.iloc[0, :].values,
103        feature_names,
104        show=False,
105        matplotlib=False
106    ))
107    with open(shap_html_path_1, 'r', encoding='utf-8') as f:
108        shap_html_1 = f.read()
109    st.components.v1.html(add_background(shap_html_1), height=130)
110
111elif predicted_encoded_repayment_interval == 2:
112    st.write("### ๐Ÿ“… SHAP Force Plot for Monthly Repayment Interval")
113    shap_html_path_2 = "shap_force_plot_class_2.html"
114    shap.save_html(shap_html_path_2, shap.force_plot(
115        explainer.expected_value[2],
116        shap_values[0][:, 2],
117        X_processed.iloc[0, :].values,
118        feature_names,
119        show=False,
120        matplotlib=False
121    ))
122    with open(shap_html_path_2, 'r', encoding='utf-8') as f:
123        shap_html_2 = f.read()
124    st.components.v1.html(add_background(shap_html_2), height=130)
125