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.
Files changed (79) hide show
  1. ExcelMaster/ExcelFormatTool.py +487 -0
  2. ExcelMaster/ExcelMaster.py +917 -0
  3. ExcelMaster/Template.py +525 -0
  4. ExcelMaster/Utility.py +233 -0
  5. ExcelMaster/__init__.py +3 -0
  6. Modeling_Tool/Core/Binning_Tool.py +1608 -0
  7. Modeling_Tool/Core/Binning_Tool.pyi +48 -0
  8. Modeling_Tool/Core/Check_DuckDB_Compatibility.py +835 -0
  9. Modeling_Tool/Core/Json_Data_Converter.py +621 -0
  10. Modeling_Tool/Core/Model_Registry_Tool.py +199 -0
  11. Modeling_Tool/Core/ODPS_Tool.py +284 -0
  12. Modeling_Tool/Core/Slope_Tool.py +356 -0
  13. Modeling_Tool/Core/Slope_Tool.pyi +31 -0
  14. Modeling_Tool/Core/XOR_Encryptor.py +207 -0
  15. Modeling_Tool/Core/XOR_Encryptor.pyi +26 -0
  16. Modeling_Tool/Core/__init__.py +99 -0
  17. Modeling_Tool/Core/kDataFrame.py +228 -0
  18. Modeling_Tool/Core/kDataFrame.pyi +43 -0
  19. Modeling_Tool/Core/sample_weight_utils.py +77 -0
  20. Modeling_Tool/Core/utils.py +2672 -0
  21. Modeling_Tool/Eval/Evaluation_Tool.py +1452 -0
  22. Modeling_Tool/Eval/Evaluation_Tool.pyi +47 -0
  23. Modeling_Tool/Eval/Model_Eval_Tool.py +2548 -0
  24. Modeling_Tool/Eval/Model_Eval_Tool.pyi +37 -0
  25. Modeling_Tool/Eval/__init__.py +54 -0
  26. Modeling_Tool/Eval/evaluate_model.py +2008 -0
  27. Modeling_Tool/Eval/evaluate_model.pyi +50 -0
  28. Modeling_Tool/Eval/weighted_eval_utils.py +326 -0
  29. Modeling_Tool/Explainability/Coalition_Structure.py +305 -0
  30. Modeling_Tool/Explainability/Model_Explainer.py +743 -0
  31. Modeling_Tool/Explainability/__init__.py +24 -0
  32. Modeling_Tool/Feature/Distribution_Tool.py +509 -0
  33. Modeling_Tool/Feature/Distribution_Tool.pyi +42 -0
  34. Modeling_Tool/Feature/Feature_Insights.py +762 -0
  35. Modeling_Tool/Feature/Feature_Insights.pyi +33 -0
  36. Modeling_Tool/Feature/PSI_Tool.py +1195 -0
  37. Modeling_Tool/Feature/PSI_Tool.pyi +29 -0
  38. Modeling_Tool/Feature/WOE_Engine_Feature_Patch.py +355 -0
  39. Modeling_Tool/Feature/__init__.py +40 -0
  40. Modeling_Tool/Model/Backward_Tool.py +778 -0
  41. Modeling_Tool/Model/Backward_Tool.pyi +45 -0
  42. Modeling_Tool/Model/GBM_Search_Tool.py +251 -0
  43. Modeling_Tool/Model/GBM_Tool.py +1610 -0
  44. Modeling_Tool/Model/GBM_Tool.pyi +90 -0
  45. Modeling_Tool/Model/LRM_Tool.py +1198 -0
  46. Modeling_Tool/Model/LRM_Tool.pyi +47 -0
  47. Modeling_Tool/Model/__init__.py +61 -0
  48. Modeling_Tool/Sample/Distribution_Adaptation.py +131 -0
  49. Modeling_Tool/Sample/Distribution_Adaptation.pyi +30 -0
  50. Modeling_Tool/Sample/Reject_Infer.py +413 -0
  51. Modeling_Tool/Sample/Reject_Infer.pyi +43 -0
  52. Modeling_Tool/Sample/Sample_Split.py +520 -0
  53. Modeling_Tool/Sample/Sample_Split.pyi +43 -0
  54. Modeling_Tool/Sample/__init__.py +31 -0
  55. Modeling_Tool/UAT/UAT_Consistency_Checker.py +1180 -0
  56. Modeling_Tool/UAT/__init__.py +19 -0
  57. Modeling_Tool/WOE/WOE_Adapter.py +204 -0
  58. Modeling_Tool/WOE/WOE_Adapter.pyi +21 -0
  59. Modeling_Tool/WOE/WOE_Master.py +491 -0
  60. Modeling_Tool/WOE/WOE_Master.pyi +40 -0
  61. Modeling_Tool/WOE/WOE_Monotone_Binner.py +3324 -0
  62. Modeling_Tool/WOE/WOE_Monotone_Binner.pyi +71 -0
  63. Modeling_Tool/WOE/WOE_Plot_Tool.py +919 -0
  64. Modeling_Tool/WOE/WOE_Plot_Tool.pyi +46 -0
  65. Modeling_Tool/WOE/WOE_Report_Builder.py +214 -0
  66. Modeling_Tool/WOE/WOE_Report_Builder.pyi +24 -0
  67. Modeling_Tool/WOE/WOE_Tool.py +1094 -0
  68. Modeling_Tool/WOE/WOE_Tool.pyi +41 -0
  69. Modeling_Tool/WOE/__init__.py +86 -0
  70. Modeling_Tool/WOE/plot_woe_tool.py +290 -0
  71. Modeling_Tool/WOE/plot_woe_tool.pyi +25 -0
  72. Modeling_Tool/__init__.py +176 -0
  73. Report/Report_Tool.py +380 -0
  74. Report/__init__.py +3 -0
  75. supermodelingfactory-0.2.0.dist-info/METADATA +268 -0
  76. supermodelingfactory-0.2.0.dist-info/RECORD +79 -0
  77. supermodelingfactory-0.2.0.dist-info/WHEEL +5 -0
  78. supermodelingfactory-0.2.0.dist-info/licenses/LICENSE +102 -0
  79. supermodelingfactory-0.2.0.dist-info/top_level.txt +3 -0
