Spaces:
Sleeping
Sleeping
Commit
·
01cc876
1
Parent(s):
236a1fc
Update displayed values
Browse files- app.py +32 -32
- constants.py +5 -9
- requirements.txt +1 -1
app.py
CHANGED
|
@@ -8,7 +8,7 @@ from constants import (
|
|
| 8 |
relationship_dict,
|
| 9 |
occupation_dict,
|
| 10 |
education_dict,
|
| 11 |
-
|
| 12 |
countries_dict,
|
| 13 |
marital_status_dict,
|
| 14 |
)
|
|
@@ -130,30 +130,30 @@ with st.expander("Application form", expanded=False):
|
|
| 130 |
"Native Country", countries_dict.keys(), index=len(countries_dict) - 1
|
| 131 |
)
|
| 132 |
native_country_id = countries_dict[native_country]
|
| 133 |
-
relationship = st.selectbox("
|
| 134 |
relationship_id = relationship_dict[relationship]
|
| 135 |
occupation = st.selectbox("Occupation", occupation_dict.keys(), index=1)
|
| 136 |
occupation_id = occupation_dict[occupation]
|
| 137 |
|
| 138 |
with col2:
|
| 139 |
-
education = st.selectbox("
|
| 140 |
education_id = education_dict[education]
|
| 141 |
-
|
| 142 |
-
|
| 143 |
hours_per_week = st.number_input(
|
| 144 |
-
"
|
| 145 |
)
|
| 146 |
capital_gain = st.number_input(
|
| 147 |
-
"Yearly income
|
| 148 |
)
|
| 149 |
capital_loss = st.number_input(
|
| 150 |
-
"Yearly expenditures
|
| 151 |
)
|
| 152 |
data_df = pd.DataFrame(
|
| 153 |
[
|
| 154 |
[
|
| 155 |
age,
|
| 156 |
-
|
| 157 |
education,
|
| 158 |
marital_status,
|
| 159 |
occupation,
|
|
@@ -166,14 +166,14 @@ with st.expander("Application form", expanded=False):
|
|
| 166 |
],
|
| 167 |
columns=[
|
| 168 |
"Age",
|
| 169 |
-
"
|
| 170 |
-
"
|
| 171 |
"Marital Status",
|
| 172 |
"Occupation",
|
| 173 |
-
"
|
| 174 |
"Yearly Income [€]",
|
| 175 |
"Yearly expenditures [€]",
|
| 176 |
-
"
|
| 177 |
"Native Country",
|
| 178 |
],
|
| 179 |
)
|
|
@@ -182,7 +182,7 @@ with st.expander("Application form", expanded=False):
|
|
| 182 |
"instances": [
|
| 183 |
[
|
| 184 |
age,
|
| 185 |
-
|
| 186 |
education_id,
|
| 187 |
marital_status_id,
|
| 188 |
occupation_id,
|
|
@@ -273,28 +273,25 @@ if st.session_state.selected == "Loan Decision":
|
|
| 273 |
|
| 274 |
# If prediction is positive, first show positive features, then negative features
|
| 275 |
st.success(
|
| 276 |
-
"**Positive
|
| 277 |
+ " \n- ".join(pos_feats)
|
| 278 |
)
|
| 279 |
st.warning(
|
| 280 |
"However, the following features weight ***against*** the loan application: \n - "
|
| 281 |
+ " \n- ".join(neg_feats)
|
| 282 |
-
+ " \n
|
| 283 |
-
icon="⚠️",
|
| 284 |
)
|
| 285 |
else:
|
| 286 |
st.subheader("Loan Decision: :red[NEGATIVE]", divider="red")
|
| 287 |
# If prediction is negative, first show negative features, then positive features
|
| 288 |
st.error(
|
| 289 |
-
"**Negative
|
| 290 |
+ " \n - ".join(neg_feats)
|
| 291 |
-
+ "."
|
| 292 |
)
|
| 293 |
st.warning(
|
| 294 |
"However, the following factors weigh ***in favor*** of the loan applicant: \n - "
|
| 295 |
+ " \n - ".join(pos_feats)
|
| 296 |
-
+ "
|
| 297 |
-
icon="⚠️",
|
| 298 |
)
|
| 299 |
explanation_expander = st.expander("Show explanation")
|
| 300 |
with explanation_expander:
|
|
@@ -340,9 +337,9 @@ if st.session_state.selected == "Loan Decision":
|
|
| 340 |
st.divider()
|
| 341 |
|
| 342 |
# Add prediction evaluation
|
| 343 |
-
st.subheader("
|
| 344 |
st.info(
|
| 345 |
-
"AI model predictions always come with a certain level of uncertainty.
|
| 346 |
)
|
| 347 |
cols = st.columns(4)
|
| 348 |
col_yes, col_no = cols[:2]
|
|
@@ -387,15 +384,18 @@ if st.session_state.selected == "Loan Decision":
|
|
| 387 |
logging.debug(
|
| 388 |
"Selected feedback:" + str(st.session_state.evaluation_input)
|
| 389 |
)
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
|
| 398 |
-
|
|
|
|
|
|
|
|
|
|
| 399 |
if success:
|
| 400 |
st.session_state.eval_selected = False
|
| 401 |
st.success("Feedback submitted successfully.")
|
|
|
|
| 8 |
relationship_dict,
|
| 9 |
occupation_dict,
|
| 10 |
education_dict,
|
| 11 |
+
type_of_work_dict,
|
| 12 |
countries_dict,
|
| 13 |
marital_status_dict,
|
| 14 |
)
|
|
|
|
| 130 |
"Native Country", countries_dict.keys(), index=len(countries_dict) - 1
|
| 131 |
)
|
| 132 |
native_country_id = countries_dict[native_country]
|
| 133 |
+
relationship = st.selectbox("Family situation", relationship_dict.keys())
|
| 134 |
relationship_id = relationship_dict[relationship]
|
| 135 |
occupation = st.selectbox("Occupation", occupation_dict.keys(), index=1)
|
| 136 |
occupation_id = occupation_dict[occupation]
|
| 137 |
|
| 138 |
with col2:
|
| 139 |
+
education = st.selectbox("Highest education level", education_dict.keys(), index=4)
|
| 140 |
education_id = education_dict[education]
|
| 141 |
+
type_of_work = st.selectbox("Type of work", type_of_work_dict.keys())
|
| 142 |
+
type_of_work_id = type_of_work_dict[type_of_work]
|
| 143 |
hours_per_week = st.number_input(
|
| 144 |
+
"Working hours per week", min_value=0, max_value=100, value=40
|
| 145 |
)
|
| 146 |
capital_gain = st.number_input(
|
| 147 |
+
"Yearly income", min_value=0, max_value=1000000, value=70000
|
| 148 |
)
|
| 149 |
capital_loss = st.number_input(
|
| 150 |
+
"Yearly expenditures", min_value=0, max_value=1000000, value=60000
|
| 151 |
)
|
| 152 |
data_df = pd.DataFrame(
|
| 153 |
[
|
| 154 |
[
|
| 155 |
age,
|
| 156 |
+
type_of_work,
|
| 157 |
education,
|
| 158 |
marital_status,
|
| 159 |
occupation,
|
|
|
|
| 166 |
],
|
| 167 |
columns=[
|
| 168 |
"Age",
|
| 169 |
+
"Type of work",
|
| 170 |
+
"Highest education level",
|
| 171 |
"Marital Status",
|
| 172 |
"Occupation",
|
| 173 |
+
"Family situation",
|
| 174 |
"Yearly Income [€]",
|
| 175 |
"Yearly expenditures [€]",
|
| 176 |
+
"Working hours per week",
|
| 177 |
"Native Country",
|
| 178 |
],
|
| 179 |
)
|
|
|
|
| 182 |
"instances": [
|
| 183 |
[
|
| 184 |
age,
|
| 185 |
+
type_of_work_id,
|
| 186 |
education_id,
|
| 187 |
marital_status_id,
|
| 188 |
occupation_id,
|
|
|
|
| 273 |
|
| 274 |
# If prediction is positive, first show positive features, then negative features
|
| 275 |
st.success(
|
| 276 |
+
"**Positive creditworthiness**. This is primarily attributed to: \n - "
|
| 277 |
+ " \n- ".join(pos_feats)
|
| 278 |
)
|
| 279 |
st.warning(
|
| 280 |
"However, the following features weight ***against*** the loan application: \n - "
|
| 281 |
+ " \n- ".join(neg_feats)
|
| 282 |
+
+ " \n For more details, see full explanation of the credit assessment below.",
|
|
|
|
| 283 |
)
|
| 284 |
else:
|
| 285 |
st.subheader("Loan Decision: :red[NEGATIVE]", divider="red")
|
| 286 |
# If prediction is negative, first show negative features, then positive features
|
| 287 |
st.error(
|
| 288 |
+
"**Negative creditworthiness**. This is primarily attributed to: \n - "
|
| 289 |
+ " \n - ".join(neg_feats)
|
|
|
|
| 290 |
)
|
| 291 |
st.warning(
|
| 292 |
"However, the following factors weigh ***in favor*** of the loan applicant: \n - "
|
| 293 |
+ " \n - ".join(pos_feats)
|
| 294 |
+
+ " \n For more details, see full explanation of the credit assessment below.",
|
|
|
|
| 295 |
)
|
| 296 |
explanation_expander = st.expander("Show explanation")
|
| 297 |
with explanation_expander:
|
|
|
|
| 337 |
st.divider()
|
| 338 |
|
| 339 |
# Add prediction evaluation
|
| 340 |
+
st.subheader("Evaluation: Do you agree with the predicted creditworthiness?")
|
| 341 |
st.info(
|
| 342 |
+
"AI model predictions always come with a certain level of uncertainty. \nEvaluate the correctness of the prediction based on your expertise and experience."
|
| 343 |
)
|
| 344 |
cols = st.columns(4)
|
| 345 |
col_yes, col_no = cols[:2]
|
|
|
|
| 384 |
logging.debug(
|
| 385 |
"Selected feedback:" + str(st.session_state.evaluation_input)
|
| 386 |
)
|
| 387 |
+
if st.button("Submit", key="submit_button"):
|
| 388 |
+
# FIXME: Hide comment box after submission
|
| 389 |
+
st.session_state.eval_selected = False
|
| 390 |
+
yes_button = False
|
| 391 |
+
no_button = False
|
| 392 |
+
success = send_evaluation(
|
| 393 |
+
client,
|
| 394 |
+
deployment_id,
|
| 395 |
+
request_log_id,
|
| 396 |
+
prediction_log_id,
|
| 397 |
+
st.session_state.evaluation_input,
|
| 398 |
+
)
|
| 399 |
if success:
|
| 400 |
st.session_state.eval_selected = False
|
| 401 |
st.success("Feedback submitted successfully.")
|
constants.py
CHANGED
|
@@ -44,11 +44,10 @@ countries_dict = {
|
|
| 44 |
|
| 45 |
relationship_dict = {
|
| 46 |
"Unmarried": 5,
|
| 47 |
-
"Not in Family": 3,
|
| 48 |
"Wife": 0,
|
| 49 |
-
"Own child": 1,
|
| 50 |
"Husband": 2,
|
| 51 |
-
"
|
|
|
|
| 52 |
}
|
| 53 |
|
| 54 |
occupation_dict = {
|
|
@@ -87,7 +86,7 @@ education_dict = {
|
|
| 87 |
"Preschool": 15,
|
| 88 |
}
|
| 89 |
|
| 90 |
-
|
| 91 |
"Private": 0,
|
| 92 |
"Self Employed Not Incorporated": 1,
|
| 93 |
"Self Employed Incorporated": 2,
|
|
@@ -99,11 +98,8 @@ workclass_dict = {
|
|
| 99 |
}
|
| 100 |
|
| 101 |
marital_status_dict = {
|
| 102 |
-
"
|
| 103 |
-
"Married
|
| 104 |
"Divorced": 1,
|
| 105 |
-
"Separated": 3,
|
| 106 |
"Widowed": 4,
|
| 107 |
-
"Married-spouse-absent": 5,
|
| 108 |
-
"Married-AF-spouse": 6,
|
| 109 |
}
|
|
|
|
| 44 |
|
| 45 |
relationship_dict = {
|
| 46 |
"Unmarried": 5,
|
|
|
|
| 47 |
"Wife": 0,
|
|
|
|
| 48 |
"Husband": 2,
|
| 49 |
+
"Single parent": 1,
|
| 50 |
+
"Other dependant": 4,
|
| 51 |
}
|
| 52 |
|
| 53 |
occupation_dict = {
|
|
|
|
| 86 |
"Preschool": 15,
|
| 87 |
}
|
| 88 |
|
| 89 |
+
type_of_work_dict = {
|
| 90 |
"Private": 0,
|
| 91 |
"Self Employed Not Incorporated": 1,
|
| 92 |
"Self Employed Incorporated": 2,
|
|
|
|
| 98 |
}
|
| 99 |
|
| 100 |
marital_status_dict = {
|
| 101 |
+
"Single": 2,
|
| 102 |
+
"Married": 0,
|
| 103 |
"Divorced": 1,
|
|
|
|
| 104 |
"Widowed": 4,
|
|
|
|
|
|
|
| 105 |
}
|
requirements.txt
CHANGED
|
@@ -4,7 +4,7 @@ dill==0.3.6
|
|
| 4 |
matplotlib==3.7.0
|
| 5 |
boto3==1.28.0
|
| 6 |
joblib==1.3.2
|
| 7 |
-
streamlit==1.29
|
| 8 |
scipy==1.10.1
|
| 9 |
shap==0.42.0
|
| 10 |
plotly==5.18.0
|
|
|
|
| 4 |
matplotlib==3.7.0
|
| 5 |
boto3==1.28.0
|
| 6 |
joblib==1.3.2
|
| 7 |
+
streamlit==1.29.0
|
| 8 |
scipy==1.10.1
|
| 9 |
shap==0.42.0
|
| 10 |
plotly==5.18.0
|