Skip to main content

SuperModelingFactory

PyPI Python License: BSL 1.1 Build wheels Docs

SuperModelingFactory (SMF) is an end-to-end Python toolkit for credit-risk scorecard development and model governance: sample design, WOE binning, feature screening, model training, evaluation, explainability, online/offline consistency checks, and formatted Excel reporting, all behind one consistent API.

📖 Documentation: installation, quickstart, user guides, API reference, changelog.


New here? Start with this

SMF turns the usual scorecard workflow into a handful of composable building blocks. You can call each block yourself (full control), or hand a DataFrame to a one-click pipeline (fast, reproducible).

raw sample ─► split ─► WOE binning ─► feature screening ─► model ─► evaluation ─► explainability ─► Excel report
              │          │              (PSI / IV / corr)    (LR / LGB / XGB / CatBoost)              │
              └──────────┴──────────────── one-click pipelines wrap all of these ──────────────────────┘
You want to... Use
Split samples, balance classes, infer rejected applicants SampleSplitter, StratifiedSampler, SampleBalancer, RejectInferenceFactory
Bin variables and compute WOE / IV WOE_Master (numeric features), MonotoneWOEBinner (monotone bins, categorical features, special values)
Screen features by stability, information value, and correlation PSICalculator, VarExtractionInsights, CorrelationFilter, feature_screen
Train a model LRMaster (logistic regression), GradientBoostingModel (LightGBM / XGBoost / CatBoost)
Evaluate (KS, AUC, Gains, Lift, plots) PerformanceEvaluator, GainsTableCalculator, evaluate_performance
Explain a model (SHAP, Owen value, PDP, ICE, ALE, LIME) ModelExplainer
Produce an Excel report ExcelMaster, Report
Run the whole workflow in one call CreditModelPipeline and six other pipelines

SMF installs three top-level Python packages:

Import name Role
Modeling_Tool The modeling engine. Almost everything you need is importable as from Modeling_Tool import ...
ExcelMaster Programmatic Excel workbook writer (cursor-based, charts, conditional formatting)
Report Report templates that assemble modeling artifacts into Excel workbooks

Installation

pip install supermodelingfactory
  • Python 3.10, 3.11, 3.12, 3.13. Pre-built wheels are published for macOS arm64, Linux x86_64, and Windows x86_64. SMF ships plain Python source, so no compiler is needed on other platforms.
  • macOS only: brew install libomp (OpenMP runtime required by LightGBM).

Optional extras:

Extra Command Enables
odps pip install 'supermodelingfactory[odps]' Alibaba Cloud MaxCompute (ODPSRunner, proc_means_odps, ParallelODPSManager)
explain pip install 'supermodelingfactory[explain]' ModelExplainer: SHAP, Owen value, LIME
stats pip install 'supermodelingfactory[stats]' statsmodels-based VIF gates and logistic-regression diagnostics
imblearn pip install 'supermodelingfactory[imblearn]' SMOTE and imbalanced-learn samplers in StratifiedSampler / SampleBalancer
optuna pip install 'supermodelingfactory[optuna]' Optuna search in GradientBoostingModel.param_search and the pipelines
mic pip install 'supermodelingfactory[mic]' MIC correlation in build_coalition_structure (Python < 3.11 only)

Notebook display: PerformanceEvaluator.evaluate() prints its result table through IPython.display by default. In a plain script, either pass display=False (as below) or pip install ipython.

Verify the installation:

python -c "import Modeling_Tool; print(Modeling_Tool.__version__)"

Working from a source checkout instead:

git clone https://github.com/Kyle-J-Sun/SuperModelingFactory.git
cd SuperModelingFactory
pip install -e .

See INSTALL.md for troubleshooting.


Quickstart (about 5 minutes)

The script below is self-contained: it generates synthetic data, then runs split → WOE → screening → model → evaluation → Excel report. Copy it into a file and run it.

import numpy as np
import pandas as pd

from Modeling_Tool import (
    SampleSplitter, WOE_Master, PSICalculator, VarExtractionInsights, CorrelationFilter,
    GradientBoostingModel, PerformanceEvaluator, GainsTableCalculator,
)
from ExcelMaster.ExcelMaster import ExcelMaster