@@ -0,0 +1,525 @@
1
+ __Author__ = "Jingkai SUN"
2
+ __Date__ = "2025.05.15"
3
+
4
+ import pandas as pd
5
+ import numpy as np
6
+ from datetime import datetime
7
+ import pdb, re
8
+ from PIL import Image
9
+ pd.options.mode.chained_assignment = None
10
+
11
+ from ExcelMaster.ExcelFormatTool import ExcelFormat
12
+ from ExcelMaster.Utility import *
13
+ from ExcelMaster.ExcelMaster import ExcelMaster
14
+ import logging
15
+ logger = logging.getLogger(__name__)
16
+
17
+ def get_pva_report(em, ws, gains_result, sample_list, nbins = 10, varcol = "variable", chart_scale = (10, 10)):
18
+ """ Plot PVA Table by Segment across Sample. """
19
+ gains_results = input_validation(gains_result)
20
+
21
+ varcol = varcol.lower()
22
+ segs = gains_results["seg_name"].unique().tolist()
23
+ chart_size = (nbins + chart_scale[0], (nbins + chart_scale[1])/2)
24
+
25
+ # em.reset_curr_loc()
26
+ em.merge_col(worksheet=ws, ncols=5, text="PVA Charts")
27
+
28
+ em.gap_number = 2
29
+ for seg in segs:
30
+ """ Plot PVA charts by segment row by row """
31
+ ########## Data Wrangling ###############
32
+ example = gains_results.query(f"seg_name == '{seg}'").dropna()
33
+ example = convert_perc_str_to_float(example, ["interval_bad_rate"])
34
+
35
+ cols = ["rank", "sample", "mean_score", "interval_bad_rate"]
36
+
37
+ example_fnl = example[cols].astype({"rank":int}).melt(id_vars = ["rank", "sample"], value_vars = ["mean_score", "interval_bad_rate"])
38
+ example_fnl["score_type"] = example_fnl[varcol].str.replace("mean_score", "predicted").replace("interval_bad_rate", "actual")
39
+ example_fnl = example_fnl.pivot(index = ["rank"], columns=["sample", "score_type"], values = "value")
40
+ col_order = example_fnl.columns.get_level_values(0).unique().tolist()
41
+ fnl_out_res = example_fnl[col_order]
42
+
43
+ ########### Insert Data and Charts to the Worksheet ###################
44
+ em.write_text_content(worksheet=ws, input_text=f"{seg} [[ORANGE_H3]] \n")
45
+
46
+ # sample_list = example["sample"].unique().tolist()
47
+ chart_loc = {}
48
+ for sample in sample_list:
49
+ """ Plot PVA charts by sample column by column"""
50
+ example_sample = example.query(f"sample == '{sample}'").dropna()
51
+ loc = em.write_chart(ws, df = example_sample, x="rank",
52
+ y_list=["mean_score", "interval_bad_rate"],
53
+ title=f"PVA Chart ({sample.upper()}) {seg}",
54
+ chart_size=chart_size,
55
+ chart_type="line",
56
+ major_gridlines=False,
57
+ xy_axes_name=("Quantiles", "% of Bads"),
58
+ y_axis_range=(0, 1),
59
+ y_num_format="0.00%",
60
+ skipby="col", retCellRange="value")
61
+ chart_loc[sample] = loc
62
+
63
+ loc4 = em.write_dataframe(worksheet=ws, df=fnl_out_res, title=f"PVA Chart ({seg})", index=True, skipby="row", retCellRange="value")
64
+
65
+ tbl_value_range = [x + 2 if i == 0 else x + 1
66
+ if i == 1 else x + 2
67
+ if i == 2 else x
68
+ for i, x in enumerate(loc4)]
69
+
70
+ em.set_cell_format(ws, tbl_value_range, "----")
71
+ em.set_cell_format(ws, tbl_value_range, "NUM%.3")
72
+
73
+ chart1_loc = chart_loc[sample_list[0]]
74
+ em.curr_row = chart1_loc[2] + em.gap_number
75
+ em.curr_col = chart1_loc[1]
76
+ return ws
77
+
78
+ def get_bivar_report(em, ws, attr_info, bivar, sample_list, varcol = "varname", sample_col = "sample", x_cols = ["min_indep", "max_indep"], n_col = "_freq_", dep_col = "dep", chart_size = (20, 10), average_risk_line = False):
79
+ """ Get Bivar Report by Attribute across Samples. """
80
+
81
+ ##### Worksheet 1 ######
82
+ em.merge_col(worksheet = ws, ncols=5, text = "Bivar Plot")
83
+
84
+ bivar_table = input_validation(bivar)
85
+ attr_info_table = input_validation(attr_info)
86
+
87
+ varcol = varcol.lower()
88
+ sample_col = sample_col.lower()
89
+ x_cols = [x.lower() for x in x_cols]
90
+ n_col = n_col.lower()
91
+ dep_col = dep_col.lower()
92
+
93
+ bivar_table.columns = [x.lower() for x in bivar_table.columns]
94
+ attr_info_table.columns = [x.lower() for x in attr_info_table.columns]
95
+
96
+ var_by_varimp = attr_info_table[varcol].str.lower().tolist()
97
+ bivar_table["indep_range"] = "[" + bivar_table[x_cols[0]].astype(str) + ", " \
98
+ + bivar_table[x_cols[1]].astype(str) + "]"
99
+
100
+ for var in var_by_varimp:
101
+ """ Plot Bivar Chart by Variable Row by Row. """
102
+
103
+ em.gap_number = 1
104
+ singe_attr_info = attr_info_table.query(f"{varcol} == '{var.upper()}'")
105
+ em.write_dataframe(ws, df = singe_attr_info, index = False,
106
+ title =f"Information for Attribute {var.upper()}", skipby="row", retCellRange="value")
107
+ var_desc = singe_attr_info["description"].values[0]
108
+
109
+ em.gap_number = 2
110
+ chart_loc = {}
111
+ for sample in sample_list:
112
+ """ Plot Bivar Chart Column by Column """
113
+ single_attr_bivar_sample = bivar_table.query(f"{varcol} == '{var}' and {sample_col} == '{sample}'")
114
+ single_attr_bivar_sample = get_mean_risk(single_attr_bivar_sample)
115
+
116
+ loc = em.write_duo_chart(worksheet = ws,
117
+ df = single_attr_bivar_sample,
118
+ y1_list = [n_col],
119
+ y2_list = [dep_col],
120
+ x = "indep_range",
121
+ c1_type = "column",
122
+ c2_type = "line",
123
+ y1_axis_range = None,
124
+ y2_axis_range = None,
125
+ title = f"Bivar Plot ({sample.upper()}) for Attribute {var.upper()}",
126
+ chart_size = chart_size,
127
+ xy_axes_name = (var_desc, "N", "Bad Rate"),
128
+ major_gridlines=False,
129
+ retChart = average_risk_line,
130
+ y2_num_format = "0.00%",
131
+ skipby = "col",
132
+ retCellRange="value")
133
+
134
+ if average_risk_line:
135
+
136
+ column_chart = loc[0]
137
+ line_chart = loc[1]
138
+ fnl_line_chart = em.write_chart(worksheet = ws,
139
+ df = single_attr_bivar_sample,
140
+ y_list = ['mean', 'mean_no_nan'],
141
+ x = "indep_range",
142
+ chart_type = "line",
143
+ chart_size = chart_size,
144
+ y_num_format = "0.00%",
145
+ line_type = "long_dash",
146
+ line_marker = "triangle",
147
+ xy_axes_name = (var_desc, "N", "Bad Rate"),
148
+ major_gridlines=False,
149
+ retChart = True,
150
+ y2_axis = True,
151
+ append_to_chart = line_chart)
152
+
153
+ loc = em.write_combined_chart(ws,
154
+ chart1 = column_chart,
155
+ chart2 = fnl_line_chart,
156
+ chart_size = chart_size,
157
+ skipby = "col", retCellRange="value")
158
+ chart_loc[sample] = loc
159
+ loc1 = chart_loc[sample_list[0]]
160
+ em.curr_row = loc1[2] + em.gap_number
161
+ em.curr_col = loc1[1]
162
+ return ws
163
+
164
+
165
+ def add_scr_info(em, ws, data, info, scr_info, sample_prefices, wTitle = True):
166
+ """ Add Score Info Comparison """
167
+ em.gap_number = 0
168
+ title=" "
169
+ if not wTitle:
170
+ title = None
171
+ info_data = data[info].set_index(info[:3])
172
+ info_loc = em.write_dataframe(ws, df=info_data, retCellRange="value", skipby="col", title=title, titleformat="", index = True)
173
+
174
+ i = 0
175
+ while i < len(sample_prefices):
176
+ title=sample_prefices[i].upper().strip("_")
177
+ if not wTitle:
178
+ title = None
179
+ tmp = data[[sample_prefices[i] + x for x in scr_info]]
180
+ tmp.columns = [x.replace(sample_prefices[i], "") for x in tmp.columns]
181
+ loc = em.write_dataframe(ws, df=tmp, retCellRange="value", skipby="col", title=title)
182
+ em.set_cell_format(ws, cell_range=[x + 2 if i == 1 else x for i, x in enumerate(loc)], cformat="NUM%.2")
183
+ i += 1
184
+
185
+ em.curr_col = info_loc[1]
186
+ em.curr_row = loc[2] + 1
187
+ return (info_loc[1], loc[2] + 1)
188
+
189
+ def add_perf_metrics(em, ws, data, info, perf_metrics, sample_prefices, wTitle = True):
190
+ """ Add Perf Metrics Comparison """
191
+ em.gap_number = 0
192
+ title=" "
193
+ if not wTitle:
194
+ title = None
195
+ info_data = data[info].set_index(info[:3])
196
+ info_loc = em.write_dataframe(ws, df=info_data, retCellRange="value", skipby="col", title=title, titleformat="", index = True)
197
+
198
+ i = 0
199
+ while i < len(sample_prefices):
200
+ title=sample_prefices[i].upper().strip("_")
201
+ if not wTitle:
202
+ title = None
203
+ tmp = data[[sample_prefices[i] + x for x in perf_metrics]]
204
+ tmp.columns = [x.replace(sample_prefices[i], "") for x in tmp.columns]
205
+ loc = em.write_dataframe(ws, df=tmp, retCellRange="value", skipby="col", title=title)
206
+ em.set_cell_format(ws, cell_range=[x - 1 if i == 3 else x for i, x in enumerate(loc)], cformat="NUM%.2")
207
+ i += 1
208
+
209
+ em.curr_col = info_loc[1]
210
+ em.curr_row = loc[2] + 1
211
+ return (info_loc[1], loc[2] + 1)
212
+
213
+ def add_perf_lift(em, ws, m2_data, m1_data, info, perf_metrics, sample_prefices, wTitle = True):
214
+ """ Add Performance Lift. """
215
+ em.gap_number = 0
216
+ title=" "
217
+ if not wTitle:
218
+ title = None
219
+
220
+ info_data = m2_data[info]
221
+ info_data[info[0]] = m2_data[info[0]] + " over " + m1_data[info[0]]
222
+ info_data = info_data.set_index(info[:3])
223
+ info_loc = em.write_dataframe(ws, df=info_data, retCellRange="value", skipby="col", title=title, titleformat="", index = True)
224
+
225
+ i = 0
226
+ while i < len(sample_prefices):
227
+
228
+ title=sample_prefices[i].upper().strip("_")
229
+ if not wTitle:
230
+ title = None
231
+
232
+ m2_perf = m2_data[[sample_prefices[i] + x for x in perf_metrics]]
233
+ m2_perf.columns = [x.replace(sample_prefices[i], "") for x in m2_perf.columns]
234
+
235
+ m1_perf = m1_data[[sample_prefices[i] + x for x in perf_metrics]]
236
+ m1_perf.columns = [x.replace(sample_prefices[i], "") for x in m1_perf.columns]
237
+
238
+ perf_lift = (m2_perf/m1_perf) - 1
239
+
240
+ loc = em.write_dataframe(ws, df=perf_lift, retCellRange="value", skipby="col", title=title)
241
+ em.set_cell_format(ws, cell_range=loc, cformat="NUM%.2")
242
+ em.set_data_bar(ws, cell_range=loc)
243
+ i += 1
244
+
245
+ em.curr_col = info_loc[1]
246
+ em.curr_row = loc[2] + 1
247
+ return info_loc
248
+
249
+ def get_seg_perf_comparison_report(em, ws, m1_data, bad, sample_prefices,
250
+ title = "Performance Comparison",
251
+ m2_data = None,
252
+ perf_metrics = ["ks", "top10_cap", "top20_cap", "top40_cap", "auc"],
253
+ nbins=100):
254
+ """ Get Segment Perf Eval Report. """
255
+
256
+ metric_cols = [sample + metric for sample in sample_prefices for metric in perf_metrics]
257
+
258
+ m1_data = input_validation(m1_data)
259
+ m1_data = convert_perc_str_to_float(m1_data, metric_cols)
260
+
261
+ em.gap_number = 0
262
+ em.merge_col(ws, ncols=3, text = title, cformat = "ORANGE_H4")
263
+ em.gap_number = 2
264
+ em.write_text_content(ws, input_text=f"(Gains in {nbins} bins is used.) \n \n")
265
+
266
+ info = [f"{sample_prefices[0]}scr_name", "true_bad", "seg_name", "seg_info"]
267
+ scr_info = ["num_of_total", f"num_of_{bad.lower()}", f"rate_of_{bad.lower()}", "mean_score"]
268
+ fnl_loc = add_scr_info(em, ws, m1_data, info, scr_info, sample_prefices)
269
+
270
+ if m2_data is not None:
271
+ m2_data = input_validation(m2_data)
272
+ m2_data = convert_perc_str_to_float(m2_data, metric_cols)
273
+ fnl_loc = add_scr_info(em, ws, m2_data, info, scr_info, sample_prefices, False)
274
+
275
+ em.curr_col = fnl_loc[0]
276
+ em.curr_row = fnl_loc[1] + 3
277
+
278
+ fnl_loc = add_perf_metrics(em, ws, m1_data, info, perf_metrics, sample_prefices)
279
+
280
+ if m2_data is not None:
281
+ fnl_loc = add_perf_metrics(em, ws, m2_data, info, perf_metrics, sample_prefices, False)
282
+
283
+ em.curr_col = fnl_loc[0]
284
+ em.curr_row = fnl_loc[1] + 3
285
+
286
+ if m2_data is not None:
287
+ info_loc = add_perf_lift(em, ws, m2_data, m1_data, info, perf_metrics, sample_prefices)
288
+ return ws
289
+
290
+
291
+ def get_means_chart_report(em, ws, means_rpt, by_class, varlist, class_name = None,
292
+ stats_list = ['N', 'NMISS', 'MIN', 'MEAN', 'MAX'], inc_miss_rate = True,
293
+ varcol = "variable", attr_info = None):
294
+ """ Plot Means Chart and Get Report. """
295
+ from tqdm import tqdm
296
+
297
+ means_rpt = input_validation(means_rpt)
298
+
299
+ if class_name is None:
300
+ class_name = by_class
301
+
302
+ means_rpt.columns = [x.lower() for x in means_rpt.columns]
303
+ varcol = varcol.lower()
304
+ means_rpt = means_rpt[means_rpt[varcol].isin(varlist)]
305
+
306
+ if inc_miss_rate:
307
+ if "missing_rate" not in means_rpt.columns:
308
+ means_rpt["missing_rate"] = means_rpt["nmiss"]/(means_rpt["n"] + means_rpt["nmiss"])
309
+
310
+ # em.reset_curr_loc()
311
+ em.gap_number = 2
312
+ em.merge_col(ws, ncols = 5, text="Means Chart by Attribute")
313
+
314
+ for var in tqdm(varlist):
315
+ """ By Attribute. """
316
+
317
+ if attr_info is not None:
318
+ em.gap_number = 0
319
+ attr_info_table = input_validation(attr_info)
320
+ singe_attr_info = attr_info_table.query(f"{varcol} == '{var.upper()}'")
321
+ em.write_dataframe(ws, df = singe_attr_info,
322
+ index = False,
323
+ title =f"Information for Attribute {var.upper()}",
324
+ skipby="row", retCellRange="value")
325
+
326
+ em.gap_number = 2
327
+ example = means_rpt[means_rpt[varcol] == var]
328
+ chart_loc = {}
329
+ for stat in stats_list:
330
+ """ By Statistic. """
331
+ em.write_text_content(worksheet=ws, input_text=f"{stat} ({var}) [[ORANGE_H3]] \n")
332
+ example = example.sort_values([by_class.lower()], ascending = True)
333
+
334
+ if inc_miss_rate:
335
+ loc = em.write_duo_chart(ws,
336
+ df = example,
337
+ x = by_class.lower(),
338
+ y1_list=[stat.lower()],
339
+ y2_list = ["missing_rate"],
340
+ title = f"{stat.upper()} for Attribute {var}",
341
+ chart_size=(20, 10),
342
+ c1_type="column",
343
+ c2_type="line",
344
+ y2_num_format = "0.00%",
345
+ major_gridlines=False,
346
+ xy_axes_name=(class_name, stat, "Missing Rate (%)"),
347
+ skipby="col",
348
+ y1_axis_range=None,
349
+ y2_axis_range=None,
350
+ retCellRange="value")
351
+ else:
352
+ loc = em.write_chart(ws,
353
+ df = example,
354
+ x = by_class.lower(),
355
+ y_list=[stat.lower()],
356
+ title = f"{stat.upper()} for Attribute {var}",
357
+ chart_size=(20, 10),
358
+ chart_type="column",
359
+ major_gridlines=False,
360
+ xy_axes_name=(class_name, stat),
361
+ skipby="col",
362
+ y_axis_range=None,
363
+ retCellRange="value")
364
+
365
+ chart_loc[stat] = loc
366
+
367
+ em.curr_row = loc[0] - 1
368
+
369
+ chart1_loc = chart_loc[stats_list[0]]
370
+ em.curr_row = chart1_loc[2] + em.gap_number
371
+ em.curr_col = chart1_loc[1]
372
+
373
+ em.reset_curr_loc()
374
+ return ws
375
+
376
+
377
+ def get_grid_boxplot_report(em, ws, perf_res, hparam_list, metric_list, fontsize = 12, figsize = (30, 13), transp_bg = True, color_grp = (20, 1), colored_box = True):
378
+ """ Plot Boxplots of Grid Search Result for Hyperparams. """
379
+
380
+ em.gap_number = 2
381
+
382
+ em.merge_col(ws, ncols = 5, text="Boxplot For Grid Search Result")
383
+
384
+ chart_loc = {}
385
+ for metric in metric_list:
386
+
387
+ em.write_text_content(worksheet=ws, input_text=f"{metric} [[ORANGE_H3]] \n")
388
+
389
+ for param in hparam_list:
390
+ loc = em.write_boxplot(ws,
391
+ df = perf_res[[param, metric]],
392
+ x = param,
393
+ y = metric,
394
+ y_percentage = True,
395
+ show_fig = False,
396
+ colored_box = True,
397
+ fontsize = fontsize,
398
+ figsize = figsize,
399
+ color_grp = color_grp,
400
+ title= f"Boxplot for {string_proc(param)}",
401
+ transp_bg = transp_bg,
402
+ skipby = "col",
403
+ retCellRange = "value")
404
+
405
+ chart_loc[param] = loc
406
+
407
+ chart1_loc = chart_loc[hparam_list[0]]
408
+ em.curr_row = chart1_loc[2] + em.gap_number
409
+ em.curr_col = chart1_loc[1]
410
+
411
+ return ws
412
+
413
+
414
+ def get_var_reduct_report(em, ws, vr_perf, metric_cols, target_metrics = None, basic_info_text = None, nvars_col = "nvars"):
415
+ """ Generate Variable Reduction Excel Report. """
416
+
417
+ if target_metrics is None:
418
+ target_metrics = metric_cols
419
+
420
+ nvars_col = nvars_col.lower()
421
+
422
+ vr_perf = input_validation(vr_perf)
423
+ vr_perf = convert_perc_str_to_float(vr_perf, metric_cols)
424
+ res = get_metrics_shift(vr_perf, [x for x in metric_cols if x in target_metrics])
425
+
426
+ shift_cols = [y + "_shift" for y in metric_cols]
427
+
428
+ all_metric_cols = metric_cols + shift_cols
429
+ info_table = vr_perf[[x for x in vr_perf.columns if x not in all_metric_cols]]
430
+ metrics_table = vr_perf[[x for x in vr_perf.columns if x in metric_cols]]
431
+ shift_table = vr_perf[[x for x in vr_perf.columns if x in shift_cols]]
432
+
433
+ em.write_text_content(ws, input_text="{#} Variable Reduction Report \n")
434
+
435
+ if basic_info_text:
436
+ em.write_text_content(ws, input_text=basic_info_text)
437
+
438
+ em.gap_number = 0
439
+ info_loc = em.write_dataframe(ws, df=info_table, title = "Model Information", header = True, index = False, retCellRange="value", skipby="col")
440
+ perf_loc = em.write_dataframe(ws, df=metrics_table, title = "Variable Reduction Performance", header = True, index = False, retCellRange="value", skipby="col")
441
+ shift_loc = em.write_dataframe(ws, df=shift_table, title = "Performance Shift", header = True, index = False, retCellRange="value", skipby="row")
442
+
443
+ em.set_cell_format(ws, perf_loc, cformat="NUM%.2")
444
+ em.set_cell_format(ws, shift_loc, cformat="NUM%.2")
445
+ em.set_data_bar(ws, shift_loc)
446
+
447
+ em.gap_number = 2
448
+ chart_start_loc = (info_loc[2] + em.gap_number, info_loc[1])
449
+ # print(chart_start_loc)
450
+ em.reset_curr_loc(loc = chart_start_loc)
451
+
452
+ i = 0
453
+ chart_loc = []
454
+ while i < len(target_metrics):
455
+
456
+ metric = target_metrics[i]
457
+ logger.info(metric)
458
+
459
+ loc = em.write_duo_chart(worksheet = ws,
460
+ df = res,
461
+ y1_list = [metric],
462
+ y2_list = [metric + '_shift'],
463
+ x = nvars_col,
464
+ c1_type = "line",
465
+ c2_type = "line",
466
+ y1_axis_range = None,
467
+ y2_axis_range = None,
468
+ title = metric,
469
+ chart_size = (20, 10),
470
+ xy_axes_name = ("Nvars", metric, metric + '_shift'),
471
+ major_gridlines=False,
472
+ retChart = False,
473
+ retCellRange = "value",
474
+ skipby = "col",
475
+ y1_num_format = "0.00%",
476
+ y2_num_format = "0.00%")
477
+
478
+ chart_loc.append(loc)
479
+ # print(loc)
480
+
481
+ if (i != 0) and (i % 2 == 1):
482
+ reset_loc = (chart_loc[i][2] + em.gap_number, chart_loc[0][1])
483
+ # print(reset_loc)
484
+ em.reset_curr_loc(loc = reset_loc)
485
+
486
+ i += 1
487
+ # print(chart_loc)
488
+ return ws
489
+
490
+
491
+ def get_grid_search_report(em, ws, rs_perf, metric_cols, sample_prefices, basic_info_text = None, sortby = "hd_auc"):
492
+ """ Get Grid Search Report. """
493
+ rs_perf = input_validation(rs_perf)
494
+ rs_perf = convert_perc_str_to_float(rs_perf, metric_cols)
495
+
496
+ if sortby:
497
+ rs_perf = rs_perf.sort_values([sortby], ascending = False)
498
+
499
+ i = 1
500
+ while i <= len(sample_prefices) - 1:
501
+ rs_perf = compute_overfitting_shift(rs_perf, (sample_prefices[0], sample_prefices[i]))
502
+ i += 1
503
+
504
+ shift_cols = [x for x in rs_perf.columns if x.endswith("_shift")]
505
+
506
+ all_metric_cols = metric_cols + shift_cols
507
+ info_table = rs_perf[[x for x in rs_perf.columns if x not in all_metric_cols]]
508
+ metrics_table = rs_perf[[x for x in rs_perf.columns if x in metric_cols]]
509
+ shift_table = rs_perf[[x for x in rs_perf.columns if x in shift_cols]]
510
+
511
+ em.write_text_content(ws, input_text="{#} Grid Search Report \n")
512
+
513
+ if basic_info_text:
514
+ em.write_text_content(ws, input_text=basic_info_text)
515
+
516
+ em.gap_number = 0
517
+ info_loc = em.write_dataframe(ws, df=info_table, title = "Model Information", header = True, index = False, retCellRange="value", skipby="col")
518
+ perf_loc = em.write_dataframe(ws, df=metrics_table, title = "Grid Search Performance", header = True, index = False, retCellRange="value", skipby="col")
519
+ shift_loc = em.write_dataframe(ws, df=shift_table, title = "Overfitting Performance Shift", header = True, index = False, retCellRange="value", skipby="row")
520
+
521
+ em.set_cell_format(ws, perf_loc, cformat="NUM%.2")
522
+ em.set_cell_format(ws, shift_loc, cformat="NUM%.2")
523
+ em.set_data_bar(ws, shift_loc)
524
+
525
+ return ws