Upload 13 files
Browse files- .gitattributes +3 -35
- .gitlab-ci.yml +13 -0
- CREDIT SCORE CARD PRESENTATION.pptx +3 -0
- Credit_Score (2).ipynb +0 -0
- Credit_Score_Classifier.py +130 -0
- Flask-keypair.pem +27 -0
- README.md +89 -0
- app.py +83 -0
- clean_train.csv +0 -0
- credit_classifier.joblib +3 -0
- requirements.txt +5 -0
- score_app.py +24 -0
- train.csv.zip +3 -0
.gitattributes
CHANGED
|
@@ -1,35 +1,3 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 1 |
+
credit_classifier.joblib filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
CREDIT[[:space:]]SCORE[[:space:]]CARD[[:space:]]PRESENTATION.pptx filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
train.csv.zip filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.gitlab-ci.yml
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
stages:
|
| 2 |
+
- deploy
|
| 3 |
+
|
| 4 |
+
deploy_to_streamlit:
|
| 5 |
+
stage: deploy
|
| 6 |
+
script:
|
| 7 |
+
- echo "Deploying to Streamlit..."
|
| 8 |
+
- curl -X POST "https://api.streamlit.io/deploy" \
|
| 9 |
+
-H "Authorization: Bearer $STREAMLIT_API_TOKEN" \
|
| 10 |
+
-H "Content-Type: application/json" \
|
| 11 |
+
-d '{"repository": "https://gitlab.com/rosey-team/credit-score/-/tree/main", "branch": "main"}'
|
| 12 |
+
only:
|
| 13 |
+
- main
|
CREDIT SCORE CARD PRESENTATION.pptx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:861cd7621885df16ea52a7809786001b34fd4e96bb5a68ec16bccf5dddfe9d6f
|
| 3 |
+
size 4090426
|
Credit_Score (2).ipynb
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Credit_Score_Classifier.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""i
|
| 2 |
+
mport streamlit as st
|
| 3 |
+
import pandas as pd
|
| 4 |
+
import numpy as np
|
| 5 |
+
from sklearn.ensemble import RandomForestClassifier
|
| 6 |
+
from sklearn.model_selection import train_test_split
|
| 7 |
+
from joblib import dump, load
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
# Load and process data
|
| 12 |
+
data = pd.read_csv("C:/Users/lenovo/Downloads/Create_score_model/clean_train.csv")
|
| 13 |
+
X = data.drop('Credit_Score', axis=1)
|
| 14 |
+
y = data['Credit_Score']
|
| 15 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
| 16 |
+
|
| 17 |
+
X_train.head()
|
| 18 |
+
|
| 19 |
+
# Train the model
|
| 20 |
+
rf = RandomForestClassifier(random_state=42)
|
| 21 |
+
rf.fit(X_train, y_train)
|
| 22 |
+
|
| 23 |
+
# Save the model
|
| 24 |
+
#dump(rf, 'credit_classifier.joblib', compress=('gzip', 9))
|
| 25 |
+
|
| 26 |
+
# Streamlit App
|
| 27 |
+
# %%writefile scoring_app.py
|
| 28 |
+
loaded_model = load(rf)
|
| 29 |
+
|
| 30 |
+
# Streamlit interface
|
| 31 |
+
st.title("Credit Score Prediction App")
|
| 32 |
+
|
| 33 |
+
# Input fields
|
| 34 |
+
feature1 = st.number_input("Outstanding Debt")
|
| 35 |
+
feature2 = st.number_input("Credit Mix")
|
| 36 |
+
feature3 = st.number_input("Credit History Age (in months)")
|
| 37 |
+
feature4 = st.number_input("Monthly Balance")
|
| 38 |
+
feature5 = st.number_input("Payment Behaviour")
|
| 39 |
+
feature6 = st.number_input("Annual Income")
|
| 40 |
+
feature7 = st.number_input("Number of Delayed Payments")
|
| 41 |
+
|
| 42 |
+
# Define target names
|
| 43 |
+
target_names = {0: "Good", 1: "Poor", 2: "Standard"}
|
| 44 |
+
|
| 45 |
+
if st.button("Predict"):
|
| 46 |
+
prediction = loaded_model.predict([[feature1, feature2, feature3, feature4, feature5, feature6, feature7]])
|
| 47 |
+
st.write(f"Predicted Class: {target_names[prediction[0]]}")
|
| 48 |
+
|
| 49 |
+
"""
|
| 50 |
+
|
| 51 |
+
import streamlit as st
|
| 52 |
+
import pandas as pd
|
| 53 |
+
import numpy as np
|
| 54 |
+
from sklearn.ensemble import RandomForestClassifier
|
| 55 |
+
from sklearn.model_selection import train_test_split
|
| 56 |
+
from joblib import dump, load
|
| 57 |
+
@st.cache_resource
|
| 58 |
+
def load_and_train_model():
|
| 59 |
+
try:
|
| 60 |
+
# Load and process data
|
| 61 |
+
data = pd.read_csv("clean_train.csv")
|
| 62 |
+
except FileNotFoundError:
|
| 63 |
+
st.error("Error: The file 'clean_train.csv' was not found. Please upload the file.")
|
| 64 |
+
st.stop()
|
| 65 |
+
|
| 66 |
+
# Splitting data into features and target
|
| 67 |
+
X = data.drop('Credit_Score', axis=1)
|
| 68 |
+
y = data['Credit_Score']
|
| 69 |
+
|
| 70 |
+
# Train-test split
|
| 71 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
| 72 |
+
|
| 73 |
+
# Train the Random Forest model
|
| 74 |
+
rf = RandomForestClassifier(random_state=42)
|
| 75 |
+
rf.fit(X_train, y_train)
|
| 76 |
+
|
| 77 |
+
# Save the trained model to a file
|
| 78 |
+
dump(rf, 'credit_classifier.joblib')
|
| 79 |
+
return rf
|
| 80 |
+
|
| 81 |
+
@st.cache_resource
|
| 82 |
+
def load_model():
|
| 83 |
+
import os
|
| 84 |
+
if os.path.exists('credit_classifier.joblib'):
|
| 85 |
+
try:
|
| 86 |
+
return load('credit_classifier.joblib')
|
| 87 |
+
except Exception as e:
|
| 88 |
+
st.warning(f"Error loading model: {e}. Retraining the model...")
|
| 89 |
+
return load_and_train_model()
|
| 90 |
+
else:
|
| 91 |
+
st.warning("Model file not found. Training a new model...")
|
| 92 |
+
return load_and_train_model()
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
# Load the trained model
|
| 96 |
+
loaded_model = load_model()
|
| 97 |
+
|
| 98 |
+
# Streamlit App
|
| 99 |
+
st.title("Credit Score Prediction App")
|
| 100 |
+
st.markdown("Predict the credit score category based on user inputs.")
|
| 101 |
+
|
| 102 |
+
# Input fields
|
| 103 |
+
st.sidebar.header("Enter Feature Values:")
|
| 104 |
+
feature1 = st.sidebar.number_input("Outstanding Debt", min_value=0.0, step=100.0)
|
| 105 |
+
feature2 = st.sidebar.selectbox("Credit Mix (0=Bad, 1=Good, 2=Excellent)", [0, 1, 2])
|
| 106 |
+
feature3 = st.sidebar.number_input("Credit History Age (in months)", min_value=0.0, step=1.0)
|
| 107 |
+
feature4 = st.sidebar.number_input("Monthly Balance", min_value=0.0, step=100.0)
|
| 108 |
+
feature5 = st.sidebar.number_input("Payment Behaviour", min_value=0.0, step=1.0)
|
| 109 |
+
feature6 = st.sidebar.number_input("Annual Income", min_value=0.0, step=1000.0)
|
| 110 |
+
feature7 = st.sidebar.number_input("Number of Delayed Payments", min_value=0, step=1)
|
| 111 |
+
|
| 112 |
+
# Define target names
|
| 113 |
+
target_names = {0: "Good", 1: "Poor", 2: "Standard"}
|
| 114 |
+
|
| 115 |
+
# Predict Button
|
| 116 |
+
if st.button("Predict"):
|
| 117 |
+
try:
|
| 118 |
+
# Prepare the input as a 2D array
|
| 119 |
+
inputs = np.array([[feature1, feature2, feature3, feature4, feature5, feature6, feature7]])
|
| 120 |
+
|
| 121 |
+
# Make prediction
|
| 122 |
+
prediction = loaded_model.predict(inputs)
|
| 123 |
+
|
| 124 |
+
# Display result
|
| 125 |
+
st.success(f"Predicted Credit Score: {target_names[prediction[0]]}")
|
| 126 |
+
except Exception as e:
|
| 127 |
+
st.error(f"An error occurred during prediction: {e}")
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
|
Flask-keypair.pem
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-----BEGIN RSA PRIVATE KEY-----
|
| 2 |
+
MIIEpAIBAAKCAQEA1oOm76qQhW3n++IWurUdp1r46/JtIsyyZms6wVHLDPWbAhBe
|
| 3 |
+
FqMIjwEvs2ia3AROIf2RZVFKQUuS5OvC4/J5DfmHWlXmhYNBsLuMgSpRK0F0Utwc
|
| 4 |
+
3Skl7vDNkN+2n111RFzOY3fMvuqh2DR5v29qETa1M/46FvPZ1xc0p36VXQy0MIEA
|
| 5 |
+
QekaD0cU3qWTXRvzdojtXjFLckdSRmcYzgIUG9oRLioJPg3gkz/AdjXG+yh9l5b1
|
| 6 |
+
jdb8XFmlpiFwfBQCog4mIukNegYni7Fnhjh9AmXcHBt/s4NgZrhZKoCoZ6LBZimb
|
| 7 |
+
bx6LGA0y+KcoebpeRqM9GfrjKOy7d4k2lRwu7QIDAQABAoIBAQCnp8uQI1nCvwyB
|
| 8 |
+
w8mJ8UYU57gHCLkdaqi//Wy1bQzquwaETXCL9q4Yvo+eg9IMxVyfmkPJ0QfdEojj
|
| 9 |
+
XBQ8/eR49J5CD0MU9GoiC+MbjIxV51lX7Wqtu5xHLHMtmHtuAKhHXtV7zkT6rf0C
|
| 10 |
+
Mrk40oYun/htg3O5PqryPdPMWNW6G2ZCJZNM9GiEe+6IrrGQqUYaWzYucmHsrzgl
|
| 11 |
+
Nfx9H9hAcCuC0W3buypH9AoaPK62YAGBmW+Yz07sgSSn11KifGBvfL3XLTrSg2lj
|
| 12 |
+
z46oncCqw55MC8dVoFGjlWhm9LZJYmqU7+RCzpEjyv0ZC3g1jBRZWmZGZJcOcdPv
|
| 13 |
+
ACc+QfyNAoGBAPD0f8odH1bJsgshltbn/hmycq0W2IrDI9vHT+R0mLdoXYadxpKA
|
| 14 |
+
619UzVJEgOuEO9It422ZECu2hdRNXGo9TueB0fbotIm1N3/jb45361zyXUJN8J/o
|
| 15 |
+
Eyw2cPp/bGrcRIE3R4OanyAcR1G7nrmJzfxQZaTmvrEumXJ5cjBSgp/zAoGBAOPo
|
| 16 |
+
g8prlJ9Jf5JekK/GokwpMFpKLDbOK4pYnaLHRlwOEn1xyAjAzFSERZGNo8yuKcpE
|
| 17 |
+
aCk4Am/ZMOYWnKN6BoysznpTtE6r/cLVwkIDDw8tTh86MBM91o443rpQWcfaKY64
|
| 18 |
+
GsJERIrVaHa0+dVD4KNT8YSBFsDao49wgzgHFo2fAoGBAKdIZ6uvGkHLl6Mot6sN
|
| 19 |
+
txiqDfljQgTcQ3ni3vFxjVDP0RaTVPgDLuWpXz59Nq/Lxyg9GYbOXC6s8i6ZYs6T
|
| 20 |
+
L8OEGnv7xNNSD2znPly/npSR4vMUXzj1CtKIHVmbu25Y6+p1sV2JrG3DlDQHOMQB
|
| 21 |
+
CxPf0SFx3PPvsTKLZB5uOifHAoGAAgt4Azzr3HIAXwPSMIGLuzszX9wCgYtgAKHC
|
| 22 |
+
6E75ZqIJsG5w6QMx0iBNr3yh15hIb7QlaxlBjFdahPX2+dCCdoimYZqWp44LfNAG
|
| 23 |
+
Kil03SH+7XDMNZ/8aNJBzVIjPBPNA6bLNqr+InC/uzDsfOla/pwmMpYl6h0MEqFj
|
| 24 |
+
zADkRukCgYA9hqWdcfa0x+PKK5Q5t4wdLvwqdHUA/fpk7I5Fk/cBquXmXfeQEzTM
|
| 25 |
+
vYctKyOPAZucG6TDiSTE/g0HSzg/tLFnlRTXduSTq/l07XoPygk0PAPDHqgFqkrc
|
| 26 |
+
7KdrLgXpc9YIzPZ+fEXdZc0rmETasPaFLfepmzGsv/bAPVpCsYjUXQ==
|
| 27 |
+
-----END RSA PRIVATE KEY-----
|
README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# **Credit Scorecard Project**
|
| 2 |
+
|
| 3 |
+
### **Table of Contents**
|
| 4 |
+
1. Project Overview
|
| 5 |
+
2. Features
|
| 6 |
+
3. Technologies Used
|
| 7 |
+
4. Installation
|
| 8 |
+
5. Usage
|
| 9 |
+
6. Data
|
| 10 |
+
7. Model
|
| 11 |
+
8. Evaluation
|
| 12 |
+
9. Future Enhancements
|
| 13 |
+
10. Contributing
|
| 14 |
+
11. Contact
|
| 15 |
+
|
| 16 |
+
### **Project Overview**
|
| 17 |
+
**BUSINESS PROBLEM:**
|
| 18 |
+
|
| 19 |
+
A credit company currently faces a high risk of loan defaults, which directly impacts profitability and increases operational costs associated with debt recovery. Many customers who are approved for credit loans may not have the financial stability or creditworthiness to manage debt effectively, leading to missed payments and default. The company needs a robust way to evaluate applicants’ eligibility for credit loans to reduce the likelihood of default and ensure that only financially responsible customers are approved.
|
| 20 |
+
|
| 21 |
+
**BUSINESS OBJECTIVES:**
|
| 22 |
+
1. Minimize Loan Default Rates: Implement a data-driven model to predict and identify high-risk customers likely to default on loans, thereby reducing the overall loan default rate.
|
| 23 |
+
2. Improve Loan Eligibility Assessment: Develop a systematic method for assessing creditworthiness by using key financial and behavioral indicators (such as outstanding debt, credit history, income level, and payment behavior) to make more accurate loan approval decisions.
|
| 24 |
+
|
| 25 |
+
3. Enhance Profitability through Risk Management: By approving loans primarily for customers with strong credit profiles, the company can decrease losses due to defaults and increase profitability.
|
| 26 |
+
|
| 27 |
+
4. Increase Customer Retention of Low-Risk Borrowers: Retain and attract low-risk customers by offering favorable loan terms to those who demonstrate financial responsibility, thereby improving customer loyalty and satisfaction among reliable borrowers.
|
| 28 |
+
|
| 29 |
+
5. Support Financial Health of Borderline Customers: Provide resources or alternative loan products for borderline customers who are not immediately eligible for standard loans. This could include smaller loans or financial education programs to help these customers improve their creditworthiness, creating a pipeline of future eligible customers.
|
| 30 |
+
|
| 31 |
+
**DATA UNDERSTANDING:**
|
| 32 |
+
1. Identification Columns: ID, Customer_ID: Unique identifiers for records and customers, likely strings.
|
| 33 |
+
|
| 34 |
+
2. Demographic Information: Name, Age, SSN, Occupation: Descriptive attributes about customers. Financial and Credit Attributes:
|
| 35 |
+
|
| 36 |
+
3. Income Inofrmation: Annual_Income, Monthly_Inhand_Salary, Num_Bank_Accounts, Num_Credit_Card: Count of banking products, possibly integers. Interest_Rate, Outstanding_Debt, Credit_Utilization_Ratio: Financial metrics, potentially floats. Num_of_Loan, Type_of_Loan: Loan-related info, with Type_of_Loan listing loan types.
|
| 37 |
+
|
| 38 |
+
4. Behavioral and Payment Information: Delay_from_due_date, Num_of_Delayed_Payment, Changed_Credit_Limit, Num_Credit_Inquiries: Indicators of payment history and credit management. Payment_Behaviour, Payment_of_Min_Amount: Details on payment patterns, possibly strings or categories. Monthly_Balance, Total_EMI_per_month, Amount_invested_monthly: Monthly financial metrics, possibly floats.
|
| 39 |
+
|
| 40 |
+
5. The source of the data is Kaggle through their website https://www.kaggle.com/datasets
|
| 41 |
+
|
| 42 |
+
### **Features**
|
| 43 |
+
1. **Predictive Model**: Uses machine learning to predict credit scores.
|
| 44 |
+
2. **Data Preprocessing**: Includes handling missing data, outliers, and scaling features.
|
| 45 |
+
3. **Model Explainability**: Provides insights into the model's decisions using feature importance.
|
| 46 |
+
4. **Performance Metrics**: Accuracy, Precision, Recall, F1-Score, and AUC-ROC.
|
| 47 |
+
|
| 48 |
+
### **Technologies Used**
|
| 49 |
+
1. Programming Language: Python 3.13
|
| 50 |
+
2. Libraries:
|
| 51 |
+
3. Pandas
|
| 52 |
+
4. NumPy
|
| 53 |
+
5. Scikit-learn
|
| 54 |
+
6. XGBoost
|
| 55 |
+
7. Matplotlib & Seaborn for visualization
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
### **Data**
|
| 59 |
+
The dataset includes anonymized financial information with features like income, credit history, debt, and other personal details.
|
| 60 |
+

|
| 61 |
+
Most of the customers have a standard credit mix. However ~20000 individuals have credit mixes whose information may either be ambiguous,
|
| 62 |
+
inconsistent or not enough data to determine their where thy fall. We keep this in mind.
|
| 63 |
+
|
| 64 |
+

|
| 65 |
+
The customers have an average of 1300 of outstanding debt regardless of occupation.
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
### **Model**
|
| 69 |
+
The model uses [e.g., Logistic Regression, Decision Trees, XGBoost] to predict credit scores. Hyperparameter tuning and cross-validation ensure optimal performance.
|
| 70 |
+
|
| 71 |
+
### **Evaluation**
|
| 72 |
+
The model is evaluated using various performance metrics to ensure its reliability and accuracy. Confusion matrix, ROC curve, and classification reports are generated.
|
| 73 |
+

|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
### **Results:**
|
| 77 |
+

|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
### **Future Enhancements**
|
| 81 |
+
Incorporate more diverse datasets for robustness.
|
| 82 |
+
Implement deep learning models.
|
| 83 |
+
Develop a user-friendly web interface for real-time credit scoring.
|
| 84 |
+
Contributing
|
| 85 |
+
Contributions are welcome! Please fork the repository and submit a pull request.
|
| 86 |
+
|
| 87 |
+
### **Contact**
|
| 88 |
+
For any inquiries, please contact:
|
| 89 |
+
wahomeshiko@gmail.com
|
app.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from flask import Flask, request, render_template
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import numpy as np
|
| 4 |
+
from sklearn.ensemble import RandomForestClassifier
|
| 5 |
+
from sklearn.model_selection import train_test_split
|
| 6 |
+
from joblib import dump, load
|
| 7 |
+
import os
|
| 8 |
+
|
| 9 |
+
# Existing app initialization
|
| 10 |
+
app = Flask(__name__)
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
# Function to load and preprocess the data
|
| 14 |
+
def load_and_train_model():
|
| 15 |
+
# Load and process data
|
| 16 |
+
data = pd.read_csv("clean_train.csv")
|
| 17 |
+
X = data.drop('Credit_Score', axis=1)
|
| 18 |
+
y = data['Credit_Score']
|
| 19 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
| 20 |
+
|
| 21 |
+
# Train the model
|
| 22 |
+
rf = RandomForestClassifier(random_state=42)
|
| 23 |
+
rf.fit(X_train, y_train)
|
| 24 |
+
|
| 25 |
+
# Save the model to a file
|
| 26 |
+
dump(rf, 'credit_classifier.joblib', compress=('gzip', 9))
|
| 27 |
+
return rf
|
| 28 |
+
|
| 29 |
+
# Load the trained model (or train it if necessary)
|
| 30 |
+
def load_model():
|
| 31 |
+
if os.path.exists('credit_classifier.joblib'):
|
| 32 |
+
return load('credit_classifier.joblib')
|
| 33 |
+
else:
|
| 34 |
+
return load_and_train_model()
|
| 35 |
+
|
| 36 |
+
loaded_model = load_model()
|
| 37 |
+
|
| 38 |
+
# Define target names
|
| 39 |
+
target_names = {0: "Good", 1: "Poor", 2: "Standard"}
|
| 40 |
+
|
| 41 |
+
# Flask routes
|
| 42 |
+
@app.route("/")
|
| 43 |
+
def home():
|
| 44 |
+
return render_template("index.html")
|
| 45 |
+
|
| 46 |
+
@app.route('/predict', methods=['POST'])
|
| 47 |
+
def predict():
|
| 48 |
+
try:
|
| 49 |
+
# Extract input values from the form
|
| 50 |
+
outstanding_debt = float(request.form['outstanding_debt'])
|
| 51 |
+
credit_mix = int(request.form['credit_mix'])
|
| 52 |
+
credit_history_age = float(request.form['credit_history_age'])
|
| 53 |
+
monthly_balance = float(request.form['monthly_balance'])
|
| 54 |
+
payment_behaviour = float(request.form['payment_behaviour'])
|
| 55 |
+
annual_income = float(request.form['annual_income'])
|
| 56 |
+
delayed_payments = int(request.form['delayed_payments'])
|
| 57 |
+
|
| 58 |
+
# Prepare input data for prediction
|
| 59 |
+
input_data = [[
|
| 60 |
+
outstanding_debt, credit_mix, credit_history_age,
|
| 61 |
+
monthly_balance, payment_behaviour, annual_income,
|
| 62 |
+
delayed_payments
|
| 63 |
+
]]
|
| 64 |
+
|
| 65 |
+
# Predict using the loaded model
|
| 66 |
+
prediction = loaded_model.predict(input_data)[0] # Use loaded_model here
|
| 67 |
+
|
| 68 |
+
# Map the prediction to the category name
|
| 69 |
+
target_names = {0: "Good", 1: "Poor", 2: "Standard"}
|
| 70 |
+
prediction_text = target_names.get(prediction, "Unknown")
|
| 71 |
+
|
| 72 |
+
# Render result.html with the prediction
|
| 73 |
+
return render_template('result.html', prediction=prediction_text)
|
| 74 |
+
except Exception as e:
|
| 75 |
+
return f"An error occurred: {str(e)}"
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
#if __name__ == "__main__":
|
| 79 |
+
#app.run(debug=True)
|
| 80 |
+
|
| 81 |
+
if __name__ == "__main__":
|
| 82 |
+
app.run(host="0.0.0.0", port=8080)
|
| 83 |
+
|
clean_train.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
credit_classifier.joblib
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c9c5d5fc7bc20dd744e240340ce7d6cf51caf56c4c8db27494d3bce0f83a545d
|
| 3 |
+
size 33489157
|
requirements.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
scikit-learn
|
| 2 |
+
streamlit
|
| 3 |
+
pandas
|
| 4 |
+
joblib
|
| 5 |
+
numpy
|
score_app.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import pickle
|
| 3 |
+
|
| 4 |
+
# Load the model
|
| 5 |
+
with open('credit_model.pkl', 'rb') as f:
|
| 6 |
+
rf = pickle.load(f)
|
| 7 |
+
|
| 8 |
+
# Use 'rf' for predictions in your Streamlit app
|
| 9 |
+
st.title("Credit Score Prediction App")
|
| 10 |
+
|
| 11 |
+
# Input fields
|
| 12 |
+
feature1 = st.number_input("Outstanding_Debt")
|
| 13 |
+
feature2 = st.number_input("Credit_Mix")
|
| 14 |
+
feature3 = st.number_input("Credit_History_Age_in_months")
|
| 15 |
+
feature4 = st.number_input("Monthly_Balance")
|
| 16 |
+
feature5 = st.number_input("Paymnet_Behaviour")
|
| 17 |
+
feature6 = st.number_input("Annual_Income")
|
| 18 |
+
feature7 = st.number_input("Number_of_Delayed_Payment")
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
if st.button("Predict"):
|
| 23 |
+
prediction = rf.predict([[feature1, feature2, feature3, feature4, feature5, feature6, feature7]])
|
| 24 |
+
st.write(f"Predicted Class: {data.target_names[prediction[0]]}")
|
train.csv.zip
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1061b6701bbd529b261fd89fa68fd6cab618b4ba100778c65610ff3b0171fbbe
|
| 3 |
+
size 6382379
|