Skip to main content

High-performance Risk Modeling Toolkit powered by Polars

Project description

MARS

MARS MODELING ANALYSIS RISK SCORE

面向信贷风控分析与建模的 Polars-first 高性能工具库

PyPI version Python Versions Downloads CI License

Profile -> Bin/Evaluate -> Analyze -> Select -> Modeling Pipeline -> Monitor -> Report

项目简介 · 设计理念 · 能力地图 · 性能对比 · 安装 · 快速开始 · 核心-api-约定 · Modeling Pipeline · 报表导出 · FAQ

项目简介

MARS 覆盖数据画像、分箱评估、特征分析、特征筛选、Modeling Pipeline、特征/模型监控指标计算和 Excel/HTML 报表导出。它以宽表特征为主线,串联训练前分析、建模期调参与评估、特征与模型分稳定性观察和报表导出,让日常风控建模流程更容易复用、审计和交付。

MARS 将数据质量、分箱规则、指标评估、特征筛选、模型调参与评估结果、导出产物组织在同一套结构化报告体系中。使用者既可以直接生成 Excel/HTML 报表,也可以读取各模块返回的多粒度数据,继续做特征复盘、基于结构化表定制监控规则、内部看板数据接入或定制化分析。

设计理念

  • 性能优先:面向宽表、大样本、多特征风控场景,核心计算优先使用 Polars,减少不必要的数据复制和跨框架转换。
  • sklearn 风格:底层算法对象保持 fit / transform / evaluate 等熟悉范式,便于接入现有建模实验和 Pipeline。
  • Pandas/Polars 兼容:核心计算优先走 Polars,同时兼容 Pandas 和 Polars 的输入与输出;需要保持原类型的链路尽量减少无意义转换。
  • 风控全链路:围绕数据画像、分箱评估、特征分析、特征筛选、Modeling Pipeline、特征/模型监控指标计算、报表导出组织能力。
  • 模块可串联:分箱规则、指标明细、筛选结果、模型结果和 report 对象可在模块间复用,减少 Notebook、Excel 和零散脚本中的重复加工。
  • 监控边界清晰:模型分、prob、score 可以作为特殊特征进入同一套监控指标计算;MARS 输出结构化指标和默认报警摘要,监控窗口、基准样本、模型版本、调度方式、阈值策略、看板和业务处置流程由使用者定义。
  • 补齐开源空白:聚焦通用开源工具通常覆盖不足的信贷风控宽表分析、通用监控指标计算、报表交付和可复盘 report 对象。
  • 可审计与可二次加工:各模块 report 保留多粒度结构化表,支持 Excel/HTML 导出、内部看板接入,以及借助 Agent 做定制化摘要和报告重排。

能力地图

模块链路:数据画像 -> 分箱评估 -> 特征分析 -> 特征筛选 -> Modeling Pipeline -> 特征/模型监控 -> Excel/HTML 报表导出。

模块 主 API 典型问题 主要产出
数据画像 MarsDataProfiler / profile_stats 缺失率、零值、均值/分布、PSI、时间趋势、特征来源分组 MarsProfileReport
分箱评估 MarsNativeBinner / MarsOptimalBinner / MarsBinEvaluator / profile_risk 连续/类别分箱、IV、KS、AUC、Lift、分箱规则复用、部署转换、SQL 生成 MarsRiskProfileMarsEvaluationReport、分箱规则
特征分析 MarsDataProfiler / profile_stats / profile_risk 特征质量、单变量风险、稳定性、分布变化、业务特殊值影响 画像表、指标明细、趋势表
特征筛选 MarsStatsSelector / MarsLinearSelector / MarsImportanceSelector 质量筛选、稳定性、相关性、模型重要性 selected_features_、筛选报告
Modeling Pipeline MarsModelingSession / MarsModelTuner / MarsModelReplayRunner / MarsModelEvaluator train/val/oot 切分、模型调参、benchmark 对比、Top-K replay、重要性表、建模评估报告 MarsModelTuningResultMarsModelReplayResultMarsModelingReport
特征/模型监控 MarsMonitor / generate_monitoring_alert 支持前端监控后端监控的通用指标计算、PSI、缺失趋势、分箱占比趋势、分箱统计量趋势、target 表现覆盖率、默认报警摘要 MarsMonitoringReport、监控报警摘要
Excel/HTML 报表导出 write_excel / write_html / build_scorecard 画像报表、风险评估报表、建模评估报表、评分卡映射、部署 SQL Excel、HTML、MarsScorecard

