Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
ADDED
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import joblib
|
4 |
+
import numpy as np
|
5 |
+
import matplotlib.pyplot as plt
|
6 |
+
import seaborn as sns
|
7 |
+
from imblearn.pipeline import Pipeline as imbpipe
|
8 |
+
|
9 |
+
|
10 |
+
|
11 |
+
APP_ICON_URL = "credit-card.png"
|
12 |
+
|
13 |
+
# Setup web page
|
14 |
+
st.set_page_config(
|
15 |
+
page_title="CREDIT CARD APPROVAL APP",
|
16 |
+
page_icon=APP_ICON_URL,
|
17 |
+
layout="wide",
|
18 |
+
)
|
19 |
+
|
20 |
+
st.markdown("""
|
21 |
+
<style type="text/css">
|
22 |
+
blockquote {
|
23 |
+
margin: 1em 0px 1em -1px;
|
24 |
+
padding: 0px 0px 0px 1.2em;
|
25 |
+
font-size: 20px;
|
26 |
+
border-left: 5px solid rgb(230, 234, 241);
|
27 |
+
# background-color: rgb(129, 164, 182);
|
28 |
+
}
|
29 |
+
blockquote p {
|
30 |
+
font-size: 30px;
|
31 |
+
color: #FFFFFF;
|
32 |
+
}
|
33 |
+
[data-testid=stSidebar] {
|
34 |
+
background-color: rgb(129, 164, 182);
|
35 |
+
color: #FFFFFF;
|
36 |
+
}
|
37 |
+
[aria-selected="true"] {
|
38 |
+
color: #000000;
|
39 |
+
}
|
40 |
+
</style>
|
41 |
+
""", unsafe_allow_html=True)
|
42 |
+
with st.container():
|
43 |
+
col1,col2,_,_ = st.columns([1,14,1,1],gap="large")
|
44 |
+
with col1:
|
45 |
+
st.image(APP_ICON_URL, width=80)
|
46 |
+
with col2:
|
47 |
+
st.header(f"Credit Card Prediction App")
|
48 |
+
st.caption(f"App developed by [Alsello](https://github.com/AlselloDM)")
|
49 |
+
st.write(f"This application predicts whether your credit card application is **Approved** or **Not Approved**.")
|
50 |
+
st.markdown("___")
|
51 |
+
|
52 |
+
@st.cache_data
|
53 |
+
def fetch_data():
|
54 |
+
df = pd.read_csv('Application_Data.csv')
|
55 |
+
return df
|
56 |
+
|
57 |
+
df = fetch_data()
|
58 |
+
|
59 |
+
st.sidebar.title("Approval App 📋")
|
60 |
+
st.sidebar.write('Please choose the page')
|
61 |
+
#make two pages for EDA and Prediction
|
62 |
+
page = st.sidebar.selectbox('Choose a page', ['EDA', 'Approval Form📋'])
|
63 |
+
if page == 'EDA':
|
64 |
+
|
65 |
+
st.subheader('Approval Status')
|
66 |
+
st.write('Approval Status is the target variable with value of 0 (not approved) and 1 (approved).')
|
67 |
+
sns.countplot(x='Status', data=df)
|
68 |
+
plt.xticks([0, 1])
|
69 |
+
st.pyplot(plt)
|
70 |
+
st.write('The data is imbalanced.')
|
71 |
+
|
72 |
+
st.subheader('Correlation between Years Employed and Total Income')
|
73 |
+
st.write('Years Employed and Total Income usually has correlation.')
|
74 |
+
plt.figure(figsize=(8, 6))
|
75 |
+
plt.scatter(df['Years_of_Working'], df['Total_Income'], alpha=0.5)
|
76 |
+
plt.xlabel('Years Employed')
|
77 |
+
plt.ylabel('Total Income')
|
78 |
+
plt.title('Correlation between Years Employed and Total Income')
|
79 |
+
st.pyplot(plt)
|
80 |
+
st.write('We can see that the longer the Years Employed, it does not increase the Total Income.')
|
81 |
+
st.write('')
|
82 |
+
|
83 |
+
st.subheader('Correlation of the Features')
|
84 |
+
st.write("One of the many Feature Selection Methods is Pearson's Heatmap Correlation Method.")
|
85 |
+
plt.figure(figsize=(15,15))
|
86 |
+
sns.heatmap(df.corr(), annot=True)
|
87 |
+
plt.show()
|
88 |
+
st.pyplot(plt)
|
89 |
+
st.write("There are no good enough features to choose so I used another method called 'SelectKBest'.")
|
90 |
+
st.write('')
|
91 |
+
|
92 |
+
|
93 |
+
else:
|
94 |
+
st.sidebar.title("Applicant's Profile")
|
95 |
+
st.sidebar.write('Please enter the needed profile here')
|
96 |
+
def user_input_features():
|
97 |
+
# Applicant ID
|
98 |
+
id = st.number_input("ID of the applicant (7 Digits of your ID)")
|
99 |
+
# Male or Female
|
100 |
+
sex = st.selectbox('Gender',('M','F'))
|
101 |
+
# Car Ownership
|
102 |
+
car_ownership = st.selectbox('Car Ownership (1 : Yes | 0 : No)',(1,0))
|
103 |
+
# Property Ownership
|
104 |
+
property_ownership = st.selectbox('Property Ownership (1 : Yes | 0 : No)',(1,0))
|
105 |
+
# Total Children
|
106 |
+
total_children = st.slider('Number of Children?',0,5,0)
|
107 |
+
# Income
|
108 |
+
income = st.number_input('Yearly Income',27000,1575000)
|
109 |
+
# Income Type
|
110 |
+
income_type = st.selectbox("Employment Status",('Working','Commercial associate ','State servant','Pensioner','Student'))
|
111 |
+
# Education Level
|
112 |
+
education = st.selectbox("Education Level",('Lower secondary','Secondary / secondary special','Incomplete higher ','Higher education ','Academic degree'))
|
113 |
+
# Marriage Status
|
114 |
+
marriage_status = st.selectbox("Marriage Status",('Single / not married','Married','Civil marriage','Separated','Widow'))
|
115 |
+
# Residence
|
116 |
+
residence = st.selectbox('Residency',('House / apartment','With parents','Municipal apartment','Rented apartment','Office apartment','Co-op apartment'))
|
117 |
+
# Mobile Phone Ownership
|
118 |
+
mobile_phone = st.selectbox('Mobile Phone Ownership (1 : True | 0 : False)',(1,0))
|
119 |
+
# Work Phone Ownership
|
120 |
+
work_phone = st.selectbox('Work Phone Ownership (1 : True | 0 : False)',(1,0))
|
121 |
+
# Phone Ownership
|
122 |
+
phone = st.selectbox('Phone Ownership (1 : True | 0 : False)',(1,0))
|
123 |
+
# Email Ownership
|
124 |
+
email = st.selectbox('Email Ownership (1 : True | 0 : False)',(1,0))
|
125 |
+
# Job Title
|
126 |
+
job_title = st.selectbox('Job Title',('Laborers','Core staff','Sales staff','Managers','Drivers','High skill tech staff','Accountants','Medicine staff','Cooking staff','Security staff','Cleaning staff','Private service staff','Low-skill Laborers','Waiters/barmen staff','Secretaries','HR staff','Realty agents','IT staff'))
|
127 |
+
# Total Family Member
|
128 |
+
total_family = st.slider('Number of Family Member',1,7,1)
|
129 |
+
# Applicant Age
|
130 |
+
age = st.number_input("Age")
|
131 |
+
# Years of Working
|
132 |
+
years_of_working = st.number_input("Years of Work")
|
133 |
+
# Total Bad Debt
|
134 |
+
total_bad_debt = st.slider('Total of Bad Debt',0,49,0)\
|
135 |
+
# Total Good Debt
|
136 |
+
total_good_debt = st.slider('Total of Good Debt',1,61,1)
|
137 |
+
|
138 |
+
|
139 |
+
|
140 |
+
|
141 |
+
data = {'Applicant_ID': id,'Applicant_Gender':sex,'Owned_Car':car_ownership,
|
142 |
+
'Owned_Realty':property_ownership,'Total_Children':total_children,
|
143 |
+
'Total_Income':income,'Income_Type':income_type,
|
144 |
+
'Education_Type':education,'Family_Status':marriage_status,
|
145 |
+
'Housing_Type':residence,'Owned_Mobile_Phone':mobile_phone,'Owned_Work_Phone':work_phone,
|
146 |
+
'Owned_Phone':phone,'Owned_Email':email,'Job_Title':job_title,'Total_Family_Members':total_family,
|
147 |
+
'Applicant_Age':age,'Years_of_Working':years_of_working,
|
148 |
+
'Total_Bad_Debt':total_bad_debt,'Total_Good_Debt':total_good_debt}
|
149 |
+
#
|
150 |
+
features = pd.DataFrame(data,index=[0])
|
151 |
+
return features
|
152 |
+
|
153 |
+
input_df = user_input_features()
|
154 |
+
|
155 |
+
st.subheader('Applicant Data📋')
|
156 |
+
st.write(input_df)
|
157 |
+
|
158 |
+
load_model = joblib.load("model")
|
159 |
+
|
160 |
+
|
161 |
+
if st.button('Predict'):
|
162 |
+
try:
|
163 |
+
prediction = load_model.predict(input_df)
|
164 |
+
prediction_proba = load_model.predict_proba(input_df)
|
165 |
+
|
166 |
+
st.subheader('APPROVAL')
|
167 |
+
for i in range(len(prediction)):
|
168 |
+
if prediction[i] == 0:
|
169 |
+
st.error("This applicant is not **Approved**")
|
170 |
+
else:
|
171 |
+
st.success("This applicant is **Approved**")
|
172 |
+
|
173 |
+
st.subheader('Probability')
|
174 |
+
st.write("0 : No | 1 : Yes")
|
175 |
+
st.write(prediction_proba)
|
176 |
+
|
177 |
+
except ValueError:
|
178 |
+
st.header("Insufficient Applicant Data")
|