# 1. Synthetic data ---------------------------------------------------------------
rng = np.random.default_rng(42)
n = 6000
data = pd.DataFrame({
    "age": rng.normal(35, 8, n).clip(18, 70),
    "income": rng.lognormal(10, 0.4, n),
    "score_b": rng.normal(600, 60, n),
    "utilization": rng.uniform(0, 1, n),
    "n_overdue": rng.poisson(0.3, n),
})
logit = -2.2 - 0.02 * (data["score_b"] - 600) + 0.5 * data["n_overdue"] - 0.8 * data["utilization"]
data["bad_flag"] = rng.binomial(1, 1 / (1 + np.exp(-logit)))
features = ["age", "income", "score_b", "utilization", "n_overdue"]

# 2. Split (stratified by the target) ------------------------------------------------
train_df, test_df = SampleSplitter(test_size=0.3, random_state=42, stratify=True).split_df(
    data, target="bad_flag")

# 3. WOE binning and encoding (adds one `<feature>_woe` column per feature) ---------
woe = WOE_Master(train_data=train_df, varlist=features, dep="bad_flag")
woe.fit(nbins=10, equal_freq=True)
train_woe = woe.transform(train_df)
test_woe = woe.transform(test_df)

# 4. Feature screening: stability (PSI) -> information value (IV) -> correlation -----
psi = PSICalculator(buckets=10, binning_engine=woe).calculate(
    expected_df=train_df, current_data=test_df, varlist=features)
stable = psi.loc[psi["psi"] < 0.1, "var"].tolist()

iv_report = VarExtractionInsights(
    data=train_df, dep="bad_flag", plot_path="./iv_plots/", woe_binner=woe,
).get_var_analysis_report(train_df, stable)
keep_by_iv = iv_report.loc[iv_report["iv"] >= 0.02, "var"].tolist()

keep_vars = CorrelationFilter(
    data=train_df, dep="bad_flag", corr_cutpoint=0.7, woe_binner=woe,
).remove_highly_correlated(keep_by_iv)
woe_cols = [f"{v}_woe" for v in keep_vars]
print("selected features:", keep_vars)

# 5. Train a gradient-boosting model (LightGBM here; "xgb" and "cat" also work) ------
gbm = GradientBoostingModel("lgb", params={
    "n_estimators": 200, "learning_rate": 0.05, "max_depth": 3,
    "early_stopping_rounds": 20, "eval_metric": "auc", "verbose": -1,
})
gbm.fit(train_woe[woe_cols], train_woe["bad_flag"], test_woe[woe_cols], test_woe["bad_flag"])

# 6. Evaluate: KS / AUC / Top-decile lift per dataset -------------------------------------
perf = (
    PerformanceEvaluator(tgt_name="bad_flag", model=gbm, feature_cols=woe_cols)
    .add_dataset("train", train_woe)
    .add_dataset("test", test_woe)
    .evaluate(display=False)
)
print(perf[["index", "KS", "AUC"]])

# 7. Gains table on the test set -----------------------------------------------------------
scored = test_woe.copy()
scored["score"] = gbm.predict(test_woe[woe_cols])      # probability of bad
gains = GainsTableCalculator(data=scored, dep="bad_flag", score="score", nbins=10).calculate()

# 8. Excel report ---------------------------------------------------------------------------
em = ExcelMaster("model_report.xlsx", verbose=False)
ws = em.add_worksheet("Performance")
em.write_dataframe(ws, perf, title="Model performance", titleformat="BLUE_H2")
em.write_dataframe(ws, gains.reset_index(), title="Gains table (test)", titleformat="BLUE_H2")
em.close_workbook()

What to expect: a model_report.xlsx workbook, IV plots in ./iv_plots/, and a perf table whose KS / AUC are roughly 0.4 / 0.77 on this synthetic data.