性能对比

面向宽表分箱场景,MARS 重点优化大样本、多特征下的分箱拟合、规则转换和报表链路衔接。可用以下命令复现测试结果:

conda run -n mars python benchmarks/benchmark_binning_speed.py native --rows 200000 --features 3000 --repeats 1
conda run -n mars python benchmarks/benchmark_binning_speed.py optimal --rows 50000 --features 1000 --repeats 3
  • 计时范围:数据生成 + fit + transform + 本轮清理
  • 内存口径:主进程及其子进程的 RSS;结束增量为本轮结束 RSS - 起始 RSS,峰值增量为采样峰值 RSS - 起始 RSS
  • Python:3.10.19;系统:Windows-10-10.0.26200-SP0
  • 结束增量会受 Python、Polars、NumPy 内存分配器缓存影响;比较峰值压力时优先看“峰值增量”

原生分箱:toad vs MarsNativeBinner

  • 数据规模:200,000 行 × 3,000 个数值特征
  • 重复次数:1;随机种子:2026
场景 方法 平均耗时(s) 最快(s) 最慢(s) 平均结束增量(MB) 峰值增量(MB) 相对基准 备注
等频分箱 toad Combiner + WOETransformer 126.083 126.083 126.083 30.7 20516.1 1.60x
等频分箱 MarsNativeBinner 78.768 78.768 78.768 3348.2 6768.8 1.00x method=quantile
等宽分箱 toad Combiner + WOETransformer 105.859 105.859 105.859 6.7 20468.4 1.31x
等宽分箱 MarsNativeBinner 81.058 81.058 81.058 -7.8 6727.7 1.00x method=uniform

原生等频/等宽的额外能力

MARS 的原生等频/等宽分箱不只是生成切点。围绕风控特征分析和监控指标计算,这些处理统一沉淀在同一套规则对象中,便于后续分析、监控和导出复用:

  • 缺失值、NaN、自定义 missing_values 和业务特殊值 special_values 会独立隔离,不挤占正常分箱数量。
  • merge_small_bins 可在等频/等宽后自动合并低占比碎片箱,减少极端宽表中的不稳定分箱。
  • remove_empty_bins 可在等宽场景自动清理空箱,适配长尾、零膨胀和稀疏分布。
  • 原生分箱支持处理类别特征,最优分箱支持类别合并,用于降低高基数类别带来的不稳定性。
  • 分箱规则可以继续进入特征分析、特征/模型监控指标计算、Modeling Pipeline 结果和后续报表链路,减少从探索到部署之间的规则重写。

最优分箱:MarsOptimalBinner vs optbinning

  • 数据规模:50,000 行 × 1,000 个数值特征
  • 重复次数:3;随机种子:2026
场景 方法 平均耗时(s) 最快(s) 最慢(s) 平均结束增量(MB) 峰值增量(MB) 相对基准 备注
最优分箱 MarsOptimalBinner 28.011 26.627 29.189 282.0 5531.5 1.00x 单特征 time_limit=1s
最优分箱 optbinning.BinningProcess 125.826 124.474 126.538 17.0 628.4 4.49x 单特征 time_limit=1s

安装

MARS 支持 Python >= 3.10

pip install mars-risk
场景 安装命令
基础能力(含画像、分箱、筛选、Excel/HTML 报表和图表报告) pip install mars-risk
Notebook 交互 pip install "mars-risk[notebook]"
树模型与调参 pip install "mars-risk[ml,tuning]"
本地开发 pip install -e ".[dev,ml,tuning]"
git clone https://github.com/leeesq/mars-risk.git
cd mars-risk
pip install -e ".[dev,ml,tuning]"

快速开始

下面的示例保持短小,展示主链路的新 API 约定。

准备样本

import polars as pl

df = pl.DataFrame(
    {
        "apply_dt": [
            "2024-01-03", "2024-01-10", "2024-01-17", "2024-01-24",
            "2024-02-03", "2024-02-10", "2024-02-17", "2024-02-24",
            "2024-03-03", "2024-03-10", "2024-03-17", "2024-03-24",
        ],
        "month": [
            "2024-01", "2024-01", "2024-01", "2024-01",
            "2024-02", "2024-02", "2024-02", "2024-02",
            "2024-03", "2024-03", "2024-03", "2024-03",
        ],
        "income": [3200, 3600, -999, None, 3300, 4200, -999, 5800, 3400, 4300, None, 6100],
        "utilization": [0.12, 0.18, 0.52, 0.61, 0.14, 0.29, 0.54, 0.58, 0.16, 0.31, 0.56, 0.63],
        "segment": ["new", "repeat", "vip", "vip", "new", "repeat", "vip", "vip", "new", "repeat", "vip", "vip"],
        "target": [0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1],
    }
)

