app in progress
Browse files
app.py
CHANGED
@@ -2,52 +2,25 @@ import streamlit as st
|
|
2 |
import pandas as pd
|
3 |
import logging
|
4 |
from deeploy import Client
|
5 |
-
from utils import
|
6 |
-
from utils import
|
|
|
|
|
7 |
|
8 |
logging.basicConfig(level=logging.INFO)
|
9 |
|
10 |
st.set_page_config(layout="wide")
|
11 |
|
12 |
-
|
13 |
-
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
with st.spinner("Submitting response..."):
|
23 |
-
# Call the explain endpoint as it also includes the prediction
|
24 |
-
client.evaluate(deployment_id, request_log_id, prediction_log_id, evaluation_input)
|
25 |
-
return True
|
26 |
-
except Exception as e:
|
27 |
-
logging.error(e)
|
28 |
-
st.error(
|
29 |
-
"Failed to submit feedback."
|
30 |
-
+ "Check whether you are using the right model URL and Token. "
|
31 |
-
+ "Contact Deeploy if the problem persists."
|
32 |
-
)
|
33 |
-
st.write(f"Error message: {e}")
|
34 |
-
|
35 |
-
|
36 |
-
def get_model_url():
|
37 |
-
"""Get model url and retrieve workspace id and deployment id from it"""
|
38 |
-
model_url = st.text_area(
|
39 |
-
"Model URL (default is the demo deployment)",
|
40 |
-
"https://api.app.deeploy.ml/workspaces/708b5808-27af-461a-8ee5-80add68384c7/deployments/1785f8b8-c5a6-4f55-9a83-df8bdb0b9977/",
|
41 |
-
height=125,
|
42 |
-
)
|
43 |
-
elems = model_url.split("/")
|
44 |
-
try:
|
45 |
-
workspace_id = elems[4]
|
46 |
-
deployment_id = elems[6]
|
47 |
-
except IndexError:
|
48 |
-
workspace_id = ""
|
49 |
-
deployment_id = ""
|
50 |
-
return model_url, workspace_id, deployment_id
|
51 |
|
52 |
st.markdown("""
|
53 |
<style>
|
@@ -65,9 +38,16 @@ with st.sidebar:
|
|
65 |
model_url, workspace_id, deployment_id = get_model_url()
|
66 |
deployment_token = st.text_input("Deeploy Model Token", "my-secret-token")
|
67 |
if deployment_token == "my-secret-token":
|
68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
-
# define client
|
71 |
client_options = {
|
72 |
"host": host,
|
73 |
"deployment_token": deployment_token,
|
@@ -75,50 +55,97 @@ with st.sidebar:
|
|
75 |
}
|
76 |
client = Client(**client_options)
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
positive_and_negative_indices = first_five_posneg_indices(response)
|
83 |
-
positive_texts, negative_texts = get_texts(positive_and_negative_indices, feature_texts)
|
84 |
-
positive_vals, negative_vals = get_input_values(positive_and_negative_indices, example_input)
|
85 |
-
|
86 |
-
# Create a function to generate a table
|
87 |
-
def create_table(texts, values, title):
|
88 |
-
# TODO: change color dataframe header -> tried many different options but none worked see below
|
89 |
-
# header_style = '''
|
90 |
-
# <style>
|
91 |
-
# th{
|
92 |
-
# background-color: #00052D;
|
93 |
-
# }
|
94 |
-
# </style>
|
95 |
-
# '''
|
96 |
-
df = pd.DataFrame({"Feature Explanation": texts, 'Value': values})
|
97 |
-
# df = df.style.set_properties(**{
|
98 |
-
# 'selector': 'th',
|
99 |
-
# 'props': [
|
100 |
-
# ('background-color', 'black'),
|
101 |
-
# ('color', 'cyan')]
|
102 |
-
# })
|
103 |
-
# df = df.style.set_properties(**{'background-color': 'black',
|
104 |
-
# 'color': 'green'})
|
105 |
-
|
106 |
-
# headers = {
|
107 |
-
# 'selector': 'th',
|
108 |
-
# 'props': [('background-color', '#67c5a4')]#'background-color: #000066; color: white;'
|
109 |
-
# }
|
110 |
-
# df = df.style.set_table_styles([headers])
|
111 |
-
st.markdown(f'#### {title}') # Markdown for styling
|
112 |
-
st.dataframe(df, hide_index=True) # Display a simple table
|
113 |
-
# st.markdown(header_style, unsafe_allow_html=True)
|
114 |
-
|
115 |
-
# Arrange tables horizontally using Streamlit columns
|
116 |
-
col1, col2 = st.columns(2,gap="small")
|
117 |
-
|
118 |
-
# Display tables in Streamlit columns
|
119 |
-
with col1:
|
120 |
-
create_table(positive_texts, positive_vals, 'Important Suspicious Variables')
|
121 |
-
|
122 |
-
with col2:
|
123 |
-
create_table(negative_texts, negative_vals, 'Important Unsuspicious Variables')
|
124 |
|
|
|
2 |
import pandas as pd
|
3 |
import logging
|
4 |
from deeploy import Client
|
5 |
+
from utils import get_request_body, get_fake_certainty, get_model_url, get_random_suspicious_transaction
|
6 |
+
from utils import get_explainability_texts, get_explainability_values
|
7 |
+
from utils import COL_NAMES, feature_texts
|
8 |
+
from visual_components import create_data_input_table, create_table, ChangeButtonColour
|
9 |
|
10 |
logging.basicConfig(level=logging.INFO)
|
11 |
|
12 |
st.set_page_config(layout="wide")
|
13 |
|
14 |
+
data = pd.read_pickle("data/preprocessed_data.pkl")
|
15 |
+
# data = data.drop('isFraud', axis=1)
|
16 |
|
17 |
+
# Disable the submit button after it is clicked
|
18 |
+
def disable():
|
19 |
+
st.session_state.disabled = True
|
20 |
|
21 |
+
# Initialize disabled for form_submit_button to False
|
22 |
+
if "disabled" not in st.session_state:
|
23 |
+
st.session_state.disabled = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
st.markdown("""
|
26 |
<style>
|
|
|
38 |
model_url, workspace_id, deployment_id = get_model_url()
|
39 |
deployment_token = st.text_input("Deeploy Model Token", "my-secret-token")
|
40 |
if deployment_token == "my-secret-token":
|
41 |
+
st.warning(
|
42 |
+
"Please enter Deeploy API token."
|
43 |
+
)
|
44 |
+
else:
|
45 |
+
st.button("Get suspicious transaction", key="predict_button", help="Click to get a suspicious transaction", use_container_width=True, on_click=disable, disabled=st.session_state.disabled
|
46 |
+
) #on_click=lambda: st.experimental_rerun()
|
47 |
+
ChangeButtonColour("Get suspicious transaction", '#FFFFFF', "#00052D")#'#FFFFFF', "#00052D"
|
48 |
+
|
49 |
|
50 |
+
# define client optsions and instantiate client
|
51 |
client_options = {
|
52 |
"host": host,
|
53 |
"deployment_token": deployment_token,
|
|
|
55 |
}
|
56 |
client = Client(**client_options)
|
57 |
|
58 |
+
# st.text(client_options)
|
59 |
+
# st.text(deployment_id)
|
60 |
+
|
61 |
+
if "predict_button" not in st.session_state:
|
62 |
+
st.session_state.predict_button = False
|
63 |
+
st.title("Money Laundering System")
|
64 |
+
st.divider()
|
65 |
+
st.info(
|
66 |
+
"Fill in left hand side and click on button to observe a potential fraudulent transaction"
|
67 |
+
)
|
68 |
+
if st.session_state.predict_button:
|
69 |
+
try:
|
70 |
+
with st.spinner("Loading..."):
|
71 |
+
datapoint_pd = get_random_suspicious_transaction(data)
|
72 |
+
request_body = get_request_body(datapoint_pd)
|
73 |
+
# Call the explain endpoint as it also includes the prediction
|
74 |
+
exp = client.explain(request_body=request_body, deployment_id=deployment_id)
|
75 |
+
shap_values = exp['explanations'][0]['shap_values']
|
76 |
+
|
77 |
+
|
78 |
+
col1, col2 = st.columns(2)
|
79 |
+
|
80 |
+
with col1:
|
81 |
+
|
82 |
+
create_data_input_table(datapoint_pd, COL_NAMES)
|
83 |
+
with col2:
|
84 |
+
certainty = get_fake_certainty()
|
85 |
+
st.metric(label='#### Model Certainty', value=certainty)
|
86 |
+
|
87 |
+
explainability_texts, sorted_indices = get_explainability_texts(shap_values, feature_texts)
|
88 |
+
explainability_values = get_explainability_values(sorted_indices, datapoint_pd)
|
89 |
+
create_table(explainability_texts, explainability_values, 'Important Suspicious Variables: ')
|
90 |
+
|
91 |
+
|
92 |
+
st.divider()
|
93 |
+
|
94 |
+
|
95 |
+
# Add prediction evaluation
|
96 |
+
st.subheader("Prediction Evaluation")
|
97 |
+
st.write("Do you agree with the prediction?")
|
98 |
+
|
99 |
+
yes_button = st.button("Yes :thumbsup:", key="yes_button")
|
100 |
+
if 'eval_selected' not in st.session_state:
|
101 |
+
st.session_state['eval_selected'] = False
|
102 |
+
if yes_button:
|
103 |
+
st.session_state.eval_selected = True
|
104 |
+
st.session_state.evaluation_input = {
|
105 |
+
"result": 0 # Agree with the prediction
|
106 |
+
}
|
107 |
+
no_button = st.button("No :thumbsdown:", key="no_button")
|
108 |
+
if no_button:
|
109 |
+
st.session_state.eval_selected = True
|
110 |
+
# desired_output = not predictions[0]
|
111 |
+
# st.session_state.evaluation_input = {
|
112 |
+
# "result": 1, # Disagree with the prediction
|
113 |
+
# "value": {"predictions": [desired_output]},
|
114 |
+
# }
|
115 |
+
|
116 |
+
success = False
|
117 |
+
if st.session_state.eval_selected:
|
118 |
+
comment = st.text_input("Would you like to add a comment?")
|
119 |
+
if comment:
|
120 |
+
st.session_state.evaluation_input["explanation"] = comment
|
121 |
+
logging.debug("Selected feedback:" + str(st.session_state.evaluation_input))
|
122 |
+
if st.button("Submit", key="submit_button"):
|
123 |
+
st.session_state.eval_selected = False
|
124 |
+
# success = send_evaluation(client, deployment_id, request_log_id, prediction_log_id, st.session_state.evaluation_input)
|
125 |
+
if success:
|
126 |
+
st.session_state.eval_selected = False
|
127 |
+
st.success("Feedback submitted successfully.")
|
128 |
+
|
129 |
+
|
130 |
+
|
131 |
+
|
132 |
+
|
133 |
+
except Exception as e:
|
134 |
+
logging.error(e)
|
135 |
+
st.error(
|
136 |
+
"Failed to retrieve the prediction or explanation."
|
137 |
+
+ "Check whether you are using the right model URL and Token. "
|
138 |
+
+ "Contact Deeploy if the problem persists."
|
139 |
+
)
|
140 |
+
|
141 |
+
|
142 |
+
|
143 |
+
|
144 |
+
|
145 |
+
st.session_state.successful_call = False
|
146 |
+
|
147 |
+
|
148 |
+
|
149 |
|
150 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
|