File size: 7,519 Bytes
1794e4f c8a77b2 5810688 c8a77b2 3c5e633 c8a77b2 1794e4f c8a77b2 1794e4f c8a77b2 2187b60 3c5e633 2187b60 3c5e633 c8a77b2 2187b60 c8a77b2 f1bd5a3 2187b60 c8a77b2 2187b60 c8a77b2 5810688 3c5e633 5810688 c8a77b2 5810688 c8a77b2 2187b60 32a7408 2187b60 32a7408 2187b60 3c5e633 2187b60 3c5e633 2187b60 3c5e633 2187b60 3c5e633 2187b60 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
import streamlit.components.v1 as components
import streamlit as st
from random import randrange, uniform
import pandas as pd
import logging
import numpy as np
COL_NAMES = ['Time step',
'Transaction type',
'Amount transferred',
'Sender\'s initial balance',
'Sender\'s new balance',
'Recipient\'s initial balance',
'Recipient\'s new balance',
"Sender exactly credited",
"Receiver exactly credited",
'Amount > 450 000',
'Frequent receiver',
'Merchant receiver',
'Sender ID',
'Receiver ID']
feature_texts = {0: "Time step: ", 1: "Amount transferred: ", 2: "Initial balance of sender: ", 3: "New balance of sender: ",
4: "Initial balance of recipient: ", 5: "New balance of recipient: ", 6: "Sender's balance was exactly credited: ",
7: "Receiver's balance was exactly credited: ", 8: "Transaction over 450.000: ", 9: "Frequent receiver of transactions: ", 10: "Receiver is merchant: ", 11: "Sender ID: ", 12: "Receiver ID: ",
13: "Transaction type is Cash out", 14: "Transaction type is Transfer", 15: "Transaction type is Payment", 16: "Transaction type is Cash in", 17: "Transaction type is Debit"}
CATEGORIES = np.array(['CASH_OUT', 'TRANSFER', 'PAYMENT', 'CASH_IN', 'DEBIT'])
def transformation(input, categories):
new_x = input
cat = np.array(input[1])
del new_x[1]
result_array = np.zeros(5, dtype=int)
match_index = np.where(categories == cat)[0]
result_array[match_index] = 1
new_x.extend(result_array.tolist())
python_objects = [np_type.item() if isinstance(np_type, np.generic) else np_type for np_type in new_x]
return python_objects
def get_request_body(datapoint):
data = datapoint.iloc[0].tolist()
instances = [int(x) if isinstance(x, (np.int32, np.int64)) else x for x in data]
request_body = {'instances': [instances]}
return request_body
def get_explainability_texts(shap_values, feature_texts):
# Separate positive and negative values, keep indice as corresponds to key
positive_dict = {index: val for index, val in enumerate(shap_values) if val > 0}
# Sort dictionaries based on the magnitude of values
sorted_positive_indices = [index for index, _ in sorted(positive_dict.items(), key=lambda item: abs(item[1]), reverse=True)]
positive_texts = [feature_texts[x] for x in sorted_positive_indices]
positive_texts = positive_texts[2:]
sorted_positive_indices = sorted_positive_indices[2:]
if len(positive_texts) > 5:
positive_texts = positive_texts[:5]
sorted_positive_indices = sorted_positive_indices[:5]
return positive_texts, sorted_positive_indices
def get_explainability_values(pos_indices, datapoint):
data = datapoint.iloc[0].tolist()
rounded_data = [round(value, 2) if isinstance(value, float) else value for value in data]
transformed_data = transformation(input=rounded_data, categories=CATEGORIES)
vals = []
for idx in pos_indices:
if idx in range(6,11) or idx in range(13,18):
val = str(bool(transformed_data[idx])).capitalize()
else:
val = transformed_data[idx]
vals.append(val)
return vals
# def get_weights(shap_values, sorted_indices):
# weights = [shap_values[x] for x in sorted_indices]
# total_sum = sum(weights)
# scaled_values = [val/total_sum for val in weights]
# return scaled_values
def get_weights(shap_values, sorted_indices, target_sum=0.95):
weights = [shap_values[x] for x in sorted_indices]
total_sum = sum(weights)
# Scale to the target sum (0.95 in this case)
scaled_values = [val * (target_sum / total_sum) for val in weights]
return scaled_values
def get_fake_certainty():
# Generate a random certainty between 75% and 99%
fake_certainty = uniform(0.75, 0.99)
formatted_fake_certainty = "{:.2%}".format(fake_certainty)
return formatted_fake_certainty
def get_random_suspicious_transaction(data):
suspicious_data=data[data["isFraud"]==1]
max_n=len(suspicious_data)
random_nr=randrange(max_n)
suspicous_transaction = suspicious_data[random_nr-1:random_nr].drop("isFraud", axis=1)
return suspicous_transaction
def send_evaluation(client, deployment_id, request_log_id, prediction_log_id, evaluation_input):
"""Send evaluation to Deeploy."""
try:
with st.spinner("Submitting response..."):
# Call the explain endpoint as it also includes the prediction
client.evaluate(deployment_id, request_log_id, prediction_log_id, evaluation_input)
return True
except Exception as e:
logging.error(e)
st.error(
"Failed to submit feedback."
+ "Check whether you are using the right model URL and Token. "
+ "Contact Deeploy if the problem persists."
)
st.write(f"Error message: {e}")
def get_model_url():
"""Get model url and retrieve workspace id and deployment id from it"""
model_url = st.text_area(
"Model URL (default is the demo deployment)",
"https://api.app.deeploy.ml/workspaces/708b5808-27af-461a-8ee5-80add68384c7/deployments/ac56dbdf-ba04-462f-aa70-5a0d18698e42/",
height=125,
)
elems = model_url.split("/")
try:
workspace_id = elems[4]
deployment_id = elems[6]
except IndexError:
workspace_id = ""
deployment_id = ""
return model_url, workspace_id, deployment_id
def get_comment_explanation(certainty, explainability_texts, explainability_values):
cleaned = [x.replace(':', '') for x in explainability_texts]
fi = [f'{cleaned[i]} is {x}' for i, x in enumerate(explainability_values)]
fi.insert(0, 'Important suspicious features: ')
result = '\n'.join(fi)
comment = f"Model certainty is {certainty}" + '\n''\n' + result
return comment
def create_data_input_table(datapoint, col_names):
st.subheader("Transaction details")
data = datapoint.iloc[0].tolist()
data[7:12] = [bool(value) for value in data[7:12]]
rounded_list = [round(value, 2) if isinstance(value, float) else value for value in data]
df = pd.DataFrame({"Feature name": col_names, "Value": rounded_list })
st.dataframe(df, hide_index=True, use_container_width=True, height=35*len(df)+38) #width=450
# Create a function to generate a table
def create_table(texts, values, weights, title):
df = pd.DataFrame({"Feature Explanation": texts, 'Value': values, 'Weight': weights})
st.markdown(f'#### {title}') # Markdown for styling
st.dataframe(df, hide_index=True, use_container_width=True, column_config={
'Weight': st.column_config.ProgressColumn(
'Weight',
width='small',
format="%.2f",
min_value=0,
max_value=1
)
}) #width=450 # Display a simple table
def ChangeButtonColour(widget_label, font_color, background_color='transparent'):
htmlstr = f"""
<script>
var elements = window.parent.document.querySelectorAll('button');
for (var i = 0; i < elements.length; ++i) {{
if (elements[i].innerText == '{widget_label}') {{
elements[i].style.color ='{font_color}';
elements[i].style.background = '{background_color}'
}}
}}
</script>
"""
components.html(f"{htmlstr}", height=0, width=0) |