数据画像

from mars.analysis import MarsDataProfiler, profile_stats

profiler = MarsDataProfiler(missing_values=[-999])
profile_report = profiler.generate_profile(
    df,
    group_col="month",
    config_overrides={
        "enable_sparkline": False,
        "dq_metrics": ["missing", "zeros"],
        "stat_metrics": ["mean", "psi"],
    },
)

quick_report = profile_stats(
    df,
    metrics=["missing", "mean"],
    features=["income", "utilization"],
    group_col="month",
    missing_values=[-999],
)

分箱评估

from mars.analysis import profile_risk

risk_profile = profile_risk(
    df,
    target="target",
    features=["income", "utilization", "segment"],
    group_col="month",
    binning_type="native",
    binner_params={"method": "quantile", "n_bins": 4},
    plot=False,
)

eval_report = risk_profile.report
binner = risk_profile.binner
summary = eval_report.summary_table

profile_risk() 返回 MarsRiskProfile(report, binner, targets, metadata)report 用于查看和导出分箱评估报表,binner 用于复用本次分箱规则。

分箱器

from mars.feature import MarsNativeBinner

X = df.select(["income", "utilization", "segment"])
y = df.get_column("target")

binner = MarsNativeBinner(method="quantile", n_bins=4, special_values=[-999])
binner.fit(X, y, cat_features=["segment"])

X_bin = binner.transform(X, return_type="index")
X_woe = binner.transform(X, return_type="woe")
income_mapping = binner.get_bin_mapping("income")

特征筛选

from mars.feature import MarsStatsSelector

selector = MarsStatsSelector(
    missing_thr=0.9,
    iv_thr=0.01,
    psi_thr=0.25,
    skip_fine_scan=True,
)

selector.fit(
    df,
    target="target",
    features=["income", "utilization", "segment"],
    group_col="month",
)

selected_features = selector.selected_features_
selection_report = selector.get_eval_report(df)

特征/模型监控

mars.monitoring 的定位是监控指标计算层,MarsMonitor 提供特征与模型分的通用监控指标计算能力。无标签场景可以使用 target=None 做分布监控;target 成熟后可以继续计算坏账率、IV、KS、AUC、Lift 等标签指标。模型分、prob 或 score 只需要作为一个普通字段放入 features

from mars.monitoring import MarsMonitor, generate_monitoring_alert

monitor_df = df.with_columns((pl.col("utilization") * 100).alias("model_score"))

monitor_report = MarsMonitor(
    binner_params={"method": "quantile", "n_bins": 4},
).monitor(
    monitor_df,
    features=["model_score", "income", "utilization"],
    target="target",
    group_col="month",
    trend_column_order="desc",
)

monitor_summary = monitor_report.summary_table
bin_stat_trends = monitor_report.bin_stat_trend_tables
target_observation = monitor_report.target_observation_table

alert_text = generate_monitoring_alert(
    monitor_report,
    score_key="model_score",
    model_features=["income", "utilization"],
)

监控链路只接受 0/1/True/False/null target;null 表示样本尚未到表现期。target=None 时只输出无标签分布监控;传入 target 时,PSI、缺失率和分箱占比使用全量样本,坏账率、IV、KS、AUC、Lift 等标签指标只使用已表现样本。PSI 默认不包含缺失箱和特殊值箱,缺失率会单独进入趋势监控。trend_column_order 控制趋势宽表取值列的展示顺序,默认 "asc" 保持从早到晚;需要最新月份靠前时可设为 "desc",报警摘要会按 report 记录的趋势列顺序识别基准期和最新期。generate_monitoring_alert 是基于 MarsMonitoringReport 的默认摘要工具,不替代业务方自己的报警规则、阈值策略和处置流程。

Modeling Pipeline

建模调参需要安装 mltuning 可选依赖。

from mars.modeling import MarsModelingSession
from mars.modeling.tuning import MarsModelReplayRunner

