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
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
"""
|
|
3
|
+
Model explainability sub-package.
|
|
4
|
+
|
|
5
|
+
Provides :class:`ModelExplainer`, a unified wrapper for models trained by
|
|
6
|
+
SuperModelingFactory (``GradientBoostingModel`` and ``LRMaster``) as well as raw
|
|
7
|
+
fitted estimators. It supports SHAP attribution, Owen Value grouped attribution,
|
|
8
|
+
plus PDP, ICE, ALE, and LIME explanations from one entry point.
|
|
9
|
+
|
|
10
|
+
``shap`` and ``lime`` are optional dependencies imported lazily on first use;
|
|
11
|
+
install them via ``pip install supermodelingfactory[explain]``. Owen Value uses
|
|
12
|
+
SHAP's PartitionExplainer under the same explainability extra.
|
|
13
|
+
|
|
14
|
+
Examples
|
|
15
|
+
--------
|
|
16
|
+
>>> from Modeling_Tool.Explainability import ModelExplainer
|
|
17
|
+
>>> exp = ModelExplainer(gbm)
|
|
18
|
+
>>> exp.feature_importance(test_X).head()
|
|
19
|
+
>>> exp.partial_dependence(test_X, feature='age_woe').head()
|
|
20
|
+
"""
|
|
21
|
+
from .Coalition_Structure import CREDIT_PRIOR_GROUPS, build_coalition_structure
|
|
22
|
+
from .Model_Explainer import ModelExplainer
|
|
23
|
+
|
|
24
|
+
__all__ = ["ModelExplainer", "build_coalition_structure", "CREDIT_PRIOR_GROUPS"]
|
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
"""
|
|
2
|
+
数据处理与分析工具包
|
|
3
|
+
提供分组统计、分布分析和可视化功能
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
import pandas as pd
|
|
8
|
+
import seaborn as sns
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
|
|
11
|
+
class proc_means:
|
|
12
|
+
""" Proc Means by Group.
|
|
13
|
+
|
|
14
|
+
用于按分组变量计算数值变量的描述性统计量,包括均值、分位数、缺失率等。
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
data : pd.DataFrame
|
|
19
|
+
输入的原始数据框
|
|
20
|
+
varlist : list
|
|
21
|
+
需要进行统计的数值变量名列表
|
|
22
|
+
groupby : list
|
|
23
|
+
分组变量名列表
|
|
24
|
+
spec_missing_value : any, optional
|
|
25
|
+
需要被当作缺失值处理的特殊值,默认为None
|
|
26
|
+
|
|
27
|
+
Examples
|
|
28
|
+
--------
|
|
29
|
+
>>> pm = proc_means(df, ['age', 'score'], ['gender'])
|
|
30
|
+
>>> result = pm()
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, data, varlist, groupby, spec_missing_value=None):
|
|
34
|
+
"""初始化proc_means对象。
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
data : pd.DataFrame
|
|
39
|
+
输入的原始数据框
|
|
40
|
+
varlist : list
|
|
41
|
+
需要进行统计的数值变量名列表
|
|
42
|
+
groupby : list
|
|
43
|
+
分组变量名列表
|
|
44
|
+
spec_missing_value : any, optional
|
|
45
|
+
需要被当作缺失值处理的特殊值
|
|
46
|
+
"""
|
|
47
|
+
self.data = data
|
|
48
|
+
self.varlist = varlist
|
|
49
|
+
self.groupby = groupby
|
|
50
|
+
self.spec_missing_value = spec_missing_value
|
|
51
|
+
|
|
52
|
+
def treat_spec_missing(self):
|
|
53
|
+
"""处理特定的缺失值。
|
|
54
|
+
|
|
55
|
+
将self.spec_missing_value指定的值替换为np.nan,以便正确计算统计量。
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
pd.DataFrame
|
|
60
|
+
处理缺失值后的数据框
|
|
61
|
+
"""
|
|
62
|
+
if self.spec_missing_value is not None:
|
|
63
|
+
self.data = self.data.replace(self.spec_missing_value, np.nan)
|
|
64
|
+
return self.data
|
|
65
|
+
|
|
66
|
+
def group_means(self, q=None):
|
|
67
|
+
"""按分组计算描述性统计量。
|
|
68
|
+
|
|
69
|
+
对指定变量按分组计算描述性统计量,包括计数、均值、标准差、最小值、最大值
|
|
70
|
+
以及自定义分位数。
|
|
71
|
+
|
|
72
|
+
Parameters
|
|
73
|
+
----------
|
|
74
|
+
q : list, optional
|
|
75
|
+
分位数列表,默认为[0.05, 0.15, 0.25, 0.5, 0.75, 0.95, 0.99]
|
|
76
|
+
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
pd.DataFrame
|
|
80
|
+
包含描述性统计量的数据框
|
|
81
|
+
"""
|
|
82
|
+
if q is None:
|
|
83
|
+
q = [0.05, 0.15, 0.25, 0.5, 0.75, 0.95, 0.99]
|
|
84
|
+
|
|
85
|
+
data_w_varlist = self.data[self.groupby + self.varlist]
|
|
86
|
+
|
|
87
|
+
grouped_data = data_w_varlist\
|
|
88
|
+
.melt(id_vars=self.groupby,
|
|
89
|
+
value_vars=self.varlist,
|
|
90
|
+
var_name="attribute",
|
|
91
|
+
value_name="value")\
|
|
92
|
+
.groupby(self.groupby + ["attribute"])
|
|
93
|
+
res_describe = grouped_data.describe(percentiles=q)
|
|
94
|
+
res_describe = res_describe.droplevel(level=0, axis=1)
|
|
95
|
+
return res_describe
|
|
96
|
+
|
|
97
|
+
def group_sum(self):
|
|
98
|
+
"""计算每组的样本数量。
|
|
99
|
+
|
|
100
|
+
统计每个分组组合中的观测数量(样本总数)。
|
|
101
|
+
|
|
102
|
+
Returns
|
|
103
|
+
-------
|
|
104
|
+
pd.DataFrame
|
|
105
|
+
包含每组样本数量的聚合结果
|
|
106
|
+
"""
|
|
107
|
+
data = self.data.copy()
|
|
108
|
+
data["_sum_ind"] = 1
|
|
109
|
+
data = data[self.groupby + self.varlist + ["_sum_ind"]]
|
|
110
|
+
grouped_data = data\
|
|
111
|
+
.melt(id_vars=self.groupby + ["_sum_ind"],
|
|
112
|
+
value_vars=self.varlist,
|
|
113
|
+
var_name="attribute",
|
|
114
|
+
value_name="value")\
|
|
115
|
+
.groupby(self.groupby + ["attribute"])
|
|
116
|
+
res_sum = grouped_data.agg(sum_all=("_sum_ind", "sum"))
|
|
117
|
+
return res_sum
|
|
118
|
+
|
|
119
|
+
def __call__(self, q=None):
|
|
120
|
+
"""执行完整的分组统计分析。
|
|
121
|
+
|
|
122
|
+
综合计算分组统计量,包括样本数、N_ALL、均值、标准差、分位数和缺失率。
|
|
123
|
+
|
|
124
|
+
Parameters
|
|
125
|
+
----------
|
|
126
|
+
q : list, optional
|
|
127
|
+
分位数列表,默认为[0.05, 0.15, 0.25, 0.5, 0.75, 0.95, 0.99]
|
|
128
|
+
|
|
129
|
+
Returns
|
|
130
|
+
-------
|
|
131
|
+
pd.DataFrame
|
|
132
|
+
完整的分组统计报告,包含N、N_ALL、各分位数和缺失率
|
|
133
|
+
"""
|
|
134
|
+
if q is None:
|
|
135
|
+
q = [0.05, 0.15, 0.25, 0.5, 0.75, 0.95, 0.99]
|
|
136
|
+
|
|
137
|
+
self.data = self.treat_spec_missing()
|
|
138
|
+
sum_total = self.group_sum()
|
|
139
|
+
means = self.group_means(q=q)
|
|
140
|
+
res_fnl = sum_total.merge(means, left_index=True, right_index=True)
|
|
141
|
+
res_fnl["missing_rate"] = 1 - res_fnl["count"] / res_fnl["sum_all"]
|
|
142
|
+
quantile_rename = {str(int(x * 100)) + "%": "Q" + str(int(x * 100)) for x in q}
|
|
143
|
+
res_fnl = res_fnl.rename(columns=quantile_rename)
|
|
144
|
+
res_fnl = res_fnl.rename(columns={"count": "N", "sum_all": "N_ALL"})
|
|
145
|
+
res_fnl.columns = [x.upper() for x in res_fnl.columns]
|
|
146
|
+
return res_fnl
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def proc_means_by_grp(data, varlist, groupby=None, spec_missing_value=None, q=None):
|
|
150
|
+
"""按分组计算变量统计报告。
|
|
151
|
+
|
|
152
|
+
对指定变量按分组计算描述性统计量,返回包含样本数、均值、分位数和缺失率的报告。
|
|
153
|
+
底层调用proc_means类完成计算。
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
data : pd.DataFrame
|
|
158
|
+
输入的原始数据框
|
|
159
|
+
varlist : list
|
|
160
|
+
需要进行统计的数值变量名列表
|
|
161
|
+
groupby : list, optional
|
|
162
|
+
分组变量名列表,默认为空列表(不分组)
|
|
163
|
+
spec_missing_value : any, optional
|
|
164
|
+
需要被当作缺失值处理的特殊值,默认为None
|
|
165
|
+
q : list, optional
|
|
166
|
+
分位数列表,默认为[0.05, 0.15, 0.25, 0.5, 0.75, 0.95, 0.99]
|
|
167
|
+
|
|
168
|
+
Returns
|
|
169
|
+
-------
|
|
170
|
+
pd.DataFrame
|
|
171
|
+
分组统计报告,包含各变量的描述性统计量
|
|
172
|
+
|
|
173
|
+
Examples
|
|
174
|
+
--------
|
|
175
|
+
>>> result = proc_means_by_grp(df, ['age', 'score'], ['gender'])
|
|
176
|
+
"""
|
|
177
|
+
if groupby is None:
|
|
178
|
+
groupby = []
|
|
179
|
+
if q is None:
|
|
180
|
+
q = [0.05, 0.15, 0.25, 0.5, 0.75, 0.95, 0.99]
|
|
181
|
+
|
|
182
|
+
means = proc_means(data, varlist, groupby=groupby, spec_missing_value=spec_missing_value)
|
|
183
|
+
means_rpt = means(q=q)
|
|
184
|
+
means_rpt = means_rpt.reset_index(drop=False)
|
|
185
|
+
|
|
186
|
+
return means_rpt
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class DistributionShiftAnalyzer:
|
|
190
|
+
"""分布偏移分析器。
|
|
191
|
+
|
|
192
|
+
用于分析不同分组之间变量分布的偏移情况,通过比较各分组超过基准组
|
|
193
|
+
异常值阈值的观测比例来评估分布差异。
|
|
194
|
+
|
|
195
|
+
Parameters
|
|
196
|
+
----------
|
|
197
|
+
data : pd.DataFrame
|
|
198
|
+
输入的原始数据框
|
|
199
|
+
grp_name : str
|
|
200
|
+
分组变量名
|
|
201
|
+
benchmark_value : any
|
|
202
|
+
基准组的分组值,用于确定异常值阈值
|
|
203
|
+
|
|
204
|
+
Examples
|
|
205
|
+
--------
|
|
206
|
+
>>> analyzer = DistributionShiftAnalyzer(df, 'gender', 'Male')
|
|
207
|
+
>>> result = analyzer.analyze(['age', 'score'])
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
def __init__(self, data, grp_name, benchmark_value):
|
|
211
|
+
"""初始化分布偏移分析器。
|
|
212
|
+
|
|
213
|
+
Parameters
|
|
214
|
+
----------
|
|
215
|
+
data : pd.DataFrame
|
|
216
|
+
输入的原始数据框
|
|
217
|
+
grp_name : str
|
|
218
|
+
分组变量名
|
|
219
|
+
benchmark_value : any
|
|
220
|
+
基准组的分组值
|
|
221
|
+
"""
|
|
222
|
+
self.data = data
|
|
223
|
+
self.grp_name = grp_name
|
|
224
|
+
self.benchmark_value = benchmark_value
|
|
225
|
+
|
|
226
|
+
def analyze_single_var(self, var, outlier_value=0.99):
|
|
227
|
+
"""分析单个变量的分布偏移。
|
|
228
|
+
|
|
229
|
+
计算各分组中超过基准组指定分位数阈值的观测比例。
|
|
230
|
+
|
|
231
|
+
Parameters
|
|
232
|
+
----------
|
|
233
|
+
var : str
|
|
234
|
+
待分析的变量名
|
|
235
|
+
outlier_value : float, optional
|
|
236
|
+
用于确定异常值阈值的分位数,默认为0.99
|
|
237
|
+
|
|
238
|
+
Returns
|
|
239
|
+
-------
|
|
240
|
+
dict
|
|
241
|
+
键为分组值,值为超过阈值的观测比例
|
|
242
|
+
"""
|
|
243
|
+
means_rpt = proc_means_by_grp(
|
|
244
|
+
self.data, [var], [self.grp_name],
|
|
245
|
+
spec_missing_value=None, q=[outlier_value]
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
outlier_name = f'Q{str(int(outlier_value * 100))}'
|
|
249
|
+
outlier_threshold = means_rpt[
|
|
250
|
+
means_rpt[self.grp_name] == self.benchmark_value
|
|
251
|
+
][outlier_name].iloc[0]
|
|
252
|
+
|
|
253
|
+
res_dict = {}
|
|
254
|
+
for group, group_data in self.data.groupby(self.grp_name):
|
|
255
|
+
cnt = group_data[group_data[var] > outlier_threshold].shape[0]
|
|
256
|
+
prop = round(cnt / group_data.shape[0], 4)
|
|
257
|
+
res_dict[group] = prop
|
|
258
|
+
return res_dict
|
|
259
|
+
|
|
260
|
+
def analyze(self, varlist, outlier_value=0.99):
|
|
261
|
+
"""分析多个变量的分布偏移。
|
|
262
|
+
|
|
263
|
+
对变量列表中每个变量计算各分组超过基准组阈值的比例,
|
|
264
|
+
并以数据框形式返回所有结果。
|
|
265
|
+
|
|
266
|
+
Parameters
|
|
267
|
+
----------
|
|
268
|
+
varlist : list
|
|
269
|
+
待分析的变量名列表
|
|
270
|
+
outlier_value : float, optional
|
|
271
|
+
用于确定异常值阈值的分位数,默认为0.99
|
|
272
|
+
|
|
273
|
+
Returns
|
|
274
|
+
-------
|
|
275
|
+
pd.DataFrame
|
|
276
|
+
行索引为变量名,列为各分组值,内容为超过阈值的观测比例
|
|
277
|
+
|
|
278
|
+
Examples
|
|
279
|
+
--------
|
|
280
|
+
>>> analyzer = DistributionShiftAnalyzer(df, 'gender', 'Male')
|
|
281
|
+
>>> result = analyzer.analyze(['age', 'score'])
|
|
282
|
+
"""
|
|
283
|
+
res_dict = {}
|
|
284
|
+
for var in varlist:
|
|
285
|
+
res = self.analyze_single_var(var=var, outlier_value=outlier_value)
|
|
286
|
+
res_dict[var] = res
|
|
287
|
+
return pd.DataFrame(res_dict).T
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def get_distribution_shift_single_var(data, var, grp_name, benchmark_value, outlier_value=0.99):
|
|
291
|
+
"""计算单个变量的分布偏移。
|
|
292
|
+
|
|
293
|
+
分析指定变量在各分组中超过基准组异常值阈值的观测比例。
|
|
294
|
+
|
|
295
|
+
Parameters
|
|
296
|
+
----------
|
|
297
|
+
data : pd.DataFrame
|
|
298
|
+
输入的原始数据框
|
|
299
|
+
var : str
|
|
300
|
+
待分析的变量名
|
|
301
|
+
grp_name : str
|
|
302
|
+
分组变量名
|
|
303
|
+
benchmark_value : any
|
|
304
|
+
基准组的分组值
|
|
305
|
+
outlier_value : float, optional
|
|
306
|
+
用于确定异常值阈值的分位数,默认为0.99
|
|
307
|
+
|
|
308
|
+
Returns
|
|
309
|
+
-------
|
|
310
|
+
dict
|
|
311
|
+
键为分组值,值为超过阈值的观测比例
|
|
312
|
+
|
|
313
|
+
Examples
|
|
314
|
+
--------
|
|
315
|
+
>>> result = get_distribution_shift_single_var(df, 'age', 'gender', 'Male')
|
|
316
|
+
"""
|
|
317
|
+
analyzer = DistributionShiftAnalyzer(data, grp_name, benchmark_value)
|
|
318
|
+
return analyzer.analyze_single_var(var, outlier_value)
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def get_distribution_shift(data, varlist, grp_name, benchmark_value, outlier_value=0.99):
|
|
322
|
+
"""计算多个变量的分布偏移。
|
|
323
|
+
|
|
324
|
+
对变量列表中每个变量分析各分组超过基准组异常值阈值的观测比例,
|
|
325
|
+
返回包含所有结果的转置数据框。
|
|
326
|
+
|
|
327
|
+
Parameters
|
|
328
|
+
----------
|
|
329
|
+
data : pd.DataFrame
|
|
330
|
+
输入的原始数据框
|
|
331
|
+
varlist : list
|
|
332
|
+
待分析的变量名列表
|
|
333
|
+
grp_name : str
|
|
334
|
+
分组变量名
|
|
335
|
+
benchmark_value : any
|
|
336
|
+
基准组的分组值
|
|
337
|
+
outlier_value : float, optional
|
|
338
|
+
用于确定异常值阈值的分位数,默认为0.99
|
|
339
|
+
|
|
340
|
+
Returns
|
|
341
|
+
-------
|
|
342
|
+
pd.DataFrame
|
|
343
|
+
行索引为变量名,列为各分组值,内容为超过阈值的观测比例
|
|
344
|
+
|
|
345
|
+
Examples
|
|
346
|
+
--------
|
|
347
|
+
>>> result = get_distribution_shift(df, ['age', 'score'], 'gender', 'Male')
|
|
348
|
+
"""
|
|
349
|
+
analyzer = DistributionShiftAnalyzer(data, grp_name, benchmark_value)
|
|
350
|
+
return analyzer.analyze(varlist, outlier_value)
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
class DistributionPlotter:
|
|
354
|
+
"""分布图绘制器。
|
|
355
|
+
|
|
356
|
+
提供多种方式可视化数值变量的分布情况,支持核密度图、直方图和地毯图。
|
|
357
|
+
|
|
358
|
+
Parameters
|
|
359
|
+
----------
|
|
360
|
+
data : pd.DataFrame
|
|
361
|
+
输入的数据框
|
|
362
|
+
score : str
|
|
363
|
+
用于绑制分布的变量名
|
|
364
|
+
|
|
365
|
+
Examples
|
|
366
|
+
--------
|
|
367
|
+
>>> plotter = DistributionPlotter(df, 'age')
|
|
368
|
+
>>> plotter.plot(method='kdeplot', title='Age Distribution')
|
|
369
|
+
"""
|
|
370
|
+
|
|
371
|
+
def __init__(self, data, score):
|
|
372
|
+
"""初始化分布图绘制器。
|
|
373
|
+
|
|
374
|
+
Parameters
|
|
375
|
+
----------
|
|
376
|
+
data : pd.DataFrame
|
|
377
|
+
输入的数据框
|
|
378
|
+
score : str
|
|
379
|
+
用于绑制分布的变量名
|
|
380
|
+
"""
|
|
381
|
+
self.data = data
|
|
382
|
+
self.score = score
|
|
383
|
+
self.plot_series = data[score]
|
|
384
|
+
|
|
385
|
+
def plot_rugplot(self, figsize=(15, 15), title="Distribution Plot"):
|
|
386
|
+
"""绑制地毯图。
|
|
387
|
+
|
|
388
|
+
在核密度估计图上叠加地毯图显示数据分布密度。
|
|
389
|
+
|
|
390
|
+
Parameters
|
|
391
|
+
----------
|
|
392
|
+
figsize : tuple, optional
|
|
393
|
+
图形尺寸,默认为(15, 15)
|
|
394
|
+
title : str, optional
|
|
395
|
+
图形标题,默认为"Distribution Plot"
|
|
396
|
+
"""
|
|
397
|
+
plt.figure(figsize=figsize)
|
|
398
|
+
sns.kdeplot(self.plot_series, color='purple')
|
|
399
|
+
sns.rugplot(self.plot_series, color='purple')
|
|
400
|
+
plt.title(title)
|
|
401
|
+
plt.xlabel(self.score)
|
|
402
|
+
plt.ylabel('Density')
|
|
403
|
+
|
|
404
|
+
def plot_kdeplot(self, figsize=(15, 15), title="Distribution Plot"):
|
|
405
|
+
"""绑制核密度估计图。
|
|
406
|
+
|
|
407
|
+
使用填充的核密度估计图展示数据分布。
|
|
408
|
+
|
|
409
|
+
Parameters
|
|
410
|
+
----------
|
|
411
|
+
figsize : tuple, optional
|
|
412
|
+
图形尺寸,默认为(15, 15)
|
|
413
|
+
title : str, optional
|
|
414
|
+
图形标题,默认为"Distribution Plot"
|
|
415
|
+
"""
|
|
416
|
+
plt.figure(figsize=figsize)
|
|
417
|
+
sns.kdeplot(self.plot_series, fill=True, color='orange')
|
|
418
|
+
plt.title(title)
|
|
419
|
+
plt.xlabel(self.score)
|
|
420
|
+
plt.ylabel('Density')
|
|
421
|
+
|
|
422
|
+
def plot_displot(self, figsize=(15, 15), title="Distribution Plot", nbins=10):
|
|
423
|
+
"""绑制分布直方图。
|
|
424
|
+
|
|
425
|
+
绑制带核密度估计的直方图展示数据分布。
|
|
426
|
+
|
|
427
|
+
Parameters
|
|
428
|
+
----------
|
|
429
|
+
figsize : tuple, optional
|
|
430
|
+
图形尺寸,默认为(15, 15)
|
|
431
|
+
title : str, optional
|
|
432
|
+
图形标题,默认为"Distribution Plot"
|
|
433
|
+
nbins : int, optional
|
|
434
|
+
直方图的箱子数量,默认为10
|
|
435
|
+
"""
|
|
436
|
+
plt.figure(figsize=figsize)
|
|
437
|
+
sns.displot(self.plot_series, kde=True, bins=nbins)
|
|
438
|
+
plt.title(title)
|
|
439
|
+
plt.xlabel(self.score)
|
|
440
|
+
plt.ylabel('Density')
|
|
441
|
+
|
|
442
|
+
def plot(self, method='displot', title="Distribution Plot", figsize=(15, 15), nbins=10):
|
|
443
|
+
"""绑制定分布图。
|
|
444
|
+
|
|
445
|
+
根据指定的方法绑制变量分布图。
|
|
446
|
+
|
|
447
|
+
Parameters
|
|
448
|
+
----------
|
|
449
|
+
method : str, optional
|
|
450
|
+
绑制方法,可选'rugplot'、'kdeplot'或'displot',默认为'displot'
|
|
451
|
+
title : str, optional
|
|
452
|
+
图形标题,默认为"Distribution Plot"
|
|
453
|
+
figsize : tuple, optional
|
|
454
|
+
图形尺寸,默认为(15, 15)
|
|
455
|
+
nbins : int, optional
|
|
456
|
+
直方图的箱子数量(仅用于displot方法),默认为10
|
|
457
|
+
|
|
458
|
+
Raises
|
|
459
|
+
------
|
|
460
|
+
ValueError
|
|
461
|
+
当指定了不支持的绑制方法时抛出
|
|
462
|
+
|
|
463
|
+
Examples
|
|
464
|
+
--------
|
|
465
|
+
>>> plotter = DistributionPlotter(df, 'age')
|
|
466
|
+
>>> plotter.plot(method='kdeplot', title='Age Distribution')
|
|
467
|
+
"""
|
|
468
|
+
if method == 'rugplot':
|
|
469
|
+
self.plot_rugplot(figsize=figsize, title=title)
|
|
470
|
+
elif method == 'kdeplot':
|
|
471
|
+
self.plot_kdeplot(figsize=figsize, title=title)
|
|
472
|
+
elif method == 'displot':
|
|
473
|
+
self.plot_displot(figsize=figsize, title=title, nbins=nbins)
|
|
474
|
+
else:
|
|
475
|
+
raise ValueError(f"Unsupported method: {method}. Choose from 'rugplot', 'kdeplot', 'displot'.")
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
def plot_distribution(data, score, method='displot', title="Distribution Plot", figsize=(15, 15), nbins=10):
|
|
479
|
+
"""绑制变量分布图。
|
|
480
|
+
|
|
481
|
+
根据指定的方法绑制变量的分布图,支持核密度估计、直方图和地毯图。
|
|
482
|
+
|
|
483
|
+
Parameters
|
|
484
|
+
----------
|
|
485
|
+
data : pd.DataFrame
|
|
486
|
+
输入的数据框
|
|
487
|
+
score : str
|
|
488
|
+
用于绑制分布的变量名
|
|
489
|
+
method : str, optional
|
|
490
|
+
绑制方法,可选'rugplot'、'kdeplot'或'displot',默认为'displot'
|
|
491
|
+
title : str, optional
|
|
492
|
+
图形标题,默认为"Distribution Plot"
|
|
493
|
+
figsize : tuple, optional
|
|
494
|
+
图形尺寸,默认为(15, 15)
|
|
495
|
+
nbins : int, optional
|
|
496
|
+
直方图的箱子数量(仅用于displot方法),默认为10
|
|
497
|
+
|
|
498
|
+
Returns
|
|
499
|
+
-------
|
|
500
|
+
None
|
|
501
|
+
直接显示绑制图形
|
|
502
|
+
|
|
503
|
+
Examples
|
|
504
|
+
--------
|
|
505
|
+
>>> plot_distribution(df, 'age', method='kdeplot')
|
|
506
|
+
>>> plot_distribution(df, 'score', method='displot', nbins=20)
|
|
507
|
+
"""
|
|
508
|
+
plotter = DistributionPlotter(data, score)
|
|
509
|
+
plotter.plot(method=method, title=title, figsize=figsize, nbins=nbins)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# Modeling_Tool.Feature.Distribution_Tool
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) 2026 Kyle Sun <github.com/Kyle-J-Sun>. All rights reserved.
|
|
5
|
+
# SuperModelingFactory — Licensed under the Business Source License 1.1.
|
|
6
|
+
#
|
|
7
|
+
# This stub describes the public API of a closed-source module compiled to a
|
|
8
|
+
# native extension (.so / .pyd). The original source is not distributed.
|
|
9
|
+
# Production / commercial use requires a separate commercial license.
|
|
10
|
+
#
|
|
11
|
+
# FINGERPRINT: SMF-DISTRIBUTION-eba574de
|
|
12
|
+
# (Unique trace marker. Do not remove or alter — used for plagiarism
|
|
13
|
+
# detection across the public internet.)
|
|
14
|
+
# =============================================================================
|
|
15
|
+
|
|
16
|
+
import numpy as np
|
|
17
|
+
import pandas as pd
|
|
18
|
+
import seaborn as sns
|
|
19
|
+
import matplotlib.pyplot as plt
|
|
20
|
+
|
|
21
|
+
class proc_means:
|
|
22
|
+
def __init__(self, data, varlist, groupby, spec_missing_value = None): ...
|
|
23
|
+
def treat_spec_missing(self): ...
|
|
24
|
+
def group_means(self, q = None): ...
|
|
25
|
+
def group_sum(self): ...
|
|
26
|
+
def __call__(self, q = None): ...
|
|
27
|
+
def proc_means_by_grp(data, varlist, groupby = None, spec_missing_value = None, q = None): ...
|
|
28
|
+
|
|
29
|
+
class DistributionShiftAnalyzer:
|
|
30
|
+
def __init__(self, data, grp_name, benchmark_value): ...
|
|
31
|
+
def analyze_single_var(self, var, outlier_value = 0.99): ...
|
|
32
|
+
def analyze(self, varlist, outlier_value = 0.99): ...
|
|
33
|
+
def get_distribution_shift_single_var(data, var, grp_name, benchmark_value, outlier_value = 0.99): ...
|
|
34
|
+
def get_distribution_shift(data, varlist, grp_name, benchmark_value, outlier_value = 0.99): ...
|
|
35
|
+
|
|
36
|
+
class DistributionPlotter:
|
|
37
|
+
def __init__(self, data, score): ...
|
|
38
|
+
def plot_rugplot(self, figsize = (15, 15), title = 'Distribution Plot'): ...
|
|
39
|
+
def plot_kdeplot(self, figsize = (15, 15), title = 'Distribution Plot'): ...
|
|
40
|
+
def plot_displot(self, figsize = (15, 15), title = 'Distribution Plot', nbins = 10): ...
|
|
41
|
+
def plot(self, method = 'displot', title = 'Distribution Plot', figsize = (15, 15), nbins = 10): ...
|
|
42
|
+
def plot_distribution(data, score, method = 'displot', title = 'Distribution Plot', figsize = (15, 15), nbins = 10): ...
|