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,762 @@
1
+ """
2
+ 变量提取与相关性分析工具包
3
+ 提供变量分析、IV计算、WOE绑图和相关性过滤功能
4
+ """
5
+
6
+ import pandas as pd
7
+ from tqdm import tqdm
8
+
9
+ from .Distribution_Tool import proc_means_by_grp
10
+ import logging
11
+ logger = logging.getLogger(__name__)
12
+
13
+ class VarExtractionInsights:
14
+ """变量提取与洞察分析器。
15
+ 用于对数据集进行变量分析,计算IV值、WOE分箱,
16
+ 并支持可视化绑图和变量筛选。
17
+
18
+ Parameters
19
+ ----------
20
+ data : pd.DataFrame
21
+ 输入的原始数据框
22
+ dep : str
23
+ 目标变量(因变量)列名
24
+ plot_path : str
25
+ 绑图保存路径
26
+ nbins : int, optional
27
+ 分箱数量,默认为10
28
+ equal_freq : bool, optional
29
+ 是否使用等频分箱,默认为True
30
+ min_bin_prop : float, optional
31
+ 每个分箱的最小样本比例,默认为0.05
32
+ precision : int, optional
33
+ WOE和IV计算精度,默认为5
34
+ chi2_method : bool, optional
35
+ 是否使用卡方分箱方法,默认为False
36
+ chi2_p : float, optional
37
+ 卡方检验的p值阈值,默认为0.9
38
+ init_equi_bins : int, optional
39
+ 初始等频分箱数量,默认为5000
40
+ tree_binning : bool, optional
41
+ 是否使用决策树分箱,默认为True
42
+ include_missing : bool, optional
43
+ 是否将缺失值作为单独分箱,默认为True
44
+ seed : int, optional
45
+ 随机种子,默认为3407
46
+ missing_rate_ref : int/float, optional
47
+ 缺失值填充参考值,默认为-999999
48
+ spec_values : list, optional
49
+ 特殊值列表,默认为空列表
50
+
51
+ Examples
52
+ --------
53
+ >>> analyzer = VarExtractionInsights(df, 'target', '/path/to/plots')
54
+ >>> report = analyzer.get_var_analysis_report(df, ['var1', 'var2'])
55
+ """
56
+
57
+ def __init__(self, data, dep, plot_path,
58
+ nbins=10, equal_freq=True, min_bin_prop=0.05, precision=5, chi2_method=False, chi2_p=0.9,
59
+ init_equi_bins=5000, tree_binning=True, include_missing=True, seed=3407, missing_rate_ref=-999999, spec_values=None):
60
+ """初始化变量提取与洞察分析器。
61
+
62
+ Parameters
63
+ ----------
64
+ data : pd.DataFrame
65
+ 输入的原始数据框
66
+ dep : str
67
+ 目标变量(因变量)列名
68
+ plot_path : str
69
+ 绑图保存路径
70
+ nbins : int, optional
71
+ 分箱数量
72
+ equal_freq : bool, optional
73
+ 是否使用等频分箱
74
+ min_bin_prop : float, optional
75
+ 每个分箱的最小样本比例
76
+ precision : int, optional
77
+ WOE和IV计算精度
78
+ chi2_method : bool, optional
79
+ 是否使用卡方分箱方法
80
+ chi2_p : float, optional
81
+ 卡方检验的p值阈值
82
+ init_equi_bins : int, optional
83
+ 初始等频分箱数量
84
+ tree_binning : bool, optional
85
+ 是否使用决策树分箱
86
+ include_missing : bool, optional
87
+ 是否将缺失值作为单独分箱
88
+ seed : int, optional
89
+ 随机种子
90
+ missing_rate_ref : int/float, optional
91
+ 缺失值填充参考值
92
+ spec_values : list, optional
93
+ 特殊值列表
94
+ """
95
+ self.data = data
96
+ self.dep = dep
97
+ self.plot_path = plot_path
98
+
99
+ self.nbins = nbins
100
+ self.equal_freq = equal_freq
101
+ self.min_bin_prop = min_bin_prop
102
+ self.precision = precision
103
+ self.chi2_method = chi2_method
104
+ self.chi2_p = chi2_p
105
+ self.init_equi_bins = init_equi_bins
106
+ self.tree_binning = tree_binning
107
+ self.include_missing = include_missing
108
+ self.seed = seed
109
+ self.missing_rate_ref = missing_rate_ref
110
+ self.spec_values = spec_values if spec_values is not None else []
111
+
112
+ @staticmethod
113
+ def remove_folder(file_path):
114
+ """删除指定文件夹。
115
+
116
+ 递归删除指定路径的文件夹及其所有内容,
117
+ 如果文件夹不存在则静默处理。
118
+
119
+ Parameters
120
+ ----------
121
+ file_path : str
122
+ 要删除的文件夹路径
123
+
124
+ Examples
125
+ --------
126
+ >>> VarExtractionInsights.remove_folder('/path/to/folder')
127
+ """
128
+ import shutil
129
+ try:
130
+ shutil.rmtree(file_path)
131
+ except Exception:
132
+ pass
133
+
134
+ def get_var_analysis_report(self, data, varlist, dep=None, iv_cut=0.01):
135
+ """生成变量分析报告。
136
+
137
+ 对指定变量列表计算IV值、KS值、Lift值等指标,
138
+ 并返回满足IV阈值的变量分析汇总结果。
139
+
140
+ Parameters
141
+ ----------
142
+ data : pd.DataFrame
143
+ 输入的原始数据框
144
+ varlist : list
145
+ 待分析的变量名列表
146
+ dep : str, optional
147
+ 目标变量列名,默认为None(使用初始化时的dep)
148
+ iv_cut : float, optional
149
+ IV值筛选阈值,默认为0.01
150
+
151
+ Returns
152
+ -------
153
+ pd.DataFrame
154
+ 包含变量分析结果的汇总表,包括:
155
+ - var: 变量名
156
+ - n_all: 总样本数
157
+ - n: 非缺失样本数
158
+ - ks_in_gains: KS统计量
159
+ - lift_in_gains: Lift值
160
+ - iv: IV值
161
+ - n_bump: 分箱数量
162
+ - missing_rate: 缺失率
163
+ - min, mean, max: 统计量
164
+ - n_bins: 分箱数
165
+
166
+ Examples
167
+ --------
168
+ >>> analyzer = VarExtractionInsights(df, 'target', '/path/to/plots')
169
+ >>> report = analyzer.get_var_analysis_report(df, ['var1', 'var2'])
170
+ """
171
+ if dep is None:
172
+ dep = self.dep
173
+
174
+ from Modeling_Tool.Eval.Model_Eval_Tool import get_gains_table
175
+
176
+ iv_info_res = []
177
+ for var in tqdm(varlist):
178
+ if data[var].nunique() > 1:
179
+ try:
180
+ attr_iv = get_gains_table(
181
+ data=data,
182
+ dep=self.dep,
183
+ nbins=self.nbins,
184
+ precision=self.precision,
185
+ min_bin_prop=self.min_bin_prop,
186
+ include_missing=self.include_missing,
187
+ score=var,
188
+ equal_freq=self.equal_freq,
189
+ chi2_method=self.chi2_method,
190
+ chi2_p=self.chi2_p,
191
+ init_equi_bins=self.init_equi_bins,
192
+ fillna=self.missing_rate_ref,
193
+ spec_values=self.spec_values,
194
+ retSummary=True,
195
+ tree_binning=self.tree_binning,
196
+ random_state=self.seed,
197
+ ascending=True,
198
+ )
199
+
200
+ attr_iv['var'] = var
201
+ iv_info_res.append(attr_iv)
202
+
203
+ except TypeError:
204
+ continue
205
+
206
+ iv_info_res = pd.concat(iv_info_res).sort_values("IV", ascending=False)
207
+
208
+ high_iv_summary = iv_info_res.query(f"IV >= {iv_cut}").round(4)
209
+ high_iv_varlist = high_iv_summary['var'].tolist()
210
+
211
+ means = proc_means_by_grp(data, high_iv_varlist, spec_missing_value=self.missing_rate_ref)
212
+
213
+ if len(high_iv_varlist) == 0:
214
+ logger.info(f"WARNING: No variable with IV >= {iv_cut}")
215
+ means = means.rename(columns={"index": "attribute"})
216
+
217
+ fnl_summary = high_iv_summary.merge(
218
+ means[['attribute', 'N_ALL', 'N', 'MISSING_RATE', 'MIN', 'MEAN', 'MAX']],
219
+ left_on=['var'],
220
+ right_on=['attribute'],
221
+ how='left'
222
+ )
223
+ fnl_summary.columns = [x.lower() for x in fnl_summary.columns]
224
+ fnl_summary = fnl_summary[[
225
+ 'var', 'n_all', 'n', 'ks_in_gains', 'lift_in_gains', 'iv',
226
+ 'n_bump', 'missing_rate', 'min', 'mean', 'max', 'n_bins'
227
+ ]]
228
+
229
+ return fnl_summary
230
+
231
+ def plot_woe(self, data, varlist, plot_group=None, plot_dirname="var_analysis_plot", plot_path=None):
232
+ """绑制WOE分布图。
233
+
234
+ 对指定变量列表计算WOE值并绑制分布图,
235
+ 保存到指定目录。
236
+
237
+ Parameters
238
+ ----------
239
+ data : pd.DataFrame
240
+ 输入的原始数据框
241
+ varlist : list
242
+ 待绑图的变量名列表
243
+ plot_group : str, optional
244
+ 分组变量名,默认为None
245
+ plot_dirname : str, optional
246
+ 绑图保存子目录名,默认为"var_analysis_plot"
247
+ plot_path : str, optional
248
+ 绑图保存根路径,默认为None(使用初始化时的plot_path)
249
+
250
+ Returns
251
+ -------
252
+ None
253
+
254
+ Examples
255
+ --------
256
+ >>> analyzer = VarExtractionInsights(df, 'target', '/path/to/plots')
257
+ >>> analyzer.plot_woe(df, ['var1', 'var2'])
258
+ """
259
+
260
+ if plot_path is None:
261
+ plot_path = self.plot_path
262
+
263
+ from Modeling_Tool.WOE.WOE_Master import WOE_Master
264
+
265
+ # Fill Missing Value.
266
+ drv_fillna = data.copy()
267
+ drv_fillna[varlist] = drv_fillna[varlist].fillna(self.missing_rate_ref)
268
+
269
+ woe_master = WOE_Master(
270
+ train_data=drv_fillna,
271
+ varlist=varlist,
272
+ dep=self.dep,
273
+ graph_save_dir=plot_path
274
+ )
275
+
276
+ woe_master.fit(
277
+ nbins=self.nbins,
278
+ equal_freq=self.equal_freq,
279
+ min_bin_prop=self.min_bin_prop,
280
+ precision=self.precision,
281
+ chi2_config=(self.init_equi_bins, self.chi2_p) if self.chi2_method else None,
282
+ tree_binning_seed=self.seed if self.tree_binning else None,
283
+ include_missing=self.include_missing,
284
+ spec_values=self.spec_values
285
+ )
286
+
287
+ train_woe = woe_master.transform(drv_fillna)
288
+ woe_master.plot_bivar_graph(train_woe, group=plot_group, dirname=plot_dirname)
289
+
290
+
291
+
292
+
293
+ def var_corr_filter(data, varlist, corr_cutpoint=0.8, method='pearson'):
294
+ """筛选高相关变量对。
295
+
296
+ 计算变量间的相关系数,返回超过阈值的高相关变量对列表。
297
+
298
+ Parameters
299
+ ----------
300
+ data : pd.DataFrame
301
+ 输入的数据框
302
+ varlist : list
303
+ 待筛选的变量名列表
304
+ corr_cutpoint : float, optional
305
+ 相关系数阈值,默认为0.8
306
+ method : str, optional
307
+ 相关系数计算方法,可选'pearson'、'spearman'、'kendall',
308
+ 默认为'pearson'
309
+
310
+ Returns
311
+ -------
312
+ pd.DataFrame
313
+ 包含高相关变量对的数据框,包括:
314
+ - VAR1: 变量1
315
+ - VAR2: 变量2
316
+ - CORR: 相关系数
317
+
318
+ Examples
319
+ --------
320
+ >>> high_corr = var_corr_filter(df, ['var1', 'var2', 'var3'], corr_cutpoint=0.8)
321
+ """
322
+ import numpy as np
323
+
324
+ corr_matrix = data[varlist].corr(method=method)
325
+
326
+ corr_list = []
327
+ for i in range(len(varlist)):
328
+ for j in range(i + 1, len(varlist)):
329
+ var1, var2 = varlist[i], varlist[j]
330
+ corr_value = corr_matrix.iloc[i, j]
331
+ if abs(corr_value) > corr_cutpoint:
332
+ corr_list.append({
333
+ 'VAR1': var1,
334
+ 'VAR2': var2,
335
+ 'CORR': corr_value
336
+ })
337
+
338
+ return pd.DataFrame(corr_list)
339
+
340
+
341
+
342
+ class CorrelationFilter:
343
+ """相关性过滤分析器。
344
+
345
+ 提供基于相关性分析的高相关变量筛选和去除功能,
346
+ 支持IV值对比和迭代筛选。
347
+
348
+ Parameters
349
+ ----------
350
+ data : pd.DataFrame
351
+ 输入的原始数据框
352
+ dep : str
353
+ 目标变量(因变量)列名
354
+ corr_cutpoint : float, optional
355
+ 相关系数阈值,超过该值的变量对将被筛选,默认为0.8
356
+ method : str, optional
357
+ 相关系数计算方法,可选'pearson'、'spearman'、'kendall',默认为'pearson'
358
+
359
+ Examples
360
+ --------
361
+ >>> filter_analyzer = CorrelationFilter(df, 'target')
362
+ >>> keep_vars = filter_analyzer.remove_highly_correlated(['var1', 'var2'])
363
+ """
364
+
365
+ def __init__(self, data, dep, corr_cutpoint=0.8, method='pearson', tree_binning=False, chi2_method=False, seed = 42, chi2_p =0.999, init_equi_bins = 1000,
366
+ missing_rate_ref = -9999999, spec_values = [], base_metric = 'iv'):
367
+ """初始化相关性过滤分析器。
368
+
369
+ Parameters
370
+ ----------
371
+ data : pd.DataFrame
372
+ 输入的原始数据框
373
+ dep : str
374
+ 目标变量(因变量)列名
375
+ corr_cutpoint : float, optional
376
+ 相关系数阈值
377
+ method : str, optional
378
+ 相关系数计算方法
379
+ tree_binning_seed : int, optional
380
+ 决策树分箱随机种子
381
+ chi2_config : tuple, optional
382
+ 卡方分箱配置
383
+ """
384
+ self.data = data
385
+ self.dep = dep
386
+ self.corr_cutpoint = corr_cutpoint
387
+ self.method = method
388
+ self.tree_binning = tree_binning
389
+ self.chi2_method = chi2_method
390
+ self.seed = seed
391
+ self.chi2_p = chi2_p
392
+ self.init_equi_bins = init_equi_bins
393
+ self.missing_rate_ref = missing_rate_ref
394
+ self.spec_values = spec_values
395
+ self.base_metric = base_metric
396
+
397
+ self.correlated_dict = {}
398
+ self.filtered_varlist = []
399
+
400
+ def filter_single_iteration(self, varlist):
401
+ """单次迭代过滤高相关变量。
402
+
403
+ 对变量列表执行一次相关性过滤,保留IV值最高的变量。
404
+
405
+ Parameters
406
+ ----------
407
+ varlist : list
408
+ 待筛选的变量名列表
409
+
410
+ Returns
411
+ -------
412
+ list
413
+ 筛选后保留的变量名列表
414
+ """
415
+ base_metric = self.base_metric.lower()
416
+
417
+ name_mapping = {
418
+ "iv": "iv",
419
+ "ks": "ks_in_gains"
420
+ }
421
+
422
+ high_corr_var = var_corr_filter(
423
+ self.data, varlist,
424
+ corr_cutpoint=self.corr_cutpoint,
425
+ method=self.method
426
+ )
427
+
428
+ if len(high_corr_var) == 0:
429
+ return varlist
430
+
431
+ base_varlist = high_corr_var['VAR1'].drop_duplicates().tolist()
432
+
433
+ correlated_dict = self.correlated_dict
434
+ selected_varlist = []
435
+ removed_varlist = []
436
+ for var in tqdm(base_varlist):
437
+ if var not in set(removed_varlist + selected_varlist):
438
+ single_var_corr = high_corr_var.query(f""" VAR1 == '{var}'""")
439
+ correlated_list = [var] + single_var_corr['VAR2'].drop_duplicates().tolist()
440
+
441
+ varInsights = VarExtractionInsights(data = self.data,
442
+ dep = self.dep,
443
+ plot_path = None,
444
+ nbins = 10,
445
+ equal_freq = True,
446
+ min_bin_prop = 0.05,
447
+ precision = 5,
448
+ chi2_method = self.chi2_method,
449
+ chi2_p = self.chi2_p,
450
+ init_equi_bins = self.init_equi_bins,
451
+ tree_binning = self.tree_binning,
452
+ include_missing = True,
453
+ seed = self.seed,
454
+ missing_rate_ref = self.missing_rate_ref)
455
+
456
+ fnl_summary = varInsights.get_var_analysis_report(data = self.data, varlist = correlated_list, dep = self.dep, iv_cut = 0)
457
+ fnl_selected_var = fnl_summary.sort_values([name_mapping[base_metric]], ascending = False)['var'][0]
458
+
459
+ if fnl_selected_var not in selected_varlist:
460
+ selected_varlist.append(fnl_selected_var)
461
+
462
+ removed_varlist += [x for x in correlated_list if x != fnl_selected_var and x not in removed_varlist]
463
+
464
+ if var not in correlated_dict:
465
+ correlated_dict[var] = {}
466
+ correlated_dict[var]['corr'] = single_var_corr
467
+ correlated_dict[var]['gains'] = fnl_summary
468
+ else:
469
+ correlated_dict[var]['corr'] = pd.concat([correlated_dict[var]['corr'], single_var_corr]).drop_duplicates()
470
+ correlated_dict[var]['gains'] = pd.concat([correlated_dict[var]['gains'], fnl_summary]).drop_duplicates()
471
+
472
+ other_varlist = [x for x in varlist if x not in (selected_varlist + removed_varlist)]
473
+ fnl_keep_varlist = selected_varlist + other_varlist
474
+
475
+ self.correlated_dict = correlated_dict
476
+
477
+ return fnl_keep_varlist
478
+
479
+ def remove_highly_correlated(self, varlist, max_iterations=10):
480
+ """迭代去除高相关变量。
481
+
482
+ 反复执行相关性过滤,直到没有变量被移除或达到最大迭代次数。
483
+
484
+ Parameters
485
+ ----------
486
+ varlist : list
487
+ 待筛选的变量名列表
488
+ max_iterations : int, optional
489
+ 最大迭代次数,默认为10
490
+
491
+ Returns
492
+ -------
493
+ list
494
+ 最终保留的变量名列表
495
+
496
+ Examples
497
+ --------
498
+ >>> filter_analyzer = CorrelationFilter(df, 'target')
499
+ >>> keep_vars = filter_analyzer.remove_highly_correlated(['var1', 'var2', 'var3'])
500
+ """
501
+ last_keep_list = self.filter_single_iteration(varlist)
502
+
503
+ for i in range(1, max_iterations):
504
+ fnl_keep_list = self.filter_single_iteration(last_keep_list)
505
+
506
+ removed_vars = [x for x in last_keep_list if x not in fnl_keep_list]
507
+ self.filtered_varlist.append(removed_vars)
508
+ if len(removed_vars) == 0:
509
+ break
510
+
511
+ last_keep_list = fnl_keep_list
512
+
513
+ self.filtered_varlist = [x for x in varlist if x not in last_keep_list]
514
+ return last_keep_list
515
+
516
+
517
+ @staticmethod
518
+ def calculate_vif(df):
519
+ """计算方差膨胀因子(VIF)。
520
+
521
+ 用于检测多重共线性问题,返回各变量的VIF值。
522
+ VIF值越大表示共线性越严重,通常VIF > 10表示存在严重共线性。
523
+
524
+ Parameters
525
+ ----------
526
+ df : pd.DataFrame
527
+ 包含自变量的数据框
528
+
529
+ Returns
530
+ -------
531
+ pd.DataFrame
532
+ 包含以下列的数据框:
533
+ - index: 变量名
534
+ - VIF: 方差膨胀因子值
535
+
536
+ Examples
537
+ --------
538
+ >>> vif_result = calculate_vif(X_train)
539
+ >>> high_vif_vars = vif_result[vif_result['VIF'] > 10]['index'].tolist()
540
+ """
541
+ from statsmodels.stats.outliers_influence import variance_inflation_factor
542
+
543
+ vif = pd.DataFrame()
544
+ vif['index'] = df.columns
545
+ vif['VIF'] = [variance_inflation_factor(df.values, i) for i in range(df.shape[1])]
546
+ return vif
547
+
548
+
549
+
550
+
551
+
552
+
553
+
554
+
555
+
556
+
557
+
558
+
559
+
560
+
561
+
562
+
563
+
564
+
565
+
566
+
567
+
568
+
569
+
570
+ # def var_corr_filter(data, varlist, corr_cutpoint=0.8, method='pearson', woe_mapping_table=None, suffix='_woe', ret_winner_var=False):
571
+ # """筛选高相关变量对。
572
+
573
+ # 计算变量间的相关性矩阵,返回超过指定阈值的高相关变量对。
574
+ # 支持基于IV值确定每对中的优质变量。
575
+
576
+ # Parameters
577
+ # ----------
578
+ # data : pd.DataFrame
579
+ # 输入的原始数据框
580
+ # varlist : list
581
+ # 待分析的变量名列表
582
+ # corr_cutpoint : float, optional
583
+ # 相关系数阈值,默认为0.8
584
+ # method : str, optional
585
+ # 相关系数计算方法,默认为'pearson',
586
+ # 可选'pearson'、'spearman'、'kendall'
587
+ # woe_mapping_table : pd.DataFrame, optional
588
+ # WOE映射表,包含VAR和IV列,默认为None
589
+ # suffix : str, optional
590
+ # WOE变量后缀,默认为'_woe'
591
+ # ret_winner_var : bool, optional
592
+ # 是否返回每对中的优质变量,默认为False
593
+
594
+ # Returns
595
+ # -------
596
+ # pd.DataFrame
597
+ # 包含高相关变量对的数据框,列包括:
598
+ # - VAR1: 变量1
599
+ # - VAR2: 变量2
600
+ # - CORR: 相关系数
601
+ # - var1_iv, var2_iv: 变量IV值(当woe_mapping_table不为None时)
602
+ # - winner: 优质变量名(当ret_winner_var=True时)
603
+
604
+ # Examples
605
+ # --------
606
+ # >>> high_corr = var_corr_filter(df, ['var1', 'var2', 'var3'])
607
+ # """
608
+ # corr_matrix = data[varlist].corr(method=method)
609
+ # corr_melt = corr_matrix.reset_index(drop=False).melt(
610
+ # id_vars=["index"],
611
+ # value_vars=[x for x in corr_matrix.columns if x != 'index']
612
+ # )
613
+ # corr_melt = corr_melt.query("index != variable")
614
+
615
+ # if woe_mapping_table is not None:
616
+ # iv_res = woe_mapping_table.groupby(["VAR"]).agg({"IV": "sum"}).reset_index()
617
+ # iv_mapping = dict(zip(iv_res['VAR'], iv_res['IV']))
618
+ # iv_mapping = {k + suffix: v for k, v in iv_mapping.items()}
619
+ # corr_melt["var1_iv"] = corr_melt["index"].map(iv_mapping)
620
+ # corr_melt["var2_iv"] = corr_melt["variable"].map(iv_mapping)
621
+
622
+ # if ret_winner_var:
623
+ # winner_var = corr_melt.apply(
624
+ # lambda row: row[row[['var1_iv', 'var2_iv']].argmax()],
625
+ # axis=1
626
+ # )
627
+ # corr_melt['winner'] = winner_var
628
+
629
+ # corr_melt = corr_melt.query(f"value > {corr_cutpoint}")
630
+
631
+ # # Drop Duplicate Comparison
632
+ # corr_melt['compare_set'] = corr_melt.apply(
633
+ # lambda x: sorted([x['index'], x['variable']]),
634
+ # axis=1
635
+ # )
636
+ # corr_melt = corr_melt.drop_duplicates(subset=['compare_set'], keep='first')
637
+ # corr_melt = corr_melt.drop(columns=['compare_set'])
638
+
639
+ # # Rename Colnames
640
+ # corr_melt.columns = ['VAR1', 'VAR2', 'CORR']
641
+ # return corr_melt.sort_values(["CORR"], ascending=False).reset_index(drop=True)
642
+
643
+
644
+
645
+
646
+ # def remove_corr_var(data, varlist, dep, corr_cutpoint=0.8, method='pearson', tree_binning_seed=None, chi2_config=None):
647
+ # """单次迭代去除高相关变量。
648
+
649
+ # 对变量列表执行一次相关性过滤,基于IV值保留最优质的变量。
650
+
651
+ # Parameters
652
+ # ----------
653
+ # data : pd.DataFrame
654
+ # 输入的原始数据框
655
+ # varlist : list
656
+ # 待筛选的变量名列表
657
+ # dep : str
658
+ # 目标变量(因变量)列名
659
+ # corr_cutpoint : float, optional
660
+ # 相关系数阈值,默认为0.8
661
+ # method : str, optional
662
+ # 相关系数计算方法,默认为'pearson'
663
+ # tree_binning_seed : int, optional
664
+ # 决策树分箱随机种子,默认为None
665
+ # chi2_config : tuple, optional
666
+ # 卡方分箱配置,(init_bins, p_value)元组,默认为None
667
+
668
+ # Returns
669
+ # -------
670
+ # list
671
+ # 筛选后保留的变量名列表
672
+
673
+ # Examples
674
+ # --------
675
+ # >>> keep_vars = remove_corr_var(df, ['var1', 'var2', 'var3'], 'target')
676
+ # """
677
+ # high_corr_var = var_corr_filter(
678
+ # data, varlist,
679
+ # corr_cutpoint=corr_cutpoint,
680
+ # method=method
681
+ # )
682
+ # base_varlist = high_corr_var['VAR1'].drop_duplicates().tolist()
683
+
684
+ # selected_varlist = []
685
+ # removed_varlist = []
686
+ # for var in tqdm(base_varlist):
687
+ # if var not in set(removed_varlist + selected_varlist):
688
+ # single_var_corr = high_corr_var.query(f""" VAR1 == '{var}'""")
689
+ # correlated_list = [var] + single_var_corr['VAR2'].drop_duplicates().tolist()
690
+
691
+ # iv_res = woe_transformation(
692
+ # train_df=data,
693
+ # varlist=correlated_list,
694
+ # dep=dep,
695
+ # oot_df=None,
696
+ # nbins=10,
697
+ # chi2_config=chi2_config,
698
+ # tree_binning_seed=tree_binning_seed,
699
+ # precision=5,
700
+ # min_bin_prop=0.05,
701
+ # include_missing=False,
702
+ # equal_freq=True,
703
+ # fillna=-999999,
704
+ # spec_values=[],
705
+ # drop_bin_info=True,
706
+ # ret_woe_table=True
707
+ # )[1].groupby(["VAR"]).agg({"IV": "sum"})
708
+ # fnl_selected_var = iv_res.reset_index().max()['VAR']
709
+
710
+ # if fnl_selected_var not in selected_varlist:
711
+ # selected_varlist.append(fnl_selected_var)
712
+
713
+ # removed_varlist += [x for x in correlated_list if x != fnl_selected_var and x not in removed_varlist]
714
+
715
+ # other_varlist = [x for x in varlist if x not in (selected_varlist + removed_varlist)]
716
+ # fnl_keep_varlist = selected_varlist + other_varlist
717
+
718
+ # return fnl_keep_varlist
719
+
720
+
721
+ # def remove_correlated_vars(data, varlist, dep, corr_cutpoint=0.8, method='pearson', tree_binning_seed=None, chi2_config=None):
722
+ # """迭代去除高相关变量。
723
+
724
+ # 反复执行相关性过滤操作,直到没有变量被移除或达到最大迭代次数。
725
+ # 基于IV值在每组高相关变量中保留最优质的变量。
726
+
727
+ # Parameters
728
+ # ----------
729
+ # data : pd.DataFrame
730
+ # 输入的原始数据框
731
+ # varlist : list
732
+ # 待筛选的变量名列表
733
+ # dep : str
734
+ # 目标变量(因变量)列名
735
+ # corr_cutpoint : float, optional
736
+ # 相关系数阈值,默认为0.8
737
+ # method : str, optional
738
+ # 相关系数计算方法,默认为'pearson'
739
+ # tree_binning_seed : int, optional
740
+ # 决策树分箱随机种子,默认为None
741
+ # chi2_config : tuple, optional
742
+ # 卡方分箱配置,(init_bins, p_value)元组,默认为None
743
+
744
+ # Returns
745
+ # -------
746
+ # list
747
+ # 最终保留的变量名列表
748
+
749
+ # Examples
750
+ # --------
751
+ # >>> keep_vars = remove_correlated_vars(df, ['var1', 'var2', 'var3'], 'target')
752
+ # """
753
+ # filter_analyzer = CorrelationFilter(
754
+ # data, dep,
755
+ # corr_cutpoint=corr_cutpoint,
756
+ # method=method,
757
+ # tree_binning_seed=tree_binning_seed,
758
+ # chi2_config=chi2_config
759
+ # )
760
+ # return filter_analyzer.remove_highly_correlated(varlist)
761
+
762
+