SuperModelingFactory 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ExcelMaster/ExcelFormatTool.py +487 -0
- ExcelMaster/ExcelMaster.py +917 -0
- ExcelMaster/Template.py +525 -0
- ExcelMaster/Utility.py +233 -0
- ExcelMaster/__init__.py +3 -0
- Modeling_Tool/Core/Binning_Tool.py +1608 -0
- Modeling_Tool/Core/Binning_Tool.pyi +48 -0
- Modeling_Tool/Core/Check_DuckDB_Compatibility.py +835 -0
- Modeling_Tool/Core/Json_Data_Converter.py +621 -0
- Modeling_Tool/Core/Model_Registry_Tool.py +199 -0
- Modeling_Tool/Core/ODPS_Tool.py +284 -0
- Modeling_Tool/Core/Slope_Tool.py +356 -0
- Modeling_Tool/Core/Slope_Tool.pyi +31 -0
- Modeling_Tool/Core/XOR_Encryptor.py +207 -0
- Modeling_Tool/Core/XOR_Encryptor.pyi +26 -0
- Modeling_Tool/Core/__init__.py +99 -0
- Modeling_Tool/Core/kDataFrame.py +228 -0
- Modeling_Tool/Core/kDataFrame.pyi +43 -0
- Modeling_Tool/Core/sample_weight_utils.py +77 -0
- Modeling_Tool/Core/utils.py +2672 -0
- Modeling_Tool/Eval/Evaluation_Tool.py +1452 -0
- Modeling_Tool/Eval/Evaluation_Tool.pyi +47 -0
- Modeling_Tool/Eval/Model_Eval_Tool.py +2548 -0
- Modeling_Tool/Eval/Model_Eval_Tool.pyi +37 -0
- Modeling_Tool/Eval/__init__.py +54 -0
- Modeling_Tool/Eval/evaluate_model.py +2008 -0
- Modeling_Tool/Eval/evaluate_model.pyi +50 -0
- Modeling_Tool/Eval/weighted_eval_utils.py +326 -0
- Modeling_Tool/Explainability/Coalition_Structure.py +305 -0
- Modeling_Tool/Explainability/Model_Explainer.py +743 -0
- Modeling_Tool/Explainability/__init__.py +24 -0
- Modeling_Tool/Feature/Distribution_Tool.py +509 -0
- Modeling_Tool/Feature/Distribution_Tool.pyi +42 -0
- Modeling_Tool/Feature/Feature_Insights.py +762 -0
- Modeling_Tool/Feature/Feature_Insights.pyi +33 -0
- Modeling_Tool/Feature/PSI_Tool.py +1195 -0
- Modeling_Tool/Feature/PSI_Tool.pyi +29 -0
- Modeling_Tool/Feature/WOE_Engine_Feature_Patch.py +355 -0
- Modeling_Tool/Feature/__init__.py +40 -0
- Modeling_Tool/Model/Backward_Tool.py +778 -0
- Modeling_Tool/Model/Backward_Tool.pyi +45 -0
- Modeling_Tool/Model/GBM_Search_Tool.py +251 -0
- Modeling_Tool/Model/GBM_Tool.py +1610 -0
- Modeling_Tool/Model/GBM_Tool.pyi +90 -0
- Modeling_Tool/Model/LRM_Tool.py +1198 -0
- Modeling_Tool/Model/LRM_Tool.pyi +47 -0
- Modeling_Tool/Model/__init__.py +61 -0
- Modeling_Tool/Sample/Distribution_Adaptation.py +131 -0
- Modeling_Tool/Sample/Distribution_Adaptation.pyi +30 -0
- Modeling_Tool/Sample/Reject_Infer.py +413 -0
- Modeling_Tool/Sample/Reject_Infer.pyi +43 -0
- Modeling_Tool/Sample/Sample_Split.py +520 -0
- Modeling_Tool/Sample/Sample_Split.pyi +43 -0
- Modeling_Tool/Sample/__init__.py +31 -0
- Modeling_Tool/UAT/UAT_Consistency_Checker.py +1180 -0
- Modeling_Tool/UAT/__init__.py +19 -0
- Modeling_Tool/WOE/WOE_Adapter.py +204 -0
- Modeling_Tool/WOE/WOE_Adapter.pyi +21 -0
- Modeling_Tool/WOE/WOE_Master.py +491 -0
- Modeling_Tool/WOE/WOE_Master.pyi +40 -0
- Modeling_Tool/WOE/WOE_Monotone_Binner.py +3324 -0
- Modeling_Tool/WOE/WOE_Monotone_Binner.pyi +71 -0
- Modeling_Tool/WOE/WOE_Plot_Tool.py +919 -0
- Modeling_Tool/WOE/WOE_Plot_Tool.pyi +46 -0
- Modeling_Tool/WOE/WOE_Report_Builder.py +214 -0
- Modeling_Tool/WOE/WOE_Report_Builder.pyi +24 -0
- Modeling_Tool/WOE/WOE_Tool.py +1094 -0
- Modeling_Tool/WOE/WOE_Tool.pyi +41 -0
- Modeling_Tool/WOE/__init__.py +86 -0
- Modeling_Tool/WOE/plot_woe_tool.py +290 -0
- Modeling_Tool/WOE/plot_woe_tool.pyi +25 -0
- Modeling_Tool/__init__.py +176 -0
- Report/Report_Tool.py +380 -0
- Report/__init__.py +3 -0
- supermodelingfactory-0.2.0.dist-info/METADATA +268 -0
- supermodelingfactory-0.2.0.dist-info/RECORD +79 -0
- supermodelingfactory-0.2.0.dist-info/WHEEL +5 -0
- supermodelingfactory-0.2.0.dist-info/licenses/LICENSE +102 -0
- supermodelingfactory-0.2.0.dist-info/top_level.txt +3 -0
ExcelMaster/Utility.py
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import xlsxwriter
|
|
2
|
+
from xlsxwriter.utility import xl_rowcol_to_cell, xl_range, xl_cell_to_rowcol
|
|
3
|
+
import openpyxl
|
|
4
|
+
import pandas as pd
|
|
5
|
+
import numpy as np
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
import pdb, re, os
|
|
8
|
+
from PIL import Image
|
|
9
|
+
import random
|
|
10
|
+
|
|
11
|
+
import matplotlib.pyplot as plt # For data visualisation
|
|
12
|
+
import seaborn as sns # For data visualisation
|
|
13
|
+
from matplotlib.ticker import PercentFormatter
|
|
14
|
+
|
|
15
|
+
def getStartDateofLatestWeek(retStr=True):
|
|
16
|
+
""" Date of first day of last week. """
|
|
17
|
+
import datetime
|
|
18
|
+
today = datetime.date.today()
|
|
19
|
+
curr_wk = today.strftime("%W")
|
|
20
|
+
d = f"{str(today.year)}-W{curr_wk}"
|
|
21
|
+
r = datetime.datetime.strptime(d + '-1', "%Y-W%W-%w")
|
|
22
|
+
res = (r + datetime.timedelta(days=-1))
|
|
23
|
+
if retStr:
|
|
24
|
+
return res.strftime("%Y-%m-%d")
|
|
25
|
+
return res
|
|
26
|
+
|
|
27
|
+
def getLastCompletedVintage(start_date = None, format="%Y-%m-%d", vintage=False):
|
|
28
|
+
""" Last Completed Vintage """
|
|
29
|
+
import datetime
|
|
30
|
+
|
|
31
|
+
todayDate = datetime.date.today()
|
|
32
|
+
|
|
33
|
+
if start_date is not None:
|
|
34
|
+
todayDate = datetime.datetime.strptime(start_date, format).date()
|
|
35
|
+
|
|
36
|
+
lastM = todayDate.replace(day=1) - datetime.timedelta(days=1)
|
|
37
|
+
if vintage:
|
|
38
|
+
return int(lastM.strftime(format)[0:7].replace("-",""))
|
|
39
|
+
return lastM.strftime(format)
|
|
40
|
+
|
|
41
|
+
def vin2quar(strDate):
|
|
42
|
+
""" String Vintage to Quarter (if compeleted month). """
|
|
43
|
+
year = int(strDate[:4])
|
|
44
|
+
month = int(strDate[4:6])
|
|
45
|
+
completed_q = [3, 6, 9, 12]
|
|
46
|
+
if month in completed_q:
|
|
47
|
+
q = (month-1)//3 + 1
|
|
48
|
+
return str(year) + "Q" + str(q)
|
|
49
|
+
return strDate
|
|
50
|
+
|
|
51
|
+
def list_files(location, pattern):
|
|
52
|
+
""" List all files. """
|
|
53
|
+
import re
|
|
54
|
+
res = []
|
|
55
|
+
for root, dirs, files in os.walk(location):
|
|
56
|
+
for file in files:
|
|
57
|
+
if re.search(pattern, file):
|
|
58
|
+
res.append(file)
|
|
59
|
+
return res
|
|
60
|
+
|
|
61
|
+
def getCurrentDateTime(fmt = "%Y%m%d%H%M%S"):
|
|
62
|
+
""" Get Current DateTime"""
|
|
63
|
+
import datetime
|
|
64
|
+
return datetime.datetime.now().strftime(fmt)
|
|
65
|
+
|
|
66
|
+
def input_table_proc(tbl):
|
|
67
|
+
""" Process Input Table. """
|
|
68
|
+
tbl.columns = [x.lower() for x in tbl.columns]
|
|
69
|
+
return tbl
|
|
70
|
+
|
|
71
|
+
def get_file_extension(input_path):
|
|
72
|
+
""" Get File Extentsion for a given file Path. """
|
|
73
|
+
return os.path.splitext(input_path)[1]
|
|
74
|
+
|
|
75
|
+
def input_validation(x, sep=","):
|
|
76
|
+
""" Input Validation. """
|
|
77
|
+
import os
|
|
78
|
+
if isinstance(x, str):
|
|
79
|
+
if get_file_extension(x) == ".sas7bdat":
|
|
80
|
+
res = pd.read_sas(x, encoding="latin-1")
|
|
81
|
+
else:
|
|
82
|
+
res = pd.read_csv(x, sep = sep)
|
|
83
|
+
res = input_table_proc(res)
|
|
84
|
+
return res
|
|
85
|
+
elif isinstance(x, pd.DataFrame):
|
|
86
|
+
return input_table_proc(x)
|
|
87
|
+
else:
|
|
88
|
+
raise AttributeError("Only Support csv/sas7bdat Path or Panda DataFrame as Input!!!")
|
|
89
|
+
|
|
90
|
+
def val_input_condition(target, condition = (">", 20)):
|
|
91
|
+
""" Condition Tuple Validation. """
|
|
92
|
+
if isinstance(condition, str):
|
|
93
|
+
return (target == condition)
|
|
94
|
+
|
|
95
|
+
else:
|
|
96
|
+
operator = condition[0].strip().lower()
|
|
97
|
+
value = float(condition[1])
|
|
98
|
+
|
|
99
|
+
if operator == '>' or operator == 'gt':
|
|
100
|
+
return (target > value)
|
|
101
|
+
elif operator == '<' or operator == 'lt':
|
|
102
|
+
return (target < value)
|
|
103
|
+
elif operator == '=' or operator == 'eq':
|
|
104
|
+
return (target == value)
|
|
105
|
+
elif operator == '>=' or operator == 'gte':
|
|
106
|
+
return (target >= value)
|
|
107
|
+
elif operator == '<=' or operator == 'lte':
|
|
108
|
+
return (target <= value)
|
|
109
|
+
elif operator == '=' or operator == 'eq':
|
|
110
|
+
return (target == value)
|
|
111
|
+
|
|
112
|
+
def get_quarter(strDate):
|
|
113
|
+
return ((int(strDate[4:6])-1)//3) + 1
|
|
114
|
+
|
|
115
|
+
def tanspose_dataframe(df, index_col):
|
|
116
|
+
""" Transpose Pandas DataFrame. """
|
|
117
|
+
df = df.set_index(index_col).T.reset_index()
|
|
118
|
+
return df
|
|
119
|
+
|
|
120
|
+
def convert_perc_str_to_float(df, cols):
|
|
121
|
+
""" Percentage to Float. """
|
|
122
|
+
for col in cols:
|
|
123
|
+
if str(df[col].dtypes) == 'object':
|
|
124
|
+
df[col] = df[col].str.rstrip('%').astype('float') / 100
|
|
125
|
+
return df
|
|
126
|
+
|
|
127
|
+
def color_hex2rgb(hex_code):
|
|
128
|
+
""" Convert Color Hex Code to RGB Tuple. """
|
|
129
|
+
hex_code = hex_code.lower()
|
|
130
|
+
h = hex_code.lstrip('#')
|
|
131
|
+
return tuple(int(h[i:i+2], 16) for i in (0, 2, 4))
|
|
132
|
+
|
|
133
|
+
def get_color_set(n, start_num = 0, step = 1, retName = False, lookupName = None):
|
|
134
|
+
""" Return a set of color code without replacement. """
|
|
135
|
+
import matplotlib.colors as mcolors
|
|
136
|
+
import re
|
|
137
|
+
|
|
138
|
+
colors = list(mcolors.XKCD_COLORS.items())
|
|
139
|
+
color_set = {}
|
|
140
|
+
|
|
141
|
+
for i in range(start_num, start_num + n * step, step):
|
|
142
|
+
name = colors[i][0].replace("xkcd:", "")
|
|
143
|
+
color = colors[i][1]
|
|
144
|
+
color_set[name] = color
|
|
145
|
+
|
|
146
|
+
if lookupName:
|
|
147
|
+
color_set = {}
|
|
148
|
+
i = 0
|
|
149
|
+
for name, color in colors:
|
|
150
|
+
if len(color_set.items()) == n:
|
|
151
|
+
break
|
|
152
|
+
if re.search(lookupName, name):
|
|
153
|
+
color_set[name.replace("xkcd:", "")] = color
|
|
154
|
+
i += 1
|
|
155
|
+
|
|
156
|
+
if retName:
|
|
157
|
+
return color_set
|
|
158
|
+
return list(color_set.values())
|
|
159
|
+
|
|
160
|
+
def string_proc(x):
|
|
161
|
+
""" Process a given String. """
|
|
162
|
+
x_list = x.split("_")
|
|
163
|
+
x_list = [x.strip().capitalize() for x in x_list]
|
|
164
|
+
x = " ".join(x_list)
|
|
165
|
+
return x
|
|
166
|
+
|
|
167
|
+
def convert_to_boxplot_data(df, x, y, y_percentage = False):
|
|
168
|
+
""" Convert dataframe to boxplot data. """
|
|
169
|
+
x_unique_value = df[x].sort_values().unique().tolist()
|
|
170
|
+
|
|
171
|
+
box_plot_data = {}
|
|
172
|
+
for v in x_unique_value:
|
|
173
|
+
box_plot_data[v] = [num * 100 if y_percentage else num for num in df[df[x] == v][y].tolist()]
|
|
174
|
+
return box_plot_data
|
|
175
|
+
|
|
176
|
+
def color_input_validation(color_grp, val_n):
|
|
177
|
+
""" Perform Color Input Validation. """
|
|
178
|
+
if isinstance(color_grp, tuple) and len(color_grp) == 2:
|
|
179
|
+
# Customize colors
|
|
180
|
+
cols = get_color_set(val_n, color_grp[0], color_grp[1], False)
|
|
181
|
+
colors = cols
|
|
182
|
+
elif isinstance(color_grp, str):
|
|
183
|
+
colors = [color_grp] * val_n
|
|
184
|
+
elif (isinstance(color_grp, list)) and (all([isinstance(x, str) for x in color_grp])) and (len(color_grp) == val_n):
|
|
185
|
+
colors = color_grp
|
|
186
|
+
else:
|
|
187
|
+
raise ValueError("Please give valid color_grp: tuple of two numbers, list of color code or a single color code.")
|
|
188
|
+
return colors
|
|
189
|
+
|
|
190
|
+
def get_metric_shift(data, metric_name, nvars_col = "nvars"):
|
|
191
|
+
""" Calculate Metric Shift for Variable Reduction. """
|
|
192
|
+
metric_lift = (data[metric_name] - data[metric_name].shift(1))
|
|
193
|
+
nvars_reduced = (data[nvars_col] - data[nvars_col].shift(1))
|
|
194
|
+
return (metric_lift / nvars_reduced).fillna(0)
|
|
195
|
+
|
|
196
|
+
def get_metrics_shift(data, metric_cols):
|
|
197
|
+
""" Get Shift for List of Metrics."""
|
|
198
|
+
for metric in metric_cols:
|
|
199
|
+
if metric.startswith(tuple(metric_cols)):
|
|
200
|
+
data[metric+"_shift"] = get_metric_shift(data, metric)
|
|
201
|
+
return data
|
|
202
|
+
|
|
203
|
+
def compute_overfitting_shift(data, sample_prefix):
|
|
204
|
+
""" Calculate Overfitting Performance Shift. """
|
|
205
|
+
b_metrics = [x for x in data.columns if x.startswith(sample_prefix[0])]
|
|
206
|
+
o_metrics = [x for x in data.columns if x.startswith(sample_prefix[1])]
|
|
207
|
+
|
|
208
|
+
if len(b_metrics) == len(o_metrics):
|
|
209
|
+
for b_metric, o_metric in zip(b_metrics, o_metrics):
|
|
210
|
+
data[o_metric+"_shift"] = data[o_metric].div(data[b_metric]) - 1
|
|
211
|
+
return data
|
|
212
|
+
|
|
213
|
+
raise ValueError("The lengths of metrics between two samples are the the same in the given dataset!")
|
|
214
|
+
|
|
215
|
+
def proc_psi_raw_report(psi_raw_table, psi_title, keep_list = None, varname = "variable", upper=True):
|
|
216
|
+
""" Processing Raw PSI Report generated from Takecopter. """
|
|
217
|
+
psi_table = input_validation(psi_raw_table)
|
|
218
|
+
psi_table = psi_table.rename(columns={"var_for_psi":varname})
|
|
219
|
+
psi_table = psi_table.set_index(varname)
|
|
220
|
+
if upper:
|
|
221
|
+
psi_table.columns = [x.upper() for x in psi_table.columns]
|
|
222
|
+
psi_table.columns = [[psi_title]*len(psi_table.columns),psi_table.columns]
|
|
223
|
+
if keep_list:
|
|
224
|
+
psi_table = psi_table[[(psi_title, x) for x in keep_list]]
|
|
225
|
+
return psi_table
|
|
226
|
+
|
|
227
|
+
def get_mean_risk(bivar_single_attr, value_range_col = ['min_indep', 'max_indep'], dep_col = "dep"):
|
|
228
|
+
"""get average risk"""
|
|
229
|
+
mean_wo_nan = bivar_single_attr.dropna(how = "all", subset=value_range_col)[dep_col].mean()
|
|
230
|
+
mean_w_na = bivar_single_attr[dep_col].mean()
|
|
231
|
+
bivar_single_attr["mean"] = mean_w_na
|
|
232
|
+
bivar_single_attr["mean_no_nan"] = mean_wo_nan
|
|
233
|
+
return bivar_single_attr
|
ExcelMaster/__init__.py
ADDED