adollbo commited on
Commit
304bada
·
1 Parent(s): 8af40ab

changed timestep to date, made amounts smaller and more interpretable

Browse files
Files changed (2) hide show
  1. app.py +4 -3
  2. utils.py +25 -11
app.py CHANGED
@@ -5,7 +5,7 @@ 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, send_evaluation, get_comment_explanation
7
  from utils import COL_NAMES, feature_texts
8
- from utils import create_data_input_table, create_table, ChangeButtonColour, get_weights
9
 
10
  logging.basicConfig(level=logging.INFO)
11
 
@@ -113,11 +113,12 @@ if st.session_state.got_explanation:
113
  prediction_log_id = st.session_state.prediction_log_id
114
  datapoint_pd = st.session_state.datapoint_pd
115
  certainty = st.session_state.certainty
 
116
 
117
  col1, col2 = st.columns(2)
118
 
119
  with col1:
120
- create_data_input_table(datapoint_pd, COL_NAMES)
121
 
122
  with col2:
123
  st.subheader('AML Model Hit')
@@ -130,7 +131,7 @@ if st.session_state.got_explanation:
130
 
131
  explainability_texts, sorted_indices = get_explainability_texts(shap_values, feature_texts)
132
  weights = get_weights(shap_values, sorted_indices)
133
- explainability_values = get_explainability_values(sorted_indices, datapoint_pd)
134
  create_table(explainability_texts, explainability_values, weights, 'Important Suspicious Factors')
135
 
136
  st.subheader("")
 
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, send_evaluation, get_comment_explanation
7
  from utils import COL_NAMES, feature_texts
8
+ from utils import create_data_input_table, create_table, ChangeButtonColour, get_weights, modify_datapoint
9
 
10
  logging.basicConfig(level=logging.INFO)
11
 
 
113
  prediction_log_id = st.session_state.prediction_log_id
114
  datapoint_pd = st.session_state.datapoint_pd
115
  certainty = st.session_state.certainty
116
+ datapoint = modify_datapoint(datapoint_pd)
117
 
118
  col1, col2 = st.columns(2)
119
 
120
  with col1:
121
+ create_data_input_table(datapoint, COL_NAMES)
122
 
123
  with col2:
124
  st.subheader('AML Model Hit')
 
131
 
132
  explainability_texts, sorted_indices = get_explainability_texts(shap_values, feature_texts)
133
  weights = get_weights(shap_values, sorted_indices)
134
+ explainability_values = get_explainability_values(sorted_indices, datapoint)
135
  create_table(explainability_texts, explainability_values, weights, 'Important Suspicious Factors')
136
 
137
  st.subheader("")
utils.py CHANGED
@@ -4,8 +4,11 @@ from random import randrange, uniform
4
  import pandas as pd
5
  import logging
6
  import numpy as np
 
 
 
7
 
