SuperModelingFactory 0.3.4__tar.gz → 0.3.6__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.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/_common.py +108 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/credit_model.py +106 -6
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/feature_validation.py +17 -1
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/__init__.py +1 -1
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/PKG-INFO +7 -4
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/README.md +6 -3
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/SuperModelingFactory.egg-info/PKG-INFO +7 -4
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/pyproject.toml +1 -1
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/setup.py +1 -1
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/ExcelMaster/ExcelFormatTool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/ExcelMaster/ExcelMaster.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/ExcelMaster/Template.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/ExcelMaster/Utility.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/ExcelMaster/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/LICENSE +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/MANIFEST.in +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Binning_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Binning_Tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Check_DuckDB_Compatibility.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Json_Data_Converter.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Model_Registry_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/ODPS_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Parallel_Engine.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Parallel_ODPS_Manager.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Proc_Compare.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Slope_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Slope_Tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/XOR_Encryptor.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/XOR_Encryptor.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/kDataFrame.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/kDataFrame.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/sample_weight_utils.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/utils.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/Evaluation_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/Evaluation_Tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/Model_Eval_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/Model_Eval_Tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/evaluate_model.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/evaluate_model.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/weighted_eval_utils.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Explainability/Coalition_Structure.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Explainability/Model_Explainer.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Explainability/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/Distribution_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/Distribution_Tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/Feature_Insights.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/Feature_Insights.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/PSI_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/PSI_Tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/WOE_Engine_Feature_Patch.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Model/Backward_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Model/Backward_Tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Model/GBM_Search_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Model/GBM_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Model/GBM_Tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Model/LRM_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Model/LRM_Tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Model/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/mock_sample.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/reject_inference.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/sample_analysis.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/score_comparison.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/score_consistency_uat.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Sample/Distribution_Adaptation.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Sample/Distribution_Adaptation.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Sample/Reject_Infer.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Sample/Reject_Infer.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Sample/Sample_Split.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Sample/Sample_Split.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Sample/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/UAT/UAT_Consistency_Checker.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/UAT/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Adapter.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Adapter.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Master.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Master.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Monotone_Binner.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Monotone_Binner.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Plot_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Plot_Tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Report_Builder.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Report_Builder.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/plot_woe_tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/plot_woe_tool.pyi +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/ref_font/KaiTi.ttf +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/ref_font/WeiRuanYaHei.ttf +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/ref_font/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/ref_font/simsun.ttc +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Report/Report_Tool.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Report/__init__.py +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/SuperModelingFactory.egg-info/SOURCES.txt +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/SuperModelingFactory.egg-info/dependency_links.txt +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/SuperModelingFactory.egg-info/not-zip-safe +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/SuperModelingFactory.egg-info/requires.txt +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/SuperModelingFactory.egg-info/top_level.txt +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/requirements.txt +0 -0
- {supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/setup.cfg +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
+
import re
|
|
4
5
|
from dataclasses import fields, is_dataclass
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
from typing import Any, Iterable, Mapping
|
|
@@ -8,6 +9,36 @@ from typing import Any, Iterable, Mapping
|
|
|
8
9
|
import numpy as np
|
|
9
10
|
import pandas as pd
|
|
10
11
|
|
|
12
|
+
_QUERY_COLUMN_RE = re.compile(r"(?<!['\"])\b([A-Za-z_][\w]*)\b(?![\'\"])")
|
|
13
|
+
_QUERY_RESERVED = frozenset(
|
|
14
|
+
{
|
|
15
|
+
"and",
|
|
16
|
+
"or",
|
|
17
|
+
"not",
|
|
18
|
+
"True",
|
|
19
|
+
"False",
|
|
20
|
+
"None",
|
|
21
|
+
"in",
|
|
22
|
+
"is",
|
|
23
|
+
"where",
|
|
24
|
+
"if",
|
|
25
|
+
"else",
|
|
26
|
+
"lambda",
|
|
27
|
+
"abs",
|
|
28
|
+
"all",
|
|
29
|
+
"any",
|
|
30
|
+
"max",
|
|
31
|
+
"min",
|
|
32
|
+
"sum",
|
|
33
|
+
"len",
|
|
34
|
+
"round",
|
|
35
|
+
"float",
|
|
36
|
+
"int",
|
|
37
|
+
"str",
|
|
38
|
+
"bool",
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
|
|
11
42
|
|
|
12
43
|
def make_dirs(*paths: str | os.PathLike | None) -> None:
|
|
13
44
|
for path in paths:
|
|
@@ -29,6 +60,83 @@ def merge_dict(base: Mapping[str, Any] | None, override: Mapping[str, Any] | Non
|
|
|
29
60
|
return merged
|
|
30
61
|
|
|
31
62
|
|
|
63
|
+
def query_referenced_columns(expr: str) -> set[str]:
|
|
64
|
+
"""Return identifier-like column names referenced in a pandas query expression."""
|
|
65
|
+
if not expr or not str(expr).strip():
|
|
66
|
+
return set()
|
|
67
|
+
return {
|
|
68
|
+
match.group(1)
|
|
69
|
+
for match in _QUERY_COLUMN_RE.finditer(str(expr))
|
|
70
|
+
if match.group(1) not in _QUERY_RESERVED
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def validate_woe_fit_query_syntax(data: pd.DataFrame, query: str) -> None:
|
|
75
|
+
"""Raise ValueError when a woe_fit_query expression is syntactically invalid."""
|
|
76
|
+
if not query:
|
|
77
|
+
return
|
|
78
|
+
sample = data.head(min(100, len(data)))
|
|
79
|
+
if sample.empty:
|
|
80
|
+
raise ValueError("woe_fit_query cannot be validated on an empty dataset.")
|
|
81
|
+
try:
|
|
82
|
+
sample.query(query, engine="python")
|
|
83
|
+
except SyntaxError as exc:
|
|
84
|
+
raise ValueError(f"Invalid woe_fit_query syntax: {query!r}") from exc
|
|
85
|
+
except Exception as exc:
|
|
86
|
+
raise ValueError(f"woe_fit_query failed on sample data: {query!r} ({exc})") from exc
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def validate_woe_fit_query_columns(
|
|
90
|
+
query: str,
|
|
91
|
+
available_cols: Iterable[str],
|
|
92
|
+
*,
|
|
93
|
+
context: str = "dataset",
|
|
94
|
+
) -> None:
|
|
95
|
+
"""Raise KeyError when query references columns missing from available_cols."""
|
|
96
|
+
if not query:
|
|
97
|
+
return
|
|
98
|
+
available = set(available_cols)
|
|
99
|
+
missing = sorted(query_referenced_columns(query) - available)
|
|
100
|
+
if missing:
|
|
101
|
+
raise KeyError(
|
|
102
|
+
f"woe_fit_query references missing columns in {context}: {missing}. "
|
|
103
|
+
"Add them to the input data, batch_base_cols, or population_dims."
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def apply_woe_fit_query(
|
|
108
|
+
train: pd.DataFrame,
|
|
109
|
+
query: str | None,
|
|
110
|
+
*,
|
|
111
|
+
target: str | None = None,
|
|
112
|
+
) -> tuple[pd.DataFrame, dict[str, Any] | None]:
|
|
113
|
+
"""Filter WOE fit rows via pandas query and return an audit row for refine_summary."""
|
|
114
|
+
if not query:
|
|
115
|
+
return train, None
|
|
116
|
+
n_before = len(train)
|
|
117
|
+
try:
|
|
118
|
+
filtered = train.query(query, engine="python").copy()
|
|
119
|
+
except Exception as exc:
|
|
120
|
+
audit = {
|
|
121
|
+
"target": target,
|
|
122
|
+
"step": "fit_filter",
|
|
123
|
+
"status": "error",
|
|
124
|
+
"query": query,
|
|
125
|
+
"n_before": n_before,
|
|
126
|
+
"error": repr(exc),
|
|
127
|
+
}
|
|
128
|
+
return train, audit
|
|
129
|
+
audit = {
|
|
130
|
+
"target": target,
|
|
131
|
+
"step": "fit_filter",
|
|
132
|
+
"status": "ok",
|
|
133
|
+
"query": query,
|
|
134
|
+
"n_before": n_before,
|
|
135
|
+
"n_after": len(filtered),
|
|
136
|
+
}
|
|
137
|
+
return filtered, audit
|
|
138
|
+
|
|
139
|
+
|
|
32
140
|
def dataclass_to_dict(obj: Any) -> dict[str, Any]:
|
|
33
141
|
if not is_dataclass(obj):
|
|
34
142
|
return dict(obj)
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/credit_model.py
RENAMED
|
@@ -9,11 +9,14 @@ import pandas as pd
|
|
|
9
9
|
|
|
10
10
|
from ._common import (
|
|
11
11
|
add_dataset_with_optional_weight,
|
|
12
|
+
apply_woe_fit_query,
|
|
12
13
|
as_list,
|
|
13
14
|
make_dirs,
|
|
14
15
|
merge_dict,
|
|
15
16
|
predict_positive,
|
|
16
17
|
safe_to_csv,
|
|
18
|
+
validate_woe_fit_query_columns,
|
|
19
|
+
validate_woe_fit_query_syntax,
|
|
17
20
|
write_basic_excel,
|
|
18
21
|
)
|
|
19
22
|
|
|
@@ -26,6 +29,7 @@ class CreditModelPipelineConfig:
|
|
|
26
29
|
split_col: str | None = None
|
|
27
30
|
sample_col: str = "sample_ind"
|
|
28
31
|
oot_col: str | None = "oot_flag"
|
|
32
|
+
weight_col: str | None = None
|
|
29
33
|
random_state: int = 42
|
|
30
34
|
write_outputs: bool = True
|
|
31
35
|
write_excel: bool = True
|
|
@@ -47,6 +51,8 @@ class CreditModelPipelineConfig:
|
|
|
47
51
|
}
|
|
48
52
|
)
|
|
49
53
|
woe_engine: str = "equal_freq"
|
|
54
|
+
woe_fit_query: str | None = None
|
|
55
|
+
extra_eval_datasets: dict[str, pd.DataFrame] | None = None
|
|
50
56
|
woe_params: dict[str, Any] = field(
|
|
51
57
|
default_factory=lambda: {"nbins": 10, "equal_freq": True, "min_bin_prop": 0.05}
|
|
52
58
|
)
|
|
@@ -207,7 +213,11 @@ class CreditModelPipeline:
|
|
|
207
213
|
models = self._train_models(model_inputs)
|
|
208
214
|
|
|
209
215
|
optuna_results = self._run_optuna(model_inputs)
|
|
210
|
-
perf_results = self._evaluate_models(
|
|
216
|
+
perf_results = self._evaluate_models(
|
|
217
|
+
model_inputs,
|
|
218
|
+
models,
|
|
219
|
+
woe_artifacts.get("extra_eval"),
|
|
220
|
+
)
|
|
211
221
|
explain_outputs = self._run_explainability(model_inputs, models)
|
|
212
222
|
model_paths: dict[str, str] = {}
|
|
213
223
|
artifact_paths: dict[str, str] = {}
|
|
@@ -283,6 +293,8 @@ class CreditModelPipeline:
|
|
|
283
293
|
excluded.add(cfg.split_col)
|
|
284
294
|
if cfg.oot_col:
|
|
285
295
|
excluded.add(cfg.oot_col)
|
|
296
|
+
if cfg.weight_col:
|
|
297
|
+
excluded.add(cfg.weight_col)
|
|
286
298
|
numeric_cols = data.select_dtypes(include=[np.number]).columns
|
|
287
299
|
return [col for col in numeric_cols if col not in excluded]
|
|
288
300
|
|
|
@@ -292,6 +304,12 @@ class CreditModelPipeline:
|
|
|
292
304
|
missing = [col for col in missing if col not in data.columns]
|
|
293
305
|
if missing:
|
|
294
306
|
raise KeyError(f"Missing required columns: {missing}")
|
|
307
|
+
if cfg.weight_col:
|
|
308
|
+
if cfg.weight_col not in data.columns:
|
|
309
|
+
raise KeyError(f"Missing weight_col {cfg.weight_col!r}")
|
|
310
|
+
from Modeling_Tool.Core.sample_weight_utils import resolve_sample_weight
|
|
311
|
+
|
|
312
|
+
resolve_sample_weight(data=data, weight_col=cfg.weight_col, expected_len=len(data))
|
|
295
313
|
if cfg.warm_start_enabled:
|
|
296
314
|
if not cfg.warm_start_score_col:
|
|
297
315
|
raise ValueError("warm_start_score_col is required when warm_start_enabled=True")
|
|
@@ -301,6 +319,38 @@ class CreditModelPipeline:
|
|
|
301
319
|
raise ValueError("warm_start_score_type must be 'probability' or 'log_odds'")
|
|
302
320
|
if cfg.warm_start_on_unsupported not in {"skip", "raise"}:
|
|
303
321
|
raise ValueError("warm_start_on_unsupported must be 'skip' or 'raise'")
|
|
322
|
+
if cfg.woe_fit_query:
|
|
323
|
+
validate_woe_fit_query_columns(cfg.woe_fit_query, data.columns, context="input data")
|
|
324
|
+
validate_woe_fit_query_syntax(data, cfg.woe_fit_query)
|
|
325
|
+
if cfg.extra_eval_datasets:
|
|
326
|
+
reserved = {"ins", "oos", "oot"}
|
|
327
|
+
conflicts = sorted(set(cfg.extra_eval_datasets) & reserved)
|
|
328
|
+
if conflicts:
|
|
329
|
+
raise ValueError(
|
|
330
|
+
f"extra_eval_datasets names cannot conflict with split names {sorted(reserved)}: {conflicts}"
|
|
331
|
+
)
|
|
332
|
+
for name, extra_df in cfg.extra_eval_datasets.items():
|
|
333
|
+
if cfg.target_col not in extra_df.columns:
|
|
334
|
+
raise KeyError(f"extra_eval_datasets[{name!r}] missing target_col {cfg.target_col!r}")
|
|
335
|
+
if cfg.warm_start_enabled and cfg.warm_start_score_col and cfg.warm_start_score_col not in extra_df.columns:
|
|
336
|
+
raise KeyError(
|
|
337
|
+
f"extra_eval_datasets[{name!r}] missing warm_start_score_col {cfg.warm_start_score_col!r}"
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
def _gbm_weight_kwargs(self, train: pd.DataFrame, val: pd.DataFrame) -> dict[str, Any]:
|
|
341
|
+
cfg = self.config
|
|
342
|
+
if not cfg.weight_col:
|
|
343
|
+
return {}
|
|
344
|
+
from Modeling_Tool.Core.sample_weight_utils import resolve_sample_weight
|
|
345
|
+
|
|
346
|
+
kwargs: dict[str, Any] = {}
|
|
347
|
+
train_sw = resolve_sample_weight(data=train, weight_col=cfg.weight_col, expected_len=len(train))
|
|
348
|
+
if train_sw is not None:
|
|
349
|
+
kwargs["sample_weight"] = train_sw
|
|
350
|
+
eval_sw = resolve_sample_weight(data=val, weight_col=cfg.weight_col, expected_len=len(val))
|
|
351
|
+
if eval_sw is not None:
|
|
352
|
+
kwargs["eval_sample_weight"] = eval_sw
|
|
353
|
+
return kwargs
|
|
304
354
|
|
|
305
355
|
def _validate_gbm_feature_source_config(self) -> None:
|
|
306
356
|
source_cfg = self.config.gbm_feature_source
|
|
@@ -442,6 +492,24 @@ class CreditModelPipeline:
|
|
|
442
492
|
summary["final_features"] = list(current)
|
|
443
493
|
return summary, list(current)
|
|
444
494
|
|
|
495
|
+
def _transform_extra_eval_datasets(
|
|
496
|
+
self,
|
|
497
|
+
transform_fn: Any,
|
|
498
|
+
feature_cols: list[str],
|
|
499
|
+
*,
|
|
500
|
+
woe_suffix: str | None = None,
|
|
501
|
+
) -> dict[str, pd.DataFrame]:
|
|
502
|
+
cfg = self.config
|
|
503
|
+
if not cfg.extra_eval_datasets:
|
|
504
|
+
return {}
|
|
505
|
+
transformed: dict[str, pd.DataFrame] = {}
|
|
506
|
+
for name, df in cfg.extra_eval_datasets.items():
|
|
507
|
+
if woe_suffix is not None:
|
|
508
|
+
transformed[name] = transform_fn(df, varlist=feature_cols, suffix=woe_suffix)
|
|
509
|
+
else:
|
|
510
|
+
transformed[name] = transform_fn(df)
|
|
511
|
+
return transformed
|
|
512
|
+
|
|
445
513
|
def _fit_woe(self, splits: dict[str, pd.DataFrame], feature_cols: list[str]) -> dict[str, Any]:
|
|
446
514
|
from Modeling_Tool import MonotoneWOEBinner, WOE_Master
|
|
447
515
|
from Modeling_Tool.WOE.WOE_Adapter import as_woe_engine
|
|
@@ -451,6 +519,11 @@ class CreditModelPipeline:
|
|
|
451
519
|
woe_suffix = cfg.woe_params.get("woe_suffix", "_woe")
|
|
452
520
|
graph_dir = str(Path(cfg.output_dir) / "figs" / "woe")
|
|
453
521
|
woe_features = [f"{col}{woe_suffix}" for col in feature_cols]
|
|
522
|
+
fit_ins, _ = apply_woe_fit_query(
|
|
523
|
+
splits["ins"],
|
|
524
|
+
cfg.woe_fit_query,
|
|
525
|
+
target=cfg.target_col,
|
|
526
|
+
)
|
|
454
527
|
|
|
455
528
|
if cfg.woe_engine.lower() == "monotone":
|
|
456
529
|
params = merge_dict(
|
|
@@ -462,7 +535,7 @@ class CreditModelPipeline:
|
|
|
462
535
|
cfg.monotone_woe_params,
|
|
463
536
|
)
|
|
464
537
|
binner = MonotoneWOEBinner(**params)
|
|
465
|
-
binner.fit(
|
|
538
|
+
binner.fit(fit_ins, chi2_binning=bool(cfg.monotone_woe_params.get("chi2_binning", False)))
|
|
466
539
|
if cfg.write_outputs and cfg.plot_outputs:
|
|
467
540
|
binner.plot_woe_graph(graph_path=str(Path(cfg.output_dir) / "figs" / "mono_woe"))
|
|
468
541
|
adapter = as_woe_engine(binner, woe_suffix=woe_suffix)
|
|
@@ -472,9 +545,14 @@ class CreditModelPipeline:
|
|
|
472
545
|
}
|
|
473
546
|
woe_table = adapter.get_woe_table(varlist=feature_cols)
|
|
474
547
|
engine = adapter
|
|
548
|
+
extra_eval = self._transform_extra_eval_datasets(
|
|
549
|
+
adapter.transform,
|
|
550
|
+
feature_cols,
|
|
551
|
+
woe_suffix=woe_suffix,
|
|
552
|
+
)
|
|
475
553
|
else:
|
|
476
554
|
master = WOE_Master(
|
|
477
|
-
train_data=
|
|
555
|
+
train_data=fit_ins,
|
|
478
556
|
varlist=feature_cols,
|
|
479
557
|
dep=cfg.target_col,
|
|
480
558
|
graph_save_dir=graph_dir,
|
|
@@ -494,13 +572,18 @@ class CreditModelPipeline:
|
|
|
494
572
|
dirname="overall",
|
|
495
573
|
varlist=feature_cols,
|
|
496
574
|
)
|
|
497
|
-
woe_table = get_overall_woe_table(master,
|
|
575
|
+
woe_table = get_overall_woe_table(master, fit_ins, varlist=feature_cols)
|
|
498
576
|
engine = master
|
|
577
|
+
extra_eval = self._transform_extra_eval_datasets(master.transform, feature_cols)
|
|
499
578
|
|
|
500
579
|
if cfg.warm_start_enabled and cfg.warm_start_score_col:
|
|
501
580
|
for name, df in woe_splits.items():
|
|
502
581
|
if cfg.warm_start_score_col not in df.columns:
|
|
503
582
|
df[cfg.warm_start_score_col] = splits[name][cfg.warm_start_score_col].to_numpy()
|
|
583
|
+
for name, df in extra_eval.items():
|
|
584
|
+
if cfg.warm_start_score_col not in df.columns:
|
|
585
|
+
source = cfg.extra_eval_datasets[name]
|
|
586
|
+
df[cfg.warm_start_score_col] = source[cfg.warm_start_score_col].to_numpy()
|
|
504
587
|
|
|
505
588
|
return {
|
|
506
589
|
"engine": engine,
|
|
@@ -509,6 +592,7 @@ class CreditModelPipeline:
|
|
|
509
592
|
"woe_features": woe_features,
|
|
510
593
|
"woe_suffix": woe_suffix,
|
|
511
594
|
"splits": woe_splits,
|
|
595
|
+
"extra_eval": extra_eval,
|
|
512
596
|
"woe_table": woe_table,
|
|
513
597
|
}
|
|
514
598
|
|
|
@@ -614,6 +698,7 @@ class CreditModelPipeline:
|
|
|
614
698
|
val_data=val,
|
|
615
699
|
val_varlist=feature_cols,
|
|
616
700
|
val_tgt_name=cfg.target_col,
|
|
701
|
+
weight_col=cfg.weight_col,
|
|
617
702
|
)
|
|
618
703
|
models[name] = (lr, getattr(lr, "model", lr), list(feature_cols))
|
|
619
704
|
elif name in {"lgb", "xgb", "cat"}:
|
|
@@ -629,6 +714,7 @@ class CreditModelPipeline:
|
|
|
629
714
|
valx=val[feature_cols],
|
|
630
715
|
valy=val[cfg.target_col].astype(int),
|
|
631
716
|
init_score=init_score,
|
|
717
|
+
**self._gbm_weight_kwargs(train, val),
|
|
632
718
|
)
|
|
633
719
|
raw = gbm._model.model if hasattr(gbm, "_model") else gbm
|
|
634
720
|
models[name] = (gbm, raw, list(feature_cols))
|
|
@@ -651,6 +737,8 @@ class CreditModelPipeline:
|
|
|
651
737
|
"model_type": f"{cfg.backward_model}m" if cfg.backward_model == "lgb" else cfg.backward_model,
|
|
652
738
|
"validation_data": splits["oos"],
|
|
653
739
|
"test_data_dict": {"oot": splits["oot"]},
|
|
740
|
+
"weight_col": cfg.weight_col,
|
|
741
|
+
"validation_weight_col": cfg.weight_col,
|
|
654
742
|
},
|
|
655
743
|
cfg.backward_params.get("init", {}),
|
|
656
744
|
)
|
|
@@ -711,6 +799,8 @@ class CreditModelPipeline:
|
|
|
711
799
|
tgt_name=cfg.target_col,
|
|
712
800
|
eval_sets={"oos": splits["oos"], "oot": splits["oot"]},
|
|
713
801
|
param_grid=cfg.lr_search_param_grid,
|
|
802
|
+
weight_col=cfg.weight_col,
|
|
803
|
+
eval_weight_col=cfg.weight_col,
|
|
714
804
|
**params,
|
|
715
805
|
)
|
|
716
806
|
self._lr_best_params = dict(getattr(lr, "best_params_", {}) or {})
|
|
@@ -831,6 +921,8 @@ class CreditModelPipeline:
|
|
|
831
921
|
data=splits["ins"],
|
|
832
922
|
search_space=search_spaces[name],
|
|
833
923
|
fit_kwargs=fit_kwargs or None,
|
|
924
|
+
weight_col=cfg.weight_col,
|
|
925
|
+
eval_weight_col=cfg.weight_col,
|
|
834
926
|
**common,
|
|
835
927
|
)
|
|
836
928
|
except Exception as exc:
|
|
@@ -841,13 +933,20 @@ class CreditModelPipeline:
|
|
|
841
933
|
self,
|
|
842
934
|
model_inputs: dict[str, dict[str, Any]],
|
|
843
935
|
models: dict[str, tuple[Any, Any, list[str]]],
|
|
936
|
+
extra_eval_splits: dict[str, pd.DataFrame] | None = None,
|
|
844
937
|
) -> dict[str, pd.DataFrame]:
|
|
845
938
|
from Modeling_Tool import PerformanceEvaluator
|
|
846
939
|
|
|
847
940
|
cfg = self.config
|
|
848
941
|
results = {}
|
|
942
|
+
extra_eval_splits = extra_eval_splits or {}
|
|
849
943
|
for name, (wrapper, _, feature_cols) in models.items():
|
|
850
944
|
splits = model_inputs[name]["splits"]
|
|
945
|
+
source = str(model_inputs[name].get("source", "woe")).lower()
|
|
946
|
+
if source == "raw" and cfg.extra_eval_datasets:
|
|
947
|
+
model_extra = {key: df.copy() for key, df in cfg.extra_eval_datasets.items()}
|
|
948
|
+
else:
|
|
949
|
+
model_extra = extra_eval_splits
|
|
851
950
|
evaluator = PerformanceEvaluator(
|
|
852
951
|
tgt_name=cfg.target_col,
|
|
853
952
|
scr_name=f"pred_{name}",
|
|
@@ -855,10 +954,11 @@ class CreditModelPipeline:
|
|
|
855
954
|
min_bin_prop=cfg.perf_min_bin_prop,
|
|
856
955
|
equal_freq=True,
|
|
857
956
|
)
|
|
858
|
-
|
|
957
|
+
eval_splits = {**splits, **model_extra}
|
|
958
|
+
for ds_name, df in eval_splits.items():
|
|
859
959
|
scored = df.copy()
|
|
860
960
|
scored[f"pred_{name}"] = self._predict_model_positive(name, wrapper, scored, feature_cols)
|
|
861
|
-
add_dataset_with_optional_weight(evaluator, ds_name, scored)
|
|
961
|
+
add_dataset_with_optional_weight(evaluator, ds_name, scored, weight_col=cfg.weight_col)
|
|
862
962
|
fig_save_path = None
|
|
863
963
|
if cfg.write_outputs and cfg.plot_outputs:
|
|
864
964
|
fig_save_path = str(Path(cfg.output_dir) / "figs" / "perf" / f"perf_{name}.png")
|
|
@@ -8,7 +8,14 @@ from typing import Any, Literal
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
import pandas as pd
|
|
10
10
|
|
|
11
|
-
from ._common import
|
|
11
|
+
from ._common import (
|
|
12
|
+
apply_woe_fit_query,
|
|
13
|
+
as_list,
|
|
14
|
+
make_dirs,
|
|
15
|
+
safe_to_csv,
|
|
16
|
+
validate_woe_fit_query_columns,
|
|
17
|
+
validate_woe_fit_query_syntax,
|
|
18
|
+
)
|
|
12
19
|
|
|
13
20
|
|
|
14
21
|
@dataclass
|
|
@@ -47,6 +54,7 @@ class FeatureValidationPipelineConfig:
|
|
|
47
54
|
)
|
|
48
55
|
|
|
49
56
|
woe_enabled: bool = True
|
|
57
|
+
woe_fit_query: str | None = None
|
|
50
58
|
woe_engine: str = "monotone"
|
|
51
59
|
woe_params: dict[str, Any] = field(
|
|
52
60
|
default_factory=lambda: {"nbins": 10, "equal_freq": True, "min_bin_prop": 0.05}
|
|
@@ -257,6 +265,8 @@ class FeatureValidationPipeline:
|
|
|
257
265
|
self._validate_batch_config(new_features)
|
|
258
266
|
feature_batches = self._make_feature_batches(new_features)
|
|
259
267
|
base_cols = self._resolve_batch_base_cols(header, incumbent_features, target_cols)
|
|
268
|
+
if cfg.woe_fit_query:
|
|
269
|
+
validate_woe_fit_query_columns(cfg.woe_fit_query, base_cols, context="CSV batch base columns")
|
|
260
270
|
|
|
261
271
|
base_df = self._read_csv(csv_path, usecols=base_cols).copy()
|
|
262
272
|
base_df["_smf_batch_row_id"] = np.arange(len(base_df))
|
|
@@ -777,6 +787,9 @@ class FeatureValidationPipeline:
|
|
|
777
787
|
raise ValueError("psi_reference_dataset must be one of ins/oos/oot/external")
|
|
778
788
|
if cfg.psi_reference_dataset == "external" and cfg.psi_reference_data is None:
|
|
779
789
|
raise ValueError("psi_reference_data is required when psi_reference_dataset='external'")
|
|
790
|
+
if cfg.woe_fit_query:
|
|
791
|
+
validate_woe_fit_query_columns(cfg.woe_fit_query, data.columns, context="input data")
|
|
792
|
+
validate_woe_fit_query_syntax(data, cfg.woe_fit_query)
|
|
780
793
|
|
|
781
794
|
def _resolve_new_features(self, data: pd.DataFrame) -> list[str]:
|
|
782
795
|
cfg = self.config
|
|
@@ -979,6 +992,9 @@ class FeatureValidationPipeline:
|
|
|
979
992
|
refine_rows = []
|
|
980
993
|
for target in target_cols:
|
|
981
994
|
train = splits["ins"][splits["ins"][target].notna()].copy()
|
|
995
|
+
train, fit_filter_row = apply_woe_fit_query(train, cfg.woe_fit_query, target=target)
|
|
996
|
+
if fit_filter_row is not None:
|
|
997
|
+
refine_rows.append(fit_filter_row)
|
|
982
998
|
if len(train) < max(10, cfg.min_group_size):
|
|
983
999
|
refine_rows.append({"target": target, "step": "fit", "status": "skipped_min_group_size", "n": len(train)})
|
|
984
1000
|
continue
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SuperModelingFactory
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.6
|
|
4
4
|
Summary: Credit risk modeling factory: WOE binning, scorecards, LightGBM, Excel reporting.
|
|
5
5
|
Home-page: https://github.com/Kyle-J-Sun/SuperModelingFactory
|
|
6
6
|
Author: Kyle Sun
|
|
@@ -114,7 +114,10 @@ SuperModelingFactory/
|
|
|
114
114
|
│ ├── Feature/ # 特征分析:分布偏移、PSI、相关性过滤
|
|
115
115
|
│ ├── Model/ # 模型训练:LR、LightGBM、XGBoost、变量选择
|
|
116
116
|
│ ├── Eval/ # 模型评估:Gains 表、ROC/KS、性能汇总
|
|
117
|
-
│
|
|
117
|
+
│ ├── Sample/ # 样本管理:切分、分层、拒绝推断、分布适配
|
|
118
|
+
│ ├── Explainability/ # 模型解释:SHAP、LIME、PDP、ICE、ALE、Owen
|
|
119
|
+
│ ├── Pipeline/ # 一键流水线:特征验收、信用建模、拒绝推断等
|
|
120
|
+
│ └── UAT/ # 线上线下分数一致性校验
|
|
118
121
|
├── ExcelMaster/ # Excel 报告引擎
|
|
119
122
|
│ ├── ExcelFormatTool.py # 格式定义(50+ 预设单元格格式)
|
|
120
123
|
│ ├── ExcelMaster.py # 核心引擎(光标流式写入、图表、条件格式)
|
|
@@ -262,9 +265,9 @@ em.close_workbook()
|
|
|
262
265
|
|
|
263
266
|
## 版本
|
|
264
267
|
|
|
265
|
-
- **Version**: 0.3.
|
|
268
|
+
- **Version**: 0.3.6
|
|
266
269
|
- **Author**: Jingkai Sun
|
|
267
270
|
|
|
268
271
|
## 许可证
|
|
269
272
|
|
|
270
|
-
|
|
273
|
+
本项目采用 **Business Source License 1.1**(Change Date **2030-06-24**)。详见文首 [许可证](#许可证) 一节与 [LICENSE](LICENSE) 全文。
|
|
@@ -57,7 +57,10 @@ SuperModelingFactory/
|
|
|
57
57
|
│ ├── Feature/ # 特征分析:分布偏移、PSI、相关性过滤
|
|
58
58
|
│ ├── Model/ # 模型训练:LR、LightGBM、XGBoost、变量选择
|
|
59
59
|
│ ├── Eval/ # 模型评估:Gains 表、ROC/KS、性能汇总
|
|
60
|
-
│
|
|
60
|
+
│ ├── Sample/ # 样本管理:切分、分层、拒绝推断、分布适配
|
|
61
|
+
│ ├── Explainability/ # 模型解释:SHAP、LIME、PDP、ICE、ALE、Owen
|
|
62
|
+
│ ├── Pipeline/ # 一键流水线:特征验收、信用建模、拒绝推断等
|
|
63
|
+
│ └── UAT/ # 线上线下分数一致性校验
|
|
61
64
|
├── ExcelMaster/ # Excel 报告引擎
|
|
62
65
|
│ ├── ExcelFormatTool.py # 格式定义(50+ 预设单元格格式)
|
|
63
66
|
│ ├── ExcelMaster.py # 核心引擎(光标流式写入、图表、条件格式)
|
|
@@ -205,9 +208,9 @@ em.close_workbook()
|
|
|
205
208
|
|
|
206
209
|
## 版本
|
|
207
210
|
|
|
208
|
-
- **Version**: 0.3.
|
|
211
|
+
- **Version**: 0.3.6
|
|
209
212
|
- **Author**: Jingkai Sun
|
|
210
213
|
|
|
211
214
|
## 许可证
|
|
212
215
|
|
|
213
|
-
|
|
216
|
+
本项目采用 **Business Source License 1.1**(Change Date **2030-06-24**)。详见文首 [许可证](#许可证) 一节与 [LICENSE](LICENSE) 全文。
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/SuperModelingFactory.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SuperModelingFactory
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.6
|
|
4
4
|
Summary: Credit risk modeling factory: WOE binning, scorecards, LightGBM, Excel reporting.
|
|
5
5
|
Home-page: https://github.com/Kyle-J-Sun/SuperModelingFactory
|
|
6
6
|
Author: Kyle Sun
|
|
@@ -114,7 +114,10 @@ SuperModelingFactory/
|
|
|
114
114
|
│ ├── Feature/ # 特征分析:分布偏移、PSI、相关性过滤
|
|
115
115
|
│ ├── Model/ # 模型训练:LR、LightGBM、XGBoost、变量选择
|
|
116
116
|
│ ├── Eval/ # 模型评估:Gains 表、ROC/KS、性能汇总
|
|
117
|
-
│
|
|
117
|
+
│ ├── Sample/ # 样本管理:切分、分层、拒绝推断、分布适配
|
|
118
|
+
│ ├── Explainability/ # 模型解释:SHAP、LIME、PDP、ICE、ALE、Owen
|
|
119
|
+
│ ├── Pipeline/ # 一键流水线:特征验收、信用建模、拒绝推断等
|
|
120
|
+
│ └── UAT/ # 线上线下分数一致性校验
|
|
118
121
|
├── ExcelMaster/ # Excel 报告引擎
|
|
119
122
|
│ ├── ExcelFormatTool.py # 格式定义(50+ 预设单元格格式)
|
|
120
123
|
│ ├── ExcelMaster.py # 核心引擎(光标流式写入、图表、条件格式)
|
|
@@ -262,9 +265,9 @@ em.close_workbook()
|
|
|
262
265
|
|
|
263
266
|
## 版本
|
|
264
267
|
|
|
265
|
-
- **Version**: 0.3.
|
|
268
|
+
- **Version**: 0.3.6
|
|
266
269
|
- **Author**: Jingkai Sun
|
|
267
270
|
|
|
268
271
|
## 许可证
|
|
269
272
|
|
|
270
|
-
|
|
273
|
+
本项目采用 **Business Source License 1.1**(Change Date **2030-06-24**)。详见文首 [许可证](#许可证) 一节与 [LICENSE](LICENSE) 全文。
|
|
@@ -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.6"
|
|
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.6"),
|
|
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.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Binning_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Binning_Tool.pyi
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Json_Data_Converter.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Model_Registry_Tool.py
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Parallel_Engine.py
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/Proc_Compare.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/XOR_Encryptor.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/XOR_Encryptor.pyi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Core/sample_weight_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/Evaluation_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/Evaluation_Tool.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/Model_Eval_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/Model_Eval_Tool.pyi
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/evaluate_model.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/evaluate_model.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Eval/weighted_eval_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Explainability/__init__.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/Distribution_Tool.py
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/Feature_Insights.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/Feature_Insights.pyi
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Feature/PSI_Tool.pyi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Model/Backward_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Model/Backward_Tool.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Model/GBM_Search_Tool.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/__init__.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/mock_sample.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/reject_inference.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/sample_analysis.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Pipeline/score_comparison.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Sample/Reject_Infer.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Sample/Reject_Infer.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Sample/Sample_Split.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/Sample/Sample_Split.pyi
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.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Monotone_Binner.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Monotone_Binner.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Plot_Tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Plot_Tool.pyi
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Report_Builder.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/WOE_Report_Builder.pyi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/plot_woe_tool.py
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/WOE/plot_woe_tool.pyi
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/ref_font/WeiRuanYaHei.ttf
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/Modeling_Tool/ref_font/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/SuperModelingFactory.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/SuperModelingFactory.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{supermodelingfactory-0.3.4 → supermodelingfactory-0.3.6}/SuperModelingFactory.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|