SuperModelingFactory 0.3.11__tar.gz → 0.3.13__tar.gz
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.
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/Feature_Screen.py +137 -6
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/Weighted_Screen.py +31 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/__init__.py +2 -0
- supermodelingfactory-0.3.13/Modeling_Tool/Pipeline/orchestrator.py +50 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/__init__.py +2 -2
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/PKG-INFO +1 -1
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/SuperModelingFactory.egg-info/PKG-INFO +1 -1
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/SuperModelingFactory.egg-info/SOURCES.txt +1 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/pyproject.toml +1 -1
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/setup.py +1 -1
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/ExcelMaster/ExcelFormatTool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/ExcelMaster/ExcelMaster.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/ExcelMaster/Template.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/ExcelMaster/Utility.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/ExcelMaster/__init__.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/LICENSE +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/MANIFEST.in +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Binning_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Binning_Tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Check_DuckDB_Compatibility.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Json_Data_Converter.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Model_Registry_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/ODPS_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Parallel_Engine.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Parallel_ODPS_Manager.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Proc_Compare.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Slope_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Slope_Tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/XOR_Encryptor.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/XOR_Encryptor.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/__init__.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/kDataFrame.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/kDataFrame.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/sample_weight_utils.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/utils.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/Evaluation_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/Evaluation_Tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/Model_Eval_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/Model_Eval_Tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/__init__.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/evaluate_model.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/evaluate_model.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/weighted_eval_utils.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Explainability/Coalition_Structure.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Explainability/Model_Explainer.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Explainability/__init__.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/Distribution_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/Distribution_Tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/Feature_Insights.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/Feature_Insights.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/PSI_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/PSI_Tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/WOE_Engine_Feature_Patch.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/__init__.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/Backward_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/Backward_Tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/GBM_Search_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/GBM_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/GBM_Tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/LRM_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/LRM_Tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/__init__.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/_common.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/credit_model.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/feature_validation.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/mock_sample.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/reject_inference.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/sample_analysis.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/score_comparison.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/score_consistency_uat.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/screening_artifact.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/Distribution_Adaptation.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/Distribution_Adaptation.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/Reject_Infer.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/Reject_Infer.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/Sample_Split.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/Sample_Split.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/__init__.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/UAT/UAT_Consistency_Checker.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/UAT/__init__.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Adapter.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Adapter.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Master.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Master.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Monotone_Binner.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Monotone_Binner.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Plot_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Plot_Tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Report_Builder.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Report_Builder.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/__init__.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/plot_woe_tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/plot_woe_tool.pyi +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/ref_font/KaiTi.ttf +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/ref_font/WeiRuanYaHei.ttf +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/ref_font/__init__.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/ref_font/simsun.ttc +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/README.md +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Report/Report_Tool.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Report/__init__.py +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/SuperModelingFactory.egg-info/dependency_links.txt +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/SuperModelingFactory.egg-info/not-zip-safe +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/SuperModelingFactory.egg-info/requires.txt +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/SuperModelingFactory.egg-info/top_level.txt +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/requirements.txt +0 -0
- {supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/setup.cfg +0 -0
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/Feature_Screen.py
RENAMED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import warnings
|
|
6
5
|
from dataclasses import dataclass, field
|
|
7
6
|
from pathlib import Path
|
|
8
7
|
from typing import Any, Mapping
|
|
@@ -10,11 +9,18 @@ from typing import Any, Mapping
|
|
|
10
9
|
import numpy as np
|
|
11
10
|
import pandas as pd
|
|
12
11
|
|
|
12
|
+
from Modeling_Tool.Core.sample_weight_utils import resolve_sample_weight
|
|
13
|
+
|
|
13
14
|
from .Weighted_Screen import (
|
|
14
15
|
WeightedScreenResult,
|
|
16
|
+
_corr_dedup_weighted,
|
|
15
17
|
_legacy_unweighted_screen,
|
|
18
|
+
_psi_from_distributions,
|
|
16
19
|
_resolve_splits,
|
|
17
20
|
_summary_row,
|
|
21
|
+
_weighted_bin_distribution,
|
|
22
|
+
_weighted_iv_from_assigned_bins,
|
|
23
|
+
_weighted_pearson_corr_matrix,
|
|
18
24
|
_weighted_screen_impl,
|
|
19
25
|
)
|
|
20
26
|
|
|
@@ -289,6 +295,128 @@ def _woe_bins_unweighted_screen(
|
|
|
289
295
|
)
|
|
290
296
|
|
|
291
297
|
|
|
298
|
+
def _bins_to_numpy(bins: Any) -> np.ndarray:
|
|
299
|
+
if isinstance(bins, pd.Series):
|
|
300
|
+
return bins.to_numpy(dtype=object)
|
|
301
|
+
return np.asarray(bins, dtype=object)
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def _weighted_woe_bins_screen(
|
|
305
|
+
splits: dict[str, pd.DataFrame],
|
|
306
|
+
feature_cols: list[str],
|
|
307
|
+
target_col: str,
|
|
308
|
+
weight_col: str,
|
|
309
|
+
config: FeatureScreenConfig,
|
|
310
|
+
*,
|
|
311
|
+
prefit_woe_engine: Any | None = None,
|
|
312
|
+
) -> FeatureScreenResult:
|
|
313
|
+
from Modeling_Tool.WOE.WOE_Adapter import as_woe_engine
|
|
314
|
+
|
|
315
|
+
ins, oos, oot = splits["ins"], splits["oos"], splits["oot"]
|
|
316
|
+
w_ins = resolve_sample_weight(data=ins, weight_col=weight_col, expected_len=len(ins))
|
|
317
|
+
y_ins = ins[target_col].astype(float).to_numpy()
|
|
318
|
+
current = list(feature_cols)
|
|
319
|
+
summary_rows = [_summary_row("initial", len(feature_cols), len(current), None, weight_col)]
|
|
320
|
+
|
|
321
|
+
binner = prefit_woe_engine
|
|
322
|
+
if binner is None:
|
|
323
|
+
binner = fit_screening_woe_engine(
|
|
324
|
+
ins,
|
|
325
|
+
feature_cols,
|
|
326
|
+
target_col,
|
|
327
|
+
woe_engine=config.woe_engine,
|
|
328
|
+
woe_fit_query=config.woe_fit_query,
|
|
329
|
+
woe_params=config.woe_params,
|
|
330
|
+
monotone_woe_params=config.monotone_woe_params,
|
|
331
|
+
categorical_features=config.categorical_features,
|
|
332
|
+
)
|
|
333
|
+
adapter = as_woe_engine(binner)
|
|
334
|
+
|
|
335
|
+
psi_records: list[dict] = []
|
|
336
|
+
if config.psi_enabled:
|
|
337
|
+
for var in feature_cols:
|
|
338
|
+
if var not in ins.columns or ins[var].nunique(dropna=False) <= 1:
|
|
339
|
+
continue
|
|
340
|
+
bins_ins = _bins_to_numpy(adapter.assign_bins(ins, var))
|
|
341
|
+
exp_dist = _weighted_bin_distribution(bins_ins, w_ins, config.content)
|
|
342
|
+
row: dict[str, Any] = {"var": var, "psi_ins_oos": np.nan, "psi_ins_oot": np.nan}
|
|
343
|
+
if "oos" in config.psi_compare_splits and len(oos) > 0:
|
|
344
|
+
w_oos = resolve_sample_weight(data=oos, weight_col=weight_col, expected_len=len(oos))
|
|
345
|
+
bins_oos = _bins_to_numpy(adapter.assign_bins(oos, var))
|
|
346
|
+
act = _weighted_bin_distribution(bins_oos, w_oos, config.content)
|
|
347
|
+
row["psi_ins_oos"] = _psi_from_distributions(exp_dist, act, config.content)
|
|
348
|
+
if "oot" in config.psi_compare_splits and len(oot) > 0:
|
|
349
|
+
w_oot = resolve_sample_weight(data=oot, weight_col=weight_col, expected_len=len(oot))
|
|
350
|
+
bins_oot = _bins_to_numpy(adapter.assign_bins(oot, var))
|
|
351
|
+
act = _weighted_bin_distribution(bins_oot, w_oot, config.content)
|
|
352
|
+
row["psi_ins_oot"] = _psi_from_distributions(exp_dist, act, config.content)
|
|
353
|
+
psi_records.append(row)
|
|
354
|
+
|
|
355
|
+
psi_table = pd.DataFrame(psi_records) if psi_records else pd.DataFrame(
|
|
356
|
+
columns=["var", "psi_ins_oos", "psi_ins_oot"],
|
|
357
|
+
)
|
|
358
|
+
if not psi_table.empty:
|
|
359
|
+
compare_cols = [c for c in ("psi_ins_oos", "psi_ins_oot") if c in psi_table.columns]
|
|
360
|
+
psi_table["psi_max"] = psi_table[compare_cols].max(axis=1, skipna=True)
|
|
361
|
+
keep = psi_table.loc[psi_table["psi_max"] < config.psi_threshold, "var"].tolist()
|
|
362
|
+
n_before = len(current)
|
|
363
|
+
current = [v for v in current if v in keep] or current
|
|
364
|
+
summary_rows.append(_summary_row("psi", n_before, len(current), config.psi_threshold, weight_col))
|
|
365
|
+
else:
|
|
366
|
+
psi_table["psi_max"] = pd.Series(dtype=float)
|
|
367
|
+
else:
|
|
368
|
+
psi_table = pd.DataFrame(columns=["var", "psi_ins_oos", "psi_ins_oot", "psi_max"])
|
|
369
|
+
|
|
370
|
+
iv_records: list[dict] = []
|
|
371
|
+
if config.iv_enabled:
|
|
372
|
+
for var in current:
|
|
373
|
+
if var not in ins.columns or ins[var].nunique(dropna=False) <= 1:
|
|
374
|
+
continue
|
|
375
|
+
bins_ins = _bins_to_numpy(adapter.assign_bins(ins, var))
|
|
376
|
+
x_ins = ins[var].to_numpy(dtype=float)
|
|
377
|
+
iv_val, n_b, miss = _weighted_iv_from_assigned_bins(y_ins, w_ins, bins_ins, x_ins)
|
|
378
|
+
iv_records.append({
|
|
379
|
+
"var": var,
|
|
380
|
+
"iv_weighted": iv_val,
|
|
381
|
+
"n_bins": n_b,
|
|
382
|
+
"missing_rate": miss,
|
|
383
|
+
})
|
|
384
|
+
iv_table = pd.DataFrame(iv_records) if iv_records else pd.DataFrame(
|
|
385
|
+
columns=["var", "iv_weighted", "n_bins", "missing_rate"],
|
|
386
|
+
)
|
|
387
|
+
if not iv_table.empty:
|
|
388
|
+
keep = iv_table.loc[iv_table["iv_weighted"] >= config.iv_threshold, "var"].tolist()
|
|
389
|
+
n_before = len(current)
|
|
390
|
+
current = [v for v in current if v in keep] or current
|
|
391
|
+
summary_rows.append(_summary_row("iv", n_before, len(current), config.iv_threshold, weight_col))
|
|
392
|
+
else:
|
|
393
|
+
iv_table = pd.DataFrame(columns=["var", "iv_weighted", "n_bins", "missing_rate"])
|
|
394
|
+
|
|
395
|
+
corr_dropped = pd.DataFrame(columns=["var_a", "var_b", "corr", "iv_a", "iv_b", "kept", "dropped"])
|
|
396
|
+
if config.corr_enabled and len(current) > 1:
|
|
397
|
+
X = ins[current].astype(float).to_numpy()
|
|
398
|
+
corr = _weighted_pearson_corr_matrix(X, w_ins)
|
|
399
|
+
iv_map = dict(zip(iv_table["var"], iv_table["iv_weighted"])) if not iv_table.empty else {}
|
|
400
|
+
n_before = len(current)
|
|
401
|
+
current, corr_dropped = _corr_dedup_weighted(
|
|
402
|
+
current,
|
|
403
|
+
corr,
|
|
404
|
+
iv_map,
|
|
405
|
+
config.corr_threshold,
|
|
406
|
+
config.corr_max_iterations,
|
|
407
|
+
)
|
|
408
|
+
summary_rows.append(_summary_row("corr", n_before, len(current), config.corr_threshold, weight_col))
|
|
409
|
+
|
|
410
|
+
summary_rows.append(_summary_row("final", len(feature_cols), len(current), None, weight_col))
|
|
411
|
+
return FeatureScreenResult(
|
|
412
|
+
selected_features=list(current),
|
|
413
|
+
iv_table=iv_table,
|
|
414
|
+
psi_table=psi_table,
|
|
415
|
+
corr_dropped=corr_dropped,
|
|
416
|
+
summary=pd.DataFrame(summary_rows),
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
|
|
292
420
|
def feature_screen(
|
|
293
421
|
splits: dict[str, pd.DataFrame],
|
|
294
422
|
feature_cols: list[str],
|
|
@@ -303,11 +431,14 @@ def feature_screen(
|
|
|
303
431
|
use_woe_bins = _needs_woe_bins(cfg)
|
|
304
432
|
|
|
305
433
|
if weight_col is not None:
|
|
306
|
-
if use_woe_bins:
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
434
|
+
if use_woe_bins or prefit_woe_engine is not None:
|
|
435
|
+
return _weighted_woe_bins_screen(
|
|
436
|
+
splits,
|
|
437
|
+
feature_cols,
|
|
438
|
+
target_col,
|
|
439
|
+
weight_col,
|
|
440
|
+
cfg,
|
|
441
|
+
prefit_woe_engine=prefit_woe_engine,
|
|
311
442
|
)
|
|
312
443
|
return _weighted_screen_impl(
|
|
313
444
|
splits,
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/Weighted_Screen.py
RENAMED
|
@@ -119,6 +119,37 @@ def _psi_from_distributions(expected: pd.Series, actual: pd.Series, content: flo
|
|
|
119
119
|
return float(((a - e) * np.log(a / e)).sum())
|
|
120
120
|
|
|
121
121
|
|
|
122
|
+
def _weighted_iv_from_assigned_bins(
|
|
123
|
+
y: np.ndarray,
|
|
124
|
+
w: np.ndarray,
|
|
125
|
+
bins: np.ndarray,
|
|
126
|
+
x: np.ndarray,
|
|
127
|
+
) -> tuple[float, int, float]:
|
|
128
|
+
total_bad = float(np.sum(w * y))
|
|
129
|
+
total_good = float(np.sum(w * (1.0 - y)))
|
|
130
|
+
if total_bad <= 0 or total_good <= 0:
|
|
131
|
+
missing_rate = 1.0 - float(np.sum(w[np.isfinite(x)])) / float(np.sum(w) or 1.0)
|
|
132
|
+
return 0.0, 0, missing_rate
|
|
133
|
+
|
|
134
|
+
rows = []
|
|
135
|
+
for b in pd.unique(bins):
|
|
136
|
+
m = bins == b
|
|
137
|
+
bad_w = float(np.sum(w[m] * y[m]))
|
|
138
|
+
good_w = float(np.sum(w[m] * (1.0 - y[m])))
|
|
139
|
+
rows.append({
|
|
140
|
+
"bad_pct": bad_w / total_bad,
|
|
141
|
+
"good_pct": good_w / total_good,
|
|
142
|
+
})
|
|
143
|
+
if not rows:
|
|
144
|
+
missing_rate = 1.0 - float(np.sum(w[np.isfinite(x)])) / float(np.sum(w) or 1.0)
|
|
145
|
+
return 0.0, 0, missing_rate
|
|
146
|
+
|
|
147
|
+
stats = pd.DataFrame(rows)
|
|
148
|
+
iv = float(calc_iv(stats, "bad_pct", "good_pct").sum())
|
|
149
|
+
missing_rate = 1.0 - float(np.sum(w[np.isfinite(x)])) / float(np.sum(w) or 1.0)
|
|
150
|
+
return iv, len(rows), missing_rate
|
|
151
|
+
|
|
152
|
+
|
|
122
153
|
def _weighted_iv_for_var(
|
|
123
154
|
x: np.ndarray,
|
|
124
155
|
y: np.ndarray,
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/__init__.py
RENAMED
|
@@ -29,6 +29,7 @@ from .feature_validation import (
|
|
|
29
29
|
FeatureValidationPipelineConfig,
|
|
30
30
|
FeatureValidationPipelineResult,
|
|
31
31
|
)
|
|
32
|
+
from .orchestrator import run_modeling_from_validation
|
|
32
33
|
from .screening_artifact import FeatureScreeningArtifact, screen_result_to_summary
|
|
33
34
|
|
|
34
35
|
__all__ = [
|
|
@@ -55,4 +56,5 @@ __all__ = [
|
|
|
55
56
|
"FeatureValidationPipelineResult",
|
|
56
57
|
"FeatureScreeningArtifact",
|
|
57
58
|
"screen_result_to_summary",
|
|
59
|
+
"run_modeling_from_validation",
|
|
58
60
|
]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""High-level orchestration helpers across SMF pipelines."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import replace
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
import pandas as pd
|
|
9
|
+
|
|
10
|
+
from .credit_model import CreditModelPipeline, CreditModelPipelineConfig, CreditModelPipelineResult
|
|
11
|
+
from .feature_validation import (
|
|
12
|
+
FeatureValidationPipeline,
|
|
13
|
+
FeatureValidationPipelineConfig,
|
|
14
|
+
FeatureValidationPipelineResult,
|
|
15
|
+
)
|
|
16
|
+
from .screening_artifact import FeatureScreeningArtifact
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def run_modeling_from_validation(
|
|
20
|
+
data: pd.DataFrame,
|
|
21
|
+
*,
|
|
22
|
+
fvp_config: FeatureValidationPipelineConfig | None = None,
|
|
23
|
+
cm_config: CreditModelPipelineConfig | None = None,
|
|
24
|
+
selection_enabled: bool = True,
|
|
25
|
+
reuse_screening_woe: bool = True,
|
|
26
|
+
) -> tuple[FeatureValidationPipelineResult, CreditModelPipelineResult]:
|
|
27
|
+
"""Run feature validation/selection, then credit modeling on the same dataset."""
|
|
28
|
+
fvp_cfg = fvp_config or FeatureValidationPipelineConfig()
|
|
29
|
+
if selection_enabled and not fvp_cfg.selection_enabled:
|
|
30
|
+
fvp_cfg = replace(fvp_cfg, selection_enabled=True)
|
|
31
|
+
|
|
32
|
+
fvp_result = FeatureValidationPipeline(fvp_cfg).run(data)
|
|
33
|
+
artifact = FeatureScreeningArtifact.from_fvp_result(fvp_result)
|
|
34
|
+
|
|
35
|
+
cm_cfg = cm_config or CreditModelPipelineConfig()
|
|
36
|
+
cm_overrides: dict[str, Any] = {
|
|
37
|
+
"screening_artifact": artifact,
|
|
38
|
+
"reuse_screening_woe": reuse_screening_woe,
|
|
39
|
+
"target_col": artifact.target_col,
|
|
40
|
+
"weight_col": artifact.weight_col,
|
|
41
|
+
}
|
|
42
|
+
if artifact.selected_features:
|
|
43
|
+
cm_overrides["feature_cols"] = list(artifact.selected_features)
|
|
44
|
+
cm_cfg = replace(cm_cfg, **cm_overrides)
|
|
45
|
+
|
|
46
|
+
cm_result = CreditModelPipeline(cm_cfg).run(data)
|
|
47
|
+
return fvp_result, cm_result
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
__all__ = ["run_modeling_from_validation"]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
|
|
3
3
|
__author__ = "Jingkai Sun"
|
|
4
|
-
__version__ = "0.3.
|
|
4
|
+
__version__ = "0.3.13"
|
|
5
5
|
|
|
6
6
|
# Core module - base data structures
|
|
7
7
|
from .Core import (
|
|
@@ -116,7 +116,7 @@ _PIPELINE_EXPORTS = frozenset({
|
|
|
116
116
|
'SampleAnalysisPipeline', 'SampleAnalysisPipelineConfig', 'SampleAnalysisPipelineResult',
|
|
117
117
|
'MockSamplePipeline', 'MockSamplePipelineConfig', 'MockSamplePipelineResult',
|
|
118
118
|
'FeatureValidationPipeline', 'FeatureValidationPipelineConfig', 'FeatureValidationPipelineResult',
|
|
119
|
-
'FeatureScreeningArtifact', 'screen_result_to_summary',
|
|
119
|
+
'FeatureScreeningArtifact', 'screen_result_to_summary', 'run_modeling_from_validation',
|
|
120
120
|
})
|
|
121
121
|
|
|
122
122
|
def __getattr__(name):
|
|
@@ -62,6 +62,7 @@ Modeling_Tool/Pipeline/_common.py
|
|
|
62
62
|
Modeling_Tool/Pipeline/credit_model.py
|
|
63
63
|
Modeling_Tool/Pipeline/feature_validation.py
|
|
64
64
|
Modeling_Tool/Pipeline/mock_sample.py
|
|
65
|
+
Modeling_Tool/Pipeline/orchestrator.py
|
|
65
66
|
Modeling_Tool/Pipeline/reject_inference.py
|
|
66
67
|
Modeling_Tool/Pipeline/sample_analysis.py
|
|
67
68
|
Modeling_Tool/Pipeline/score_comparison.py
|
|
@@ -12,7 +12,7 @@ build-backend = "setuptools.build_meta"
|
|
|
12
12
|
|
|
13
13
|
[project]
|
|
14
14
|
name = "SuperModelingFactory"
|
|
15
|
-
version = "0.3.
|
|
15
|
+
version = "0.3.13"
|
|
16
16
|
description = "Credit risk modeling factory: WOE binning, scorecards, LightGBM, Excel reporting."
|
|
17
17
|
readme = "README.md"
|
|
18
18
|
requires-python = ">=3.10"
|
|
@@ -15,7 +15,7 @@ def _read(path: str) -> str:
|
|
|
15
15
|
|
|
16
16
|
setup(
|
|
17
17
|
name="SuperModelingFactory",
|
|
18
|
-
version=os.environ.get("SMF_VERSION", "0.3.
|
|
18
|
+
version=os.environ.get("SMF_VERSION", "0.3.13"),
|
|
19
19
|
description="Credit risk modeling factory: WOE binning, scorecards, LightGBM, Excel reporting.",
|
|
20
20
|
long_description=_read("README.md"),
|
|
21
21
|
long_description_content_type="text/markdown",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Binning_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Binning_Tool.pyi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Parallel_Engine.py
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Proc_Compare.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Slope_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/Slope_Tool.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/XOR_Encryptor.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/XOR_Encryptor.pyi
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/kDataFrame.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Core/kDataFrame.pyi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/Evaluation_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/Evaluation_Tool.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/Model_Eval_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/Model_Eval_Tool.pyi
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/evaluate_model.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Eval/evaluate_model.pyi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Explainability/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/PSI_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/PSI_Tool.pyi
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Feature/__init__.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/Backward_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/Backward_Tool.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/GBM_Search_Tool.py
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/GBM_Tool.pyi
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Model/LRM_Tool.pyi
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/_common.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/credit_model.py
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Pipeline/mock_sample.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/Reject_Infer.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/Reject_Infer.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/Sample_Split.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/Sample_Split.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/Sample/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Adapter.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Adapter.pyi
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Master.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Monotone_Binner.py
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Plot_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Plot_Tool.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Report_Builder.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/WOE_Report_Builder.pyi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/plot_woe_tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/WOE/plot_woe_tool.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/ref_font/KaiTi.ttf
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/ref_font/WeiRuanYaHei.ttf
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/ref_font/__init__.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.11 → supermodelingfactory-0.3.13}/Modeling_Tool/ref_font/simsun.ttc
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|