8
- COL_NAMES = ['Time step',
9
  'Transaction type',
10
  'Amount transferred',
11
  'Sender\'s initial balance',
@@ -20,7 +23,7 @@ COL_NAMES = ['Time step',
20
  'Sender ID',
21
  'Receiver ID']
22
 
23
- feature_texts = {0: "Time step: ", 1: "Amount transferred: ", 2: "Initial balance of sender: ", 3: "New balance of sender: ",
24
  4: "Initial balance of recipient: ", 5: "New balance of recipient: ", 6: "Sender's balance was exactly credited: ",
25
  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: ",
26
  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"}
@@ -59,8 +62,13 @@ def get_explainability_texts(shap_values, feature_texts):
59
  return positive_texts, sorted_positive_indices
60
 
61
 
62
- def get_explainability_values(pos_indices, datapoint):
63
- data = datapoint.iloc[0].tolist()
 
 
 
 
 
64
  rounded_data = [round(value, 2) if isinstance(value, float) else value for value in data]
65
  transformed_data = transformation(input=rounded_data, categories=CATEGORIES)
66
  vals = []
@@ -72,11 +80,18 @@ def get_explainability_values(pos_indices, datapoint):
72
  vals.append(val)
73
  return vals
74
 
75
- # def get_weights(shap_values, sorted_indices):
76
- # weights = [shap_values[x] for x in sorted_indices]
77
- # total_sum = sum(weights)
78
- # scaled_values = [val/total_sum for val in weights]
79
- # return scaled_values
 
 
 
 
 
 
 
80
 
81
  def get_weights(shap_values, sorted_indices, target_sum=0.95):
82
  weights = [shap_values[x] for x in sorted_indices]
@@ -141,9 +156,8 @@ def get_comment_explanation(certainty, explainability_texts, explainability_valu
141
  comment = f"Model certainty is {certainty}" + '\n''\n' + result
142
  return comment
143
 
144
- def create_data_input_table(datapoint, col_names):
145
  st.subheader("Transaction details")
146
- data = datapoint.iloc[0].tolist()
147
  data[7:12] = [bool(value) for value in data[7:12]]
148
  rounded_list = [round(value, 2) if isinstance(value, float) else value for value in data]
149
  df = pd.DataFrame({"Feature name": col_names, "Value": rounded_list })
 
4
  import pandas as pd
5
  import logging
6
  import numpy as np
7
+ import random
8
+ from datetime import datetime, timedelta
9
+ from babel.numbers import format_currency
10
 
11
+ COL_NAMES = ['Transaction date',
12
  'Transaction type',
13
  'Amount transferred',
14
  'Sender\'s initial balance',
 
23
  'Sender ID',
24
  'Receiver ID']
25
 
26
+ feature_texts = {0: "Date of transaction: ", 1: "Amount transferred: ", 2: "Initial balance of sender: ", 3: "New balance of sender: ",
27
  4: "Initial balance of recipient: ", 5: "New balance of recipient: ", 6: "Sender's balance was exactly credited: ",
28
  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: ",
29
  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"}
 
62
  return positive_texts, sorted_positive_indices
63
 
64
 
65
+ def random_past_date_from_last_year():
66
+ one_year_ago = datetime.now() - timedelta(days=365)
67
+ random_days = random.randint(0, (datetime.now() - one_year_ago).days)
68
+ random_date = one_year_ago + timedelta(days=random_days)
69
+ return random_date.strftime('%Y-%m-%d')
70
+
71
+ def get_explainability_values(pos_indices, data):
72
  rounded_data = [round(value, 2) if isinstance(value, float) else value for value in data]
73
  transformed_data = transformation(input=rounded_data, categories=CATEGORIES)
74
  vals = []
 
80
  vals.append(val)
81
  return vals
82
 
83
+ def modify_datapoint(datapoint): # should return list, with correct numbers/amounts, and date
84
+ data = datapoint.iloc[0].tolist()
85
+ data[0] = random_past_date_from_last_year()
86
+ modified_amounts = data.copy()
87
+ if any(val > 12000 for val in data[2:7]):
88
+ modified_amounts[2:7] = [value / 100 if value != 0 else 0 for value in data[2:7]]
89
+ if any(val > 120000 for val in modified_amounts[2:7]):
90
+ new_list = [value / 10 if value != 0 else 0 for value in modified_amounts[2:7]]
91
+ modified_amounts[2:7] = new_list
92
+ rounded_data = [round(value, 2) if isinstance(value, float) else value for value in modified_amounts]
93
+ rounded_data[2:7] = [format_currency(value, 'EUR', locale='en_GB') for value in rounded_data[2:7]]
94
+ return rounded_data
95
 
96
  def get_weights(shap_values, sorted_indices, target_sum=0.95):
97
  weights = [shap_values[x] for x in sorted_indices]
 
156
  comment = f"Model certainty is {certainty}" + '\n''\n' + result
157
  return comment
158
 
159
+ def create_data_input_table(data, col_names):
160
  st.subheader("Transaction details")
 
161
  data[7:12] = [bool(value) for value in data[7:12]]
162
  rounded_list = [round(value, 2) if isinstance(value, float) else value for value in data]
163
  df = pd.DataFrame({"Feature name": col_names, "Value": rounded_list })