Spaces:
Build error
Build error
Commit ·
04f7212
1
Parent(s): a78e0bc
Initial commit for loan default prediction app
Browse files- app.py +113 -0
- catboost_model.pkl +3 -0
- requirements.txt +5 -0
app.py
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import numpy as np
|
| 4 |
+
import pickle
|
| 5 |
+
import json
|
| 6 |
+
from sklearn.preprocessing import MinMaxScaler
|
| 7 |
+
|
| 8 |
+
# Load the encoding map
|
| 9 |
+
with open('data/encoding_map.json', 'r') as f:
|
| 10 |
+
encoding_map = json.load(f)
|
| 11 |
+
|
| 12 |
+
# Load the trained meta-model
|
| 13 |
+
with open('models/catboost_model.pkl', 'rb') as f:
|
| 14 |
+
meta_model = pickle.load(f)
|
| 15 |
+
|
| 16 |
+
# Define the expected input features (excluding 'Default')
|
| 17 |
+
expected_features = [
|
| 18 |
+
'Age', 'Income', 'LoanAmount', 'CreditScore', 'MonthsEmployed',
|
| 19 |
+
'NumCreditLines', 'InterestRate', 'LoanTerm', 'DTIRatio',
|
| 20 |
+
'Education_0', 'Education_1', 'Education_2', 'Education_3',
|
| 21 |
+
'EmploymentType_0', 'EmploymentType_1', 'EmploymentType_2', 'EmploymentType_3',
|
| 22 |
+
'MaritalStatus_0', 'MaritalStatus_1', 'MaritalStatus_2',
|
| 23 |
+
'HasMortgage_0', 'HasMortgage_1',
|
| 24 |
+
'HasDependents_0', 'HasDependents_1',
|
| 25 |
+
'LoanPurpose_0', 'LoanPurpose_1', 'LoanPurpose_2', 'LoanPurpose_3', 'LoanPurpose_4',
|
| 26 |
+
'HasCoSigner_0', 'HasCoSigner_1'
|
| 27 |
+
]
|
| 28 |
+
|
| 29 |
+
# Helper function to display a user-friendly dropdown
|
| 30 |
+
def create_input_options(label, key, encoding_map):
|
| 31 |
+
options = {v: k for k, v in encoding_map.items()}
|
| 32 |
+
user_choice = st.selectbox(label, options.keys())
|
| 33 |
+
return int(options[user_choice])
|
| 34 |
+
|
| 35 |
+
# Display the title
|
| 36 |
+
st.title("Loan Default Prediction App")
|
| 37 |
+
|
| 38 |
+
# Create a form for user input
|
| 39 |
+
with st.form("user_input_form"):
|
| 40 |
+
st.header("Please provide the following information:")
|
| 41 |
+
|
| 42 |
+
# Numerical inputs
|
| 43 |
+
age = st.number_input("Age", min_value=18, max_value=100, value=30)
|
| 44 |
+
income = st.number_input("Income (in USD)", min_value=0, value=50000)
|
| 45 |
+
loan_amount = st.number_input("Loan Amount (in USD)", min_value=1000, value=10000)
|
| 46 |
+
credit_score = st.number_input("Credit Score", min_value=300, max_value=850, value=650)
|
| 47 |
+
months_employed = st.number_input("Months Employed", min_value=0, value=12)
|
| 48 |
+
num_credit_lines = st.number_input("Number of Credit Lines", min_value=0, value=5)
|
| 49 |
+
interest_rate = st.number_input("Interest Rate (%)", min_value=0.0, max_value=100.0, value=5.0)
|
| 50 |
+
loan_term = st.number_input("Loan Term (in Months)", min_value=1, max_value=360, value=36)
|
| 51 |
+
dti_ratio = st.number_input("Debt-to-Income Ratio (%)", min_value=0.0, max_value=100.0, value=20.0)
|
| 52 |
+
|
| 53 |
+
# Categorical inputs
|
| 54 |
+
education = create_input_options("Education", "Education", encoding_map['Education'])
|
| 55 |
+
employment_type = create_input_options("Employment Type", "EmploymentType", encoding_map['EmploymentType'])
|
| 56 |
+
marital_status = create_input_options("Marital Status", "MaritalStatus", encoding_map['MaritalStatus'])
|
| 57 |
+
has_mortgage = create_input_options("Has Mortgage", "HasMortgage", encoding_map['HasMortgage'])
|
| 58 |
+
has_dependents = create_input_options("Has Dependents", "HasDependents", encoding_map['HasDependents'])
|
| 59 |
+
loan_purpose = create_input_options("Loan Purpose", "LoanPurpose", encoding_map['LoanPurpose'])
|
| 60 |
+
has_cosigner = create_input_options("Has Co-Signer", "HasCoSigner", encoding_map['HasCoSigner'])
|
| 61 |
+
|
| 62 |
+
# Submit button
|
| 63 |
+
submitted = st.form_submit_button("Submit")
|
| 64 |
+
|
| 65 |
+
# Handle form submission
|
| 66 |
+
if submitted:
|
| 67 |
+
# Create DataFrame for input data
|
| 68 |
+
input_data = pd.DataFrame({
|
| 69 |
+
'Age': [age],
|
| 70 |
+
'Income': [income],
|
| 71 |
+
'LoanAmount': [loan_amount],
|
| 72 |
+
'CreditScore': [credit_score],
|
| 73 |
+
'MonthsEmployed': [months_employed],
|
| 74 |
+
'NumCreditLines': [num_credit_lines],
|
| 75 |
+
'InterestRate': [interest_rate],
|
| 76 |
+
'LoanTerm': [loan_term],
|
| 77 |
+
'DTIRatio': [dti_ratio],
|
| 78 |
+
'Education': [education],
|
| 79 |
+
'EmploymentType': [employment_type],
|
| 80 |
+
'MaritalStatus': [marital_status],
|
| 81 |
+
'HasMortgage': [has_mortgage],
|
| 82 |
+
'HasDependents': [has_dependents],
|
| 83 |
+
'LoanPurpose': [loan_purpose],
|
| 84 |
+
'HasCoSigner': [has_cosigner]
|
| 85 |
+
})
|
| 86 |
+
|
| 87 |
+
# Encode the input data as required by the model
|
| 88 |
+
input_encoded = pd.get_dummies(input_data)
|
| 89 |
+
|
| 90 |
+
# Add missing columns with zeros (as you already do)
|
| 91 |
+
for col in expected_features:
|
| 92 |
+
if col not in input_encoded.columns:
|
| 93 |
+
input_encoded[col] = 0
|
| 94 |
+
|
| 95 |
+
# Handle potential extra features that might have been added during training
|
| 96 |
+
# This can occur if an extra feature was mistakenly included
|
| 97 |
+
input_encoded = input_encoded[expected_features]
|
| 98 |
+
|
| 99 |
+
# Reorder the columns to match the training data
|
| 100 |
+
input_encoded = input_encoded[expected_features]
|
| 101 |
+
|
| 102 |
+
# Scale the input
|
| 103 |
+
scaler = MinMaxScaler()
|
| 104 |
+
input_scaled = scaler.fit_transform(input_encoded)
|
| 105 |
+
|
| 106 |
+
# Make prediction
|
| 107 |
+
prediction = meta_model.predict(input_scaled)[0]
|
| 108 |
+
|
| 109 |
+
# Display the result
|
| 110 |
+
if prediction == 0:
|
| 111 |
+
st.success("Prediction: The applicant is not likely to default on the loan.")
|
| 112 |
+
else:
|
| 113 |
+
st.error("Prediction: The applicant is likely to default on the loan.")
|
catboost_model.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:08d927a9d18fe1a434632b270c284531215c2ba45db90c17b2cd86fe3b0fc7a3
|
| 3 |
+
size 458186
|
requirements.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
streamlit
|
| 2 |
+
catboost
|
| 3 |
+
pandas
|
| 4 |
+
scikit-learn
|
| 5 |
+
pickle
|