proscore 0.2.2__tar.gz → 0.2.3__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.
- {proscore-0.2.2/src/proscore.egg-info → proscore-0.2.3}/PKG-INFO +1 -1
- {proscore-0.2.2 → proscore-0.2.3}/pyproject.toml +1 -1
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/__init__.py +22 -16
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/__main__.py +2 -2
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/_data/__init__.py +9 -7
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/_pipeline_config.py +314 -244
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/_spec.py +1 -4
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/binning/_adjust.py +3 -9
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/binning/_binning.py +56 -79
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/binning/_categorical.py +1 -4
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/binning/_chi.py +6 -10
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/binning/_frequency.py +1 -3
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/evaluate/_diagnose.py +270 -168
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/evaluate/_metrics.py +30 -25
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/inspect/__init__.py +8 -2
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/inspect/_detect.py +18 -9
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/inspect/_quality.py +6 -20
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/inspect/_stability.py +16 -26
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/modeling/_scorecard.py +15 -14
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/monitor/_monitor.py +68 -44
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/report/_builder.py +339 -142
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/rules/_miner.py +52 -46
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/selection/_filter.py +30 -46
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/selection/_stepwise.py +17 -28
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/transform/_woe.py +12 -23
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/utils/__init__.py +3 -8
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/utils/_presets.py +3 -8
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/viz/_plots.py +3 -4
- {proscore-0.2.2 → proscore-0.2.3/src/proscore.egg-info}/PKG-INFO +1 -1
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_binning.py +17 -11
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_diagnose.py +3 -5
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_docs_examples.py +18 -31
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_evaluate.py +24 -12
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_evaluate_period.py +5 -2
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_filter.py +3 -3
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_inspect.py +16 -8
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_pipeline.py +5 -9
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_presets.py +15 -9
- proscore-0.2.3/tests/test_report.py +185 -0
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_rules.py +9 -8
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_scorecard.py +3 -5
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_spec.py +2 -16
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_stepwise.py +9 -8
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_transform.py +1 -0
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_woe.py +14 -8
- proscore-0.2.2/tests/test_report.py +0 -105
- {proscore-0.2.2 → proscore-0.2.3}/LICENSE +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/README.md +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/setup.cfg +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/binning/__init__.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/binning/_base.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/binning/_distance.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/binning/_tree.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/binning/_woe.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/evaluate/__init__.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/inspect/_correlation.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/modeling/__init__.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/monitor/__init__.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/report/__init__.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/rules/__init__.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/selection/__init__.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/selection/_screen.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/transform/__init__.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/utils/_config.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/utils/_exceptions.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/utils/_psi.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore/viz/__init__.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore.egg-info/SOURCES.txt +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore.egg-info/dependency_links.txt +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore.egg-info/entry_points.txt +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore.egg-info/requires.txt +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/src/proscore.egg-info/top_level.txt +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_pipeline_rules.py +0 -0
- {proscore-0.2.2 → proscore-0.2.3}/tests/test_screen.py +0 -0
|
@@ -19,7 +19,7 @@ from proscore.rules import RuleMiner
|
|
|
19
19
|
from proscore.selection import Filter, StepwiseSelector, assess_screen
|
|
20
20
|
from proscore.transform import WOETransformer
|
|
21
21
|
|
|
22
|
-
__version__ = "0.2.
|
|
22
|
+
__version__ = "0.2.3"
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class ProScore:
|
|
@@ -104,15 +104,13 @@ class ProScore:
|
|
|
104
104
|
|
|
105
105
|
def _categorical_features(self) -> list[str]:
|
|
106
106
|
return [
|
|
107
|
-
c for c in self.train_df.columns
|
|
108
|
-
if c != self.target and not pd.api.types.is_numeric_dtype(self.train_df[c])
|
|
107
|
+
c for c in self.train_df.columns if c != self.target and not pd.api.types.is_numeric_dtype(self.train_df[c])
|
|
109
108
|
]
|
|
110
109
|
|
|
111
110
|
def _initial_features(self) -> list[str]:
|
|
112
111
|
"""Numeric columns — the Filter candidate pool."""
|
|
113
112
|
return [
|
|
114
|
-
c for c in self.train_df.columns
|
|
115
|
-
if c != self.target and pd.api.types.is_numeric_dtype(self.train_df[c])
|
|
113
|
+
c for c in self.train_df.columns if c != self.target and pd.api.types.is_numeric_dtype(self.train_df[c])
|
|
116
114
|
]
|
|
117
115
|
|
|
118
116
|
def _numeric_after_prefilter(self) -> list[str]:
|
|
@@ -199,7 +197,8 @@ class ProScore:
|
|
|
199
197
|
features = self._initial_features()
|
|
200
198
|
self._prefilter = Filter(**kwargs)
|
|
201
199
|
self._prefilter.fit(
|
|
202
|
-
self._train_X(features),
|
|
200
|
+
self._train_X(features),
|
|
201
|
+
self._train_y(),
|
|
203
202
|
X_test=self._test_X(features) if self.test_df is not None else None,
|
|
204
203
|
bin_table=None,
|
|
205
204
|
)
|
|
@@ -278,7 +277,8 @@ class ProScore:
|
|
|
278
277
|
self._refine_skipped = False
|
|
279
278
|
self._filter = Filter(**kwargs)
|
|
280
279
|
self._filter.fit(
|
|
281
|
-
self._train_X(features),
|
|
280
|
+
self._train_X(features),
|
|
281
|
+
self._train_y(),
|
|
282
282
|
X_test=self._test_X(features) if self.test_df is not None else None,
|
|
283
283
|
bin_table=self._binner.bin_table_,
|
|
284
284
|
)
|
|
@@ -358,10 +358,8 @@ class ProScore:
|
|
|
358
358
|
_warn_halted(self)
|
|
359
359
|
return self
|
|
360
360
|
_check_transformer(self)
|
|
361
|
-
features = [c for c in self._features_for_modeling()
|
|
362
|
-
if c not in self._rule_features]
|
|
361
|
+
features = [c for c in self._features_for_modeling() if c not in self._rule_features]
|
|
363
362
|
train_woe = self._transformer.transform(self._train_X(features))
|
|
364
|
-
train_woe[self.target] = self._train_y().values
|
|
365
363
|
|
|
366
364
|
test_woe = None
|
|
367
365
|
y_test = None
|
|
@@ -372,8 +370,12 @@ class ProScore:
|
|
|
372
370
|
force_in = kwargs.pop("force_in", None)
|
|
373
371
|
self._selector = StepwiseSelector(**kwargs)
|
|
374
372
|
self._selector.fit(
|
|
375
|
-
train_woe,
|
|
376
|
-
|
|
373
|
+
train_woe,
|
|
374
|
+
self._train_y(),
|
|
375
|
+
candidates=features,
|
|
376
|
+
force_in=force_in,
|
|
377
|
+
X_test=test_woe,
|
|
378
|
+
y_test=y_test,
|
|
377
379
|
)
|
|
378
380
|
return self
|
|
379
381
|
|
|
@@ -419,10 +421,14 @@ class ProScore:
|
|
|
419
421
|
|
|
420
422
|
self.eval_result = _evaluate(
|
|
421
423
|
self._scorecard.model_,
|
|
422
|
-
train_woe,
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
424
|
+
train_woe,
|
|
425
|
+
self._train_y(),
|
|
426
|
+
X_test=test_woe,
|
|
427
|
+
y_test=self._test_y(),
|
|
428
|
+
X_oot=oot_woe,
|
|
429
|
+
y_oot=self._oot_y(),
|
|
430
|
+
features=features,
|
|
431
|
+
n_bins=n_bins,
|
|
426
432
|
)
|
|
427
433
|
return self
|
|
428
434
|
|
|
@@ -37,8 +37,7 @@ def _cmd_run(args: list[str]) -> None:
|
|
|
37
37
|
|
|
38
38
|
parser = argparse.ArgumentParser(description="Run a pipeline from Excel config")
|
|
39
39
|
parser.add_argument("config", help="Path to pipeline.xlsx")
|
|
40
|
-
parser.add_argument("--output-script", "-o", default=None,
|
|
41
|
-
help="Also generate a self-contained Python script")
|
|
40
|
+
parser.add_argument("--output-script", "-o", default=None, help="Also generate a self-contained Python script")
|
|
42
41
|
opts = parser.parse_args(args)
|
|
43
42
|
|
|
44
43
|
from proscore._pipeline_config import run_pipeline
|
|
@@ -51,6 +50,7 @@ def _cmd_run(args: list[str]) -> None:
|
|
|
51
50
|
except Exception as e:
|
|
52
51
|
print(f"运行错误: {e}", file=sys.stderr)
|
|
53
52
|
import traceback
|
|
53
|
+
|
|
54
54
|
traceback.print_exc()
|
|
55
55
|
sys.exit(1)
|
|
56
56
|
|
|
@@ -62,13 +62,15 @@ class DataReader:
|
|
|
62
62
|
rows = []
|
|
63
63
|
for col in self.features_:
|
|
64
64
|
s = self.df[col]
|
|
65
|
-
rows.append(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
rows.append(
|
|
66
|
+
{
|
|
67
|
+
"variable": col,
|
|
68
|
+
"dtype": str(s.dtype),
|
|
69
|
+
"n_missing": int(s.isna().sum()),
|
|
70
|
+
"missing_pct": round(s.isna().mean() * 100, 2),
|
|
71
|
+
"n_unique": int(s.nunique()),
|
|
72
|
+
}
|
|
73
|
+
)
|
|
72
74
|
return pd.DataFrame(rows).sort_values("missing_pct", ascending=False).reset_index(drop=True)
|
|
73
75
|
|
|
74
76
|
def __repr__(self) -> str:
|