Things worth knowing before you start

  • WOE_Master handles numeric features. For categorical (string) features, or when you need monotone bins and special-value governance, use MonotoneWOEBinner(feature_cols=..., target_col=..., cate_feats=[...]), then .fit(df) and .apply_woe(df).
  • GradientBoostingModel.fit(x_train, y_train, x_val, y_val) takes a validation set for early stopping. LightGBM ("lgb") requires early_stopping_rounds in params (a missing key raises KeyError); XGBoost and CatBoost treat it as optional, and XGBoost ignores eval_metric.
  • ExcelMaster(filepath, verbose): verbose has no default. In insert_image, figScale is an x/y scale factor (for example (0.6, 0.6)), not a pixel size.
  • Sample weights are first-class: pass weight_col (or sample_weight for array-based APIs) consistently in training and evaluation.

One-click pipelines

Pass a DataFrame and a config object; get back a structured result object. This runs end to end on the data frame from the quickstart, with the slow optional stages switched off:

from Modeling_Tool import CreditModelPipeline, CreditModelPipelineConfig

df = data.rename(columns={"bad_flag": "badflag"})
df["oot_flag"] = (np.arange(len(df)) >= int(len(df) * 0.8)).astype(int)   # last 20% = out-of-time

cfg = CreditModelPipelineConfig(
    output_dir="output",
    target_col="badflag",
    feature_cols=features,
    oot_col="oot_flag",
    train_models=["lr", "lgb"],
    backward_enabled=False,
    optuna_models=[],
    explain_models=[],
    owen_enabled=False,
    write_excel=False,
    plot_outputs=False,
)
result = CreditModelPipeline(cfg).run(df)

print(result.selected_features)
print(result.perf_results["lgb"][["index", "KS", "AUC"]])
Pipeline Config / result classes Purpose
CreditModelPipeline CreditModelPipelineConfig / CreditModelPipelineResult Split, screening, WOE, training, tuning, evaluation, explanation, Excel report
FeatureValidationPipeline FeatureValidationPipelineConfig / FeatureValidationPipelineResult Acceptance checks for new feature tables: distribution, PSI, IV/KS, correlation
RejectInferencePipeline RejectInferencePipelineConfig / RejectInferencePipelineResult Reject inference with pre-score training and benchmark comparison
ScoreComparisonPipeline ScoreComparisonPipelineConfig / ScoreComparisonPipelineResult Champion/challenger score comparison by time and population
ScoreConsistencyUATPipeline ScoreConsistencyUATPipelineConfig / ScoreConsistencyUATPipelineResult Online vs offline score and feature consistency
SampleAnalysisPipeline SampleAnalysisPipelineConfig / SampleAnalysisPipelineResult Label maturity and OOT / INS / OOS split recommendation
MockSamplePipeline MockSamplePipelineConfig / MockSamplePipelineResult Synthetic application samples for demos and tests

All of them live in Modeling_Tool.Pipeline and are also re-exported from Modeling_Tool. Every pipeline is invoked as Pipeline(config).run(data) (the UAT pipeline can also read SQL files).


Package map

SuperModelingFactory/
├── Modeling_Tool/          # Modeling engine
│   ├── Core/               #   Binning, ODPS client, parallel engine, ProcCompare, model I/O, utilities
│   ├── WOE/                #   WOE_Master, MonotoneWOEBinner, WOE transforms, plots, engine adapter
│   ├── Feature/            #   PSI, IV/KS insights, correlation filter, feature_screen, distribution analysis
│   ├── Model/              #   LRMaster, GradientBoostingModel, backward elimination
│   ├── Eval/               #   Gains tables, performance evaluation, cross-risk, ROC/KS/PR/lift plots
│   ├── Sample/             #   Splitting, sampling, reject inference, distribution adaptation
│   ├── Explainability/     #   ModelExplainer (SHAP, Owen, PDP, ICE, ALE, LIME), coalition structure
│   ├── Pipeline/           #   One-click pipelines, config schema and registry helpers
│   └── UAT/                #   UATConsistencyChecker and helpers
├── ExcelMaster/            # Excel engine: ExcelMaster, 50+ preset cell formats, report templates
├── Report/                 # Report_Tool: model performance, WOE plot, multi-model comparison reports
├── scripts/                # Release tooling (version consistency check)
└── pyproject.toml, setup.py, Makefile, INSTALL.md, CONTRIBUTING.md, RELEASING.md