session = MarsModelingSession(
    model_type="xgb",
    features=["income", "utilization", "segment"],
    target="target",
    categorical_features=["segment"],
    optimize_metric="ks",
    seed=1206,
)

modeling_df = session.slice(
    df,
    time_col="apply_dt",
    split_ratios={"train": 0.6, "val": 0.2, "oot": 0.2},
)

tuning_result = session.tune(
    modeling_df,
    n_trials=20,
    history_path=None,
)

replay_result = MarsModelReplayRunner().run(
    tuning_result,
    modeling_df,
    top_k=3,
    sort_metric="ks",
)

核心 API 约定

场景 约定
高层风控工作流 使用 df, target,例如 profile_risk(df, target="y")
底层算法对象 使用 X, y,例如 MarsNativeBinner().fit(X, y)
构造函数 放稳定策略、阈值、模型规格,不放本次样本数据
方法入参 放数据、列名、特征范围、分组、时间、输出路径
分组命名 group_col 是已有分组列,time_col 是原始日期列,time_grain 是聚合粒度
建模切片 dataset_flag_col 只表示 train/val/oot 等建模样本切片
文件输出 路径参数支持 `str

Modeling Pipeline

Modeling Pipeline 仍在快速迭代中,可能不稳定;后续接口约定、结果对象和调参参数都可能发生较大变动。

当前支持 XGBoost(xgb)、LightGBM(lgb)、CatBoost(cbt / cat / catboost)和 Logistic Regression(lr / logistic)。逻辑回归支持 numeric 与 WOE 两种特征模式。

API 职责 返回值
MarsModelDataSplitter 无状态样本切分工具 与输入类型一致的 DataFrame
MarsModelingSession 组织切分、调参、replay 和增量特征调参 会话对象
MarsModelTuner 对单个模型后端执行 Optuna 调参 MarsModelTuningResult
MarsModelReplayRunner 从调优结果中读取规格并回放 Top-K trial MarsModelReplayResult
MarsModelEvaluator 对已打分样本构建建模评估报告 MarsModelingReport
MarsFeatureIncrementalTuner 按特征数量逐步扩展调参 MarsFeatureGrowthResult

MarsModelTuningResult 会保存最佳模型、调参历史、特征重要性、训练配置和 artifact 元数据。MarsModelReplayResult 会保存 replay leaderboard、模型字典、打分数据、评估报告和重要性表。

模型分可以被视为一个特殊特征进入稳定性观察。当前 MarsModelEvaluator 是建模评估器,已输出 Score PSIscore_psi 明细,用于建模评估阶段观察模型分在 train/val/oot 或业务切片之间的分布漂移。需要按自定义时间或业务切片观察模型分时,使用者可以将模型分加入 MarsMonitorfeatures,得到 PSI、缺失率、分箱占比、分箱统计量和已表现样本风险指标等结构化结果。

Excel/HTML 报表导出与二次加工

Report 对象输出 summary_table、detail_tables、trend_tables、metadata,并支持 Excel/HTML、看板和 Agent 二次加工

画像、风险评估、建模评估和评分卡结果都以对象形式返回。MarsProfileReportMarsEvaluationReportMarsModelingReport 等 report 对象会保留 summary_tabledetail_table / detail_tablestrend_tablesmetadata / report_meta 等结构化数据,使用者可以按模块、特征、分组、时间或样本切片继续加工。

这些多粒度表格适合继续做特征复盘、基于结构化表继续定制监控规则、接入内部看板和定制化分析,也便于借助 Agent 基于明细表进行摘要、筛选、解释和报告重排。需要交付给业务或评审时,可以直接导出 Excel/HTML:

profile_report.write_excel("mars_profile.xlsx")
eval_report.write_excel("mars_evaluation.xlsx", engine="openpyxl")
eval_report.write_html("mars_evaluation.html")

评分卡链路支持从逻辑回归模型和 WOE 分箱结果生成分数映射,并导出 SQL 规则。

公开 API 概览

导入位置 公开对象
mars.analysis MarsDataProfilerMarsBinEvaluatorMarsRiskProfileprofile_statsprofile_risk
mars.feature MarsNativeBinnerMarsOptimalBinnerMarsStatsSelectorMarsLinearSelectorMarsImportanceSelector
mars.modeling MarsModelingSession
mars.modeling.tuning MarsModelTunerMarsModelReplayRunner
mars.modeling.slicing MarsModelDataSplitter
mars.modeling.results MarsModelTuningResultMarsModelReplayResult
mars.modeling.feature_growth MarsFeatureGrowthResultMarsFeatureIncrementalTuner
mars.monitoring MarsMonitorMarsMonitoringReportMarsMonitoringDataMarsMonitoringAlerterMarsMonitoringAlertConfiggenerate_monitoring_alert
mars.scoring MarsScorecardbuild_scorecard

可选依赖

  • mars-risk 基础安装已包含 Excel/HTML 报表导出和绘图报告依赖。
  • notebook:Notebook 交互展示。
  • ml:XGBoost、LightGBM、CatBoost、SHAP、statsmodels。
  • tuning:Optuna 调参。

测试与开发

python -m ruff check src tests benchmarks scripts
python -m mypy src/mars
pydoclint src/mars
python scripts/check_private_docstrings.py src/mars
MPLBACKEND=Agg python -m pytest -q --basetemp .pytest-tmp

本仓库使用 src/ 包结构,并声明 mars/py.typed。提交 Python 代码时,请保持类型注解、NumPy 风格 docstring、中文自然语言注释和 README 同步。public API 的参数、返回值和异常变更必须同步 docstring,CI 会通过 ruffpydoclint 阻断漏改;复杂私有方法缺少中文短 docstring 时,会由 scripts/check_private_docstrings.py 阻断。

FAQ

profile_risk() 返回什么?

返回 MarsRiskProfile(report, binner, targets, metadata)。其中 report 是风险评估报告,binner 是本次拟合或复用的分箱器,targets 是目标列列表,metadata 保存运行上下文。

为什么高层 API 用 target,底层对象用 y

高层 API 面向完整业务表,目标变量是某个列名,所以使用 df, target。底层算法对象面向特征矩阵和标签向量,所以使用 X, y。这样可以避免同一个方法里同时出现列名和标签向量两种语义。

MarsModelTuner.tune(history_path=None) 会写文件吗?

不会。history_path=None 时调参历史只保存在返回对象中。传入路径时才写 CSV;如果路径已存在且 overwrite=False,会抛出 FileExistsError

Pandas 和 Polars 都能用吗?

可以。核心计算优先走 Polars;Pandas 输入会在需要时转换或保持原类型返回。建模切分器会根据输入类型选择对应实现,避免不必要的跨框架转换。

路线图

  • 继续扩展模型评估、特征/模型监控指标计算、报警摘要和报表导出的测试覆盖。
  • 增强评分卡 SQL 和 artifact 回放能力。
  • 持续收敛 public API 命名和类型注解。

参与方式

欢迎提交 issue、测试用例、文档修正和真实建模场景反馈。PR 请附上最小复现、测试命令和对 public API 的影响说明。

许可证

本项目使用 LICENSE 中声明的开源许可证。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mars_risk-0.0.16.tar.gz (359.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mars_risk-0.0.16-py3-none-any.whl (351.0 kB view details)

Uploaded Python 3

File details

Details for the file mars_risk-0.0.16.tar.gz.

File metadata

  • Download URL: mars_risk-0.0.16.tar.gz
  • Upload date:
  • Size: 359.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mars_risk-0.0.16.tar.gz
Algorithm Hash digest
SHA256 4aff8bb3447d3482310a521d7393c1a2dd085066c3fd85ba79e1a54676c2af90
MD5 b36fc3e4cf8a605aa0fd934a76c6a44f
BLAKE2b-256 d7626f25d37ad2cd1cdb27bebf6db5f8828e9813cc0e10798a95d8756c645f25

See more details on using hashes here.

Provenance

The following attestation bundles were made for mars_risk-0.0.16.tar.gz:

Publisher: publish.yml on leeesq/mars-risk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mars_risk-0.0.16-py3-none-any.whl.

File metadata

  • Download URL: mars_risk-0.0.16-py3-none-any.whl
  • Upload date:
  • Size: 351.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mars_risk-0.0.16-py3-none-any.whl
Algorithm Hash digest
SHA256 da1e8405f76c877ab3849f777ab10f2b9c073157ecd5362ddeeff4102130b00e
MD5 8f846479736a2e79fb184b740643d045
BLAKE2b-256 2d3bc6e8943cd56b51d031adb5678d3d4253330729cfd986345997269a891b58

See more details on using hashes here.

Provenance

The following attestation bundles were made for mars_risk-0.0.16-py3-none-any.whl:

Publisher: publish.yml on leeesq/mars-risk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page