Per-package details: Modeling_Tool · ExcelMaster · Report.

Design rules:

  • Modeling_Tool.Core has no dependency on the other subpackages; the others depend on it one way, and cross-subpackage imports are lazy to avoid cycles.
  • Public API is exported through __init__.py: from Modeling_Tool import ... for the common names, or from Modeling_Tool.<Subpackage> import ... for the complete set. Names starting with _ are internal.
  • Classes use PascalCase and functions use snake_case.

The SMF ecosystem

Repository Purpose
SuperModelingFactory This repository: the package source
SuperModelingFactory_doc MkDocs documentation site (live)
SuperModelingFactory_pytest Full regression test suite (1896 tests at v0.9.3)
SuperModelingFactory_agent An AI-assistant skill that answers SMF questions and drafts Pipeline calls

Development and testing

make install     # editable install
make test        # smoke-import the core modules
make verify      # compile sources and build the sdist + wheel (what CI runs)

The full test suite lives in SuperModelingFactory_pytest:

export PYTHONPATH="$(pwd):${PYTHONPATH}"
pytest /path/to/SuperModelingFactory_pytest -q

GitHub Actions (.github/workflows/tests.yml) runs that suite on every push to main and every pull request, on Python 3.11 and 3.12 across three dependency sets (legacy: numpy<2, modern: numpy 2.x, bleeding: latest pandas). Every pushed commit is tested to the end; only the older run of a pull request is cancelled when that pull request gets a new push. A job that GitHub cancels because no runner picked it up for about 15 minutes is re-run automatically, at most twice (.github/workflows/retry-cancelled.yml). Pushing a v* tag builds wheels and publishes to PyPI (see RELEASING.md). Contribution workflow: CONTRIBUTING.md.


License

SMF is released under the Business Source License 1.1 (Change Date 2030-06-24).

  • Allowed: personal study, academic research, internal evaluation, prototyping, teaching, non-commercial benchmarking.
  • Not allowed without a commercial license: production use, including deployment inside any credit-risk, lending, scoring, underwriting, marketing, or other revenue-generating pipeline.
  • On 2030-06-24 the license converts automatically to Apache 2.0. For a commercial license, contact the author. See LICENSE for the full text.

Version

  • Version: 0.9.3
  • Author: Jingkai Sun

Metadata

Release files for SuperModelingFactory 0.9.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for SuperModelingFactory 0.9.3
File Size Uploaded
supermodelingfactory-0.9.3.tar.gz 17.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for SuperModelingFactory 0.9.3
File Interpreter ABI Platform
supermodelingfactory-0.9.3-py3-none-any.whl Python 3 none any Details

Total release size: 34.5 MB

Release files / supermodelingfactory-0.9.3.tar.gz

Download URL supermodelingfactory-0.9.3.tar.gz
Size 17.2 MB
Tags Source
SHA-256 checksum
How to use checksums
5aeb9c75d7bad816dd0e69b8f40832e7f374de49615a569d3742188ee038ae2c
BLAKE2b-256 checksum
How to use checksums
815b7f2cf3914989278c78a60bd4422561999ea682d6d4ecd3f8a85d575eddc6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / supermodelingfactory-0.9.3-py3-none-any.whl

Download URL supermodelingfactory-0.9.3-py3-none-any.whl
Size 17.3 MB
Tags Python 3
SHA-256 checksum
How to use checksums
dc8bc92127c1ee427ceaa096ed6cc098ff6ac45da6e7a8af7de8340fa967e3d5
BLAKE2b-256 checksum
How to use checksums
bac5563e0c9baddd99fb5edf7e982459887e5ad1aa54869d268c338452024091
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.9.3 This release

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.9

2 release files

0.6.8

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.10

2 release files

0.5.9

2 release files

0.5.8

2 release files

0.5.7

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.2

2 release files

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.3

16 release files

0.1.2

16 release files

0.1.0

13 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page