跳转至

Feature

特征分箱、特征筛选和底层 fit / transform 对象。

Binner

所有分箱器都继承 MarsBinnerBase,因此共享 fit_transformtransformprofile_bin_performanceto_dict/from_dictprune 等规则转换、评估和序列化能力。

mars.feature.MarsBinnerBase

Bases: MarsTransformer

MARS 分箱器抽象基类。

该基类定义了分箱器的公共状态、索引协议以及数值/类别特征的统一转换行为。 子类负责学习切点或类别分组规则,基类则负责缓存管理、映射导出、 WOE 物化、统计报告和 SQL 生成。

属性:

名称 类型 描述
bin_cuts_ dict of str to list of float

数值型特征的物理切点,每个列表均以 [-inf, ..., inf] 闭合。

cat_cuts_ dict of str to list of list

类别型特征的分组映射规则。将零散的字符串/分类标签聚类为逻辑组。

bin_mappings_ dict of str to dict of int to str

分箱可视化映射表。将物理索引映射为业务可读标签。

bin_woes_ dict of str to dict of int to float

分箱权重字典。存储每个分箱索引对应的 WOE 值。

feature_names_in_ list of str

拟合时输入的原始特征列名。

fit_failures_ dict of str to str

拟合过程中失败的特征及其诊断信息。

Notes

索引协议如下: Missing-1Other-2Special-3 开始向负方向扩展, 正常分箱索引从 0 开始递增。

示例:

>>> issubclass(MarsNativeBinner, MarsBinnerBase)
True

__init__

__init__(n_bins: int = 10, special_values: List[Union[int, float, str]] | None = None, missing_values: List[Union[int, float, str]] | None = None, join_threshold: int = 100, n_jobs: int = -1) -> None

初始化分箱器基类, 配置全局业务规则与并行策略。

参数:

名称 类型 描述 默认
n_bins int

期望的最大分箱数量。最终生成的箱数可能少于此值 (受单调性约束或样本量影响)。

10
special_values List[Union[int, float, str]] | None

特殊值列表。 - 在部分场景中, 某些特定取值 (如 -999, -1)代表特定含义, 会被强制分配到独立的负数索引分箱中, 不参与正常区间的切分。

None
missing_values List[Union[int, float, str]] | None

自定义缺失值列表。除了原生的 nullNaN 外, 用户可指定其他代表缺失的值。

None
join_threshold int

transform 阶段, 为防止因构建过深的逻辑分支树 (When-Then Tree)导致的计算图解析缓慢: - 当类别特征的基数 (Unique Values) 低于此值时, 使用内存级 replace 映射。 - 当基数超过此值时, 自动切换为 Hash Join 模式。

100
n_jobs int

并行计算的核心数: - -1: 自动使用 CPU核心数 - 1, 预留一个核心保证系统响应。 - 1: 强制单线程模式, 便于调试。 - N: 使用指定的核心数。

-1
Notes

初始化阶段不执行任何重型计算。所有计算资源 (进程池、线程池) 均在 fit 阶段按需按需申请。

fit

fit(X: DataFrame | DataFrame, y: Series | Series | ndarray | list[Any] | None = None, *, features: list[str] | None = None, cat_features: list[str] | None = None) -> MarsBinnerBase

拟合分箱器并缓存本次分箱特征范围。

参数:

名称 类型 描述 默认
X DataFrame | DataFrame

输入特征矩阵。

必需
y Series | Series | ndarray | list[Any] | None

目标变量。监督型分箱器或监督型分箱方法会使用该参数。

None
features list[str] | None

本次拟合的特征列;不传时由具体分箱器使用全部候选列。

None
cat_features list[str] | None

显式指定为类别型的特征列。

None

返回:

类型 描述
MarsBinnerBase

拟合完成后的当前分箱器实例。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> binner = MarsNativeBinner(method="quantile", n_bins=2)
>>> binner.fit(X, features=["age"]).features
['age']

transform

transform(X: Union[DataFrame, LazyFrame, DataFrame], *, return_type: Literal['index', 'label', 'woe'] = 'index', woe_batch_size: int = 200, lazy: bool = False) -> Union[pl.DataFrame, pd.DataFrame, pl.LazyFrame]

按当前分箱规则将输入特征映射为索引、标签或 WOE 值。

参数:

名称 类型 描述 默认
X Union[DataFrame, LazyFrame, DataFrame]

待转换的数据集。

必需
return_type Literal['index', 'label', 'woe']

输出形式。"index" 返回分箱索引,"label" 返回分箱标签, "woe" 返回对应分箱的 WOE 值。

'index'
woe_batch_size int

return_type="woe" 且当前实例尚未物化 WOE 映射时, 计算 WOE 的批处理特征数。

200
lazy bool

是否保持延迟执行。为 True 时返回 pl.LazyFrame

False

返回:

类型 描述
DataFrame or DataFrame or LazyFrame

分箱转换结果。若设置了 set_output("pandas") 且结果为 eager DataFrame,则返回 Pandas 对象。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> binner = MarsNativeBinner(method="quantile", n_bins=2).fit(X, features=["age"])
>>> binner.transform(X).columns
['age_bin']

fit_transform

fit_transform(X: Union[DataFrame, DataFrame], y: Any | None = None, *, features: List[str] | None = None, cat_features: List[str] | None = None, return_type: Literal['index', 'label', 'woe'] = 'index', woe_batch_size: int = 200, lazy: bool = False) -> Union[pl.DataFrame, pd.DataFrame, pl.LazyFrame]

先拟合分箱器,再返回分箱转换结果。

参数:

名称 类型 描述 默认
X Union[DataFrame, DataFrame]

输入特征矩阵。

必需
y Any | None

目标变量。无监督分箱场景下可为空。

None
features List[str] | None

本次拟合和转换的特征列;不传时使用全部候选列。

None
cat_features List[str] | None

明确指定的类别特征列。

None
return_type Literal['index', 'label', 'woe']

转换结果形式。

'index'
woe_batch_size int

计算 WOE 映射时的批处理特征数。

200
lazy bool

是否返回 pl.LazyFrame

False

返回:

类型 描述
DataFrame or DataFrame or LazyFrame

分箱转换结果。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> binner = MarsNativeBinner(method="quantile", n_bins=2)
>>> binner.fit_transform(X, return_type="label").columns
['age_bin']

to_dict

to_dict() -> Dict[str, Any]

将分箱器状态序列化为 Python 字典。

返回:

类型 描述
dict of str to Any

包含 paramsstate 两部分的可序列化字典。

Notes

返回结果只包含分箱规则和必要状态,不包含缓存的训练数据本体。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> binner = MarsNativeBinner(method="quantile", n_bins=2).fit(X, features=["age"])
>>> sorted(binner.to_dict().keys())
['params', 'state']

from_dict classmethod

from_dict(data: Dict[str, Any]) -> MarsBinnerBase

从字典恢复分箱器实例。

参数:

名称 类型 描述 默认
data Dict[str, Any]

to_dict 生成的状态字典。

必需

返回:

类型 描述
MarsBinnerBase

恢复后的已拟合分箱器实例。

示例:

>>> class DemoBinner(MarsBinnerBase):
...     def _fit_impl(self, X: pl.DataFrame, y: Any | None = None) -> None:
...         return None
...     def _transform_impl(self, X: pl.DataFrame) -> pl.DataFrame:
...         return X
>>> state = {
...     "params": {"features": ["age"], "n_bins": 2},
...     "state": {"bin_mappings_": {"age": {0: "young"}}},
... }
>>> DemoBinner.from_dict(state).get_bin_mapping("age")
{0: 'young'}

__getstate__

__getstate__() -> dict[str, Any]

Pickle 序列化时的钩子。

在保存模型时, 自动剔除巨大的训练数据缓存, 只保留配置和计算结果。

__setstate__

__setstate__(state: dict[str, Any]) -> None

Pickle 反序列化时的钩子。

恢复模型状态, 并将缓存初始化为 None。

clear_cache

clear_cache() -> None

清理缓存的训练数据引用。

Notes

该方法会清空 _cache_X_cache_y,并主动触发一次垃圾回收。 适合在模型训练完成、无需再次即时重算统计量时调用。

返回:

类型 描述
None

函数仅清理训练数据缓存。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> binner = MarsNativeBinner(method="quantile", n_bins=2).fit(X, features=["age"])
>>> binner.clear_cache()
>>> binner._cache_X is None
True

get_bin_mapping

get_bin_mapping(col: str) -> Dict[int, str]

获取指定特征的分箱标签映射。

参数:

名称 类型 描述 默认
col str

特征名称。

必需

返回:

类型 描述
dict of int to str

分箱索引到标签的映射字典。若该特征不存在,则返回空字典。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> binner = MarsNativeBinner(method="quantile", n_bins=2).fit(X, features=["age"])
>>> isinstance(binner.get_bin_mapping("age"), dict)
True

profile_bin_performance

profile_bin_performance(X: DataFrame | DataFrame, y: Series | Series, update_woe: bool = True, batch_size: int = 100, include_bin_index: bool = False, ordered_metric_sort_by: OrderedMetricSortBy = 'woe') -> pl.DataFrame | pd.DataFrame

计算分箱表现统计报告。

参数:

名称 类型 描述 默认
X DataFrame | DataFrame

原始特征数据集。

必需
y Series | Series

二分类目标标签。

必需
update_woe bool

是否将本次计算得到的 WOE 同步回写到 bin_woes_

True
batch_size int

特征分批处理大小。减小该值可进一步降低内存峰值。

100
include_bin_index bool

是否在返回明细中保留内部 bin_index 列。默认不保留,保持既有 报告展示顺序;轻量最优分箱等内部算法可开启该参数以稳定回溯预分箱顺序。

False
ordered_metric_sort_by OrderedMetricSortBy

KS/AUC 的排序口径。默认 "woe" 适合普通特征预测力评估; 传入 "bin_index" 时只用正常箱按原始箱序计算 KS/AUC。

'woe'

返回:

类型 描述
DataFrame or DataFrame

包含各特征各分箱统计量的明细表,通常包括样本数、坏样本数、 分布占比、WOE、IV、KS、AUC 和 Lift 等指标。

Notes

该方法依赖当前分箱器已完成拟合,并会复用 transform(return_type="index") 的输出结果来执行聚合统计。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> y = pl.Series("target", [0, 0, 1, 1])
>>> binner = MarsNativeBinner(method="quantile", n_bins=2).fit(X, y, features=["age"])
>>> stats = binner.profile_bin_performance(X, y)
>>> "feature" in stats.columns
True

update_bins

update_bins(bin_rules: Dict[str, Union[List[Union[int, float]], List[List[Any]]]], X: Union[DataFrame, DataFrame] | None = None, y: Any | None = None) -> pl.DataFrame | None

批量更新分箱规则并即时重算相关统计量。

允许用户批量传入需要强行修改切点的特征字典,系统将自动更新内部规则, 并在单次扫描中重新计算所有被修改特征的 WOE 和分箱统计量。

参数:

名称 类型 描述 默认
bin_rules Dict[str, Union[List[Union[int, float]], List[List[Any]]]]

待修改的特征分箱规则字典。 - 数值型特征:传入内部切点列表,如 {'age': [25, 30, 45]} (系统会自动补齐 -inf 和 inf)。 - 类别型特征:传入二维分组列表,如 {'city': [['北京', '上海'], ['广州', '深圳'], ['其他']]}。

必需
X Union[DataFrame, DataFrame] | None

用于重新计算 WOE 的数据。若为 None,将尝试使用 fit 时缓存的 _cache_X。

None
y Any | None

目标标签。若为 None,将尝试使用 fit 时缓存的 _cache_y。

None

返回:

类型 描述
DataFrame or DataFrame or None

返回被修改特征的最新分箱统计分布表;若没有任何有效特征被更新,则返回 None

引发:

类型 描述
ValueError

当缺少用于重算 WOE 的 X/y,且缓存也不可用时抛出。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> y = pl.Series("target", [0, 0, 1, 1])
>>> binner = MarsNativeBinner(method="quantile", n_bins=2).fit(X, y, features=["age"])
>>> updated = binner.update_bins({"age": [35]})
>>> "feature" in updated.columns
True

prune

prune(keep_features: List[str]) -> MarsBinnerBase

裁剪分箱器内部状态,仅保留指定特征。

参数:

名称 类型 描述 默认
keep_features List[str]

需要保留状态的特征列表。

必需

返回:

类型 描述
MarsBinnerBase

裁剪完成后的当前实例。

Notes

该方法会同步裁剪切点、类别分组、标签映射、WOE 映射以及 feature_names_in_, 常用于特征筛选完成后缩小序列化模型体积。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50], "income": [5, 6, 7, 8]})
>>> binner = MarsNativeBinner(method="quantile", n_bins=2).fit(X, features=["age", "income"])
>>> binner.prune(["age"]).feature_names_in_
['age']

generate_sql

generate_sql(features: Union[str, List[str]] | None = None, table_prefix: str = 't', return_type: Literal['woe', 'index', 'label'] = 'woe', map_missing: bool = True, map_special: bool = True) -> str

将分箱规则导出为 SQL CASE WHEN 片段。

参数:

名称 类型 描述 默认
features Union[str, List[str]] | None

特征名称或特征列表。若为 None,则自动导出所有已拟合的特征。

None
table_prefix str

表别名前缀。例如 "t" 会生成 "t.age"。若为空则直接使用特征名。

't'
return_type Literal['woe', 'index', 'label']

生成 SQL 的目标值类型: - 'woe': 输出 WOE 浮点数 (适合 LR 逻辑回归模型部署) - 'index': 输出分箱序号 (适合 XGBoost/LightGBM 树模型部署) - 'label': 输出分箱的中文/字符标签 (适合 BI 看板、数据分析或规则引擎)

'woe'
map_missing bool

是否将缺失值映射为对应的 WOE/Index/Label。

True
map_special bool

是否将特殊值映射为对应的 WOE/Index/Label。

True

返回:

类型 描述
str

标准 SQL 脚本(多字段间已用逗号安全分隔,可直接嵌入 SELECT 子句)。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> binner = MarsNativeBinner(method="quantile", n_bins=2).fit(X, features=["age"])
>>> sql = binner.generate_sql(features="age", return_type="index")
>>> "age_index" in sql
True

mars.feature.MarsNativeBinner

Bases: MarsBinnerBase

原生高性能特征分箱器。

基于 Polars 向量化计算与 Scikit-Learn 决策树算法构建。支持针对连续型变量的等频、 等宽与决策树(CART)离散化策略,以及针对类别型变量的头部频数保留策略。特殊值与 缺失值在执行核心分箱逻辑前会被强制物理隔离。

属性:

名称 类型 描述
bin_cuts_ dict of str to list of float

针对连续型特征拟合生成的物理切点映射字典。数组形态为 [-inf, cut_1, ..., cut_n, inf]

cat_cuts_ dict of str to list of str

针对类别型特征拟合生成的高频类别保留映射字典。

fit_failures_ dict of str to str

记录在拟合过程中触发严重计算异常的特征名称及其内部堆栈报错信息。

feature_names_in_ list of str

实际参与拟合管道的全局特征名称列表。

Notes

当数据集体量极大且连续变量呈严重长尾或零膨胀分布时,无监督的等频与等宽算法极易生成 绝对占比极低甚至频数为 0 的异常物理箱。开启 merge_small_bins 选项可在不显著增加 计算开销的前提下,强制修复连续区间的碎化问题,保障后续 WOE 映射的稳定性。

示例:

>>> import polars as pl
>>> binner = MarsNativeBinner(method="quantile", n_bins=2)
>>> df = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> binner.fit_transform(df).columns
['age_bin']

__init__

__init__(*, method: Literal['cart', 'quantile', 'uniform'] = 'quantile', n_bins: int = 10, special_values: List[Union[int, float, str]] | None = None, missing_values: List[Union[int, float, str]] | None = None, min_bin_size: float = 0.05, merge_small_bins: bool = False, cart_params: Dict[str, Any] | None = None, remove_empty_bins: bool = False, n_jobs: int = -1) -> None

初始化原生分箱器。

参数:

名称 类型 描述 默认
method Literal['cart', 'quantile', 'uniform']

数值特征的分箱策略。

'quantile'
n_bins int

最大分箱数量,不含缺失值箱和特殊值箱。

10
special_values List[Union[int, float, str]] | None

需要独立隔离的特殊值集合。

None
missing_values List[Union[int, float, str]] | None

需要额外识别为缺失的值集合。

None
min_bin_size float

单箱最小样本占比约束。

0.05
merge_small_bins bool

是否在无监督分箱后自动合并小样本箱。

False
cart_params Dict[str, Any] | None

透传给 DecisionTreeClassifier 的参数。

None
remove_empty_bins bool

是否在 uniform 分箱时清理空箱。

False
n_jobs int

并行计算使用的核心数限制。

-1

fit

fit(X: DataFrame | DataFrame, y: Series | Series | ndarray | list[Any] | None = None, *, features: list[str] | None = None, cat_features: list[str] | None = None) -> MarsNativeBinner

拟合原生分箱器。

参数:

名称 类型 描述 默认
X DataFrame | DataFrame

输入特征矩阵。

必需
y Series | Series | ndarray | list[Any] | None

目标变量。仅当 method="cart" 时必填。

None
features list[str] | None

本次拟合的特征列;不传时使用全部候选列。

None
cat_features list[str] | None

明确指定的类别特征列。

None

返回:

类型 描述
MarsNativeBinner

拟合完成后的原生分箱器实例。

引发:

类型 描述
ValueError

当输入参数、列配置或数据状态不满足当前方法要求时抛出。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> binner = MarsNativeBinner(method="quantile", n_bins=2)
>>> binner.fit(X).feature_names_in_
['age']

mars.feature.MarsLiteOptBinner

Bases: MarsBinnerBase

轻量级启发式最优分箱器。

该分箱器面向宽表风控分析场景,先复用 MarsNativeBinner 生成细粒度预分箱, 再在预分箱统计表上执行趋势约束合并。它不依赖数学规划求解器,适合作为 MarsOptimalBinner 的高速轻量替代方案。

属性:

名称 类型 描述
bin_cuts_ dict of str to list of float

数值特征最终切点,形态为 [-inf, ..., inf]

cat_cuts_ dict of str to list of list

类别特征 Top-K 分组规则。

fit_failures_ dict of str to str

拟合失败并回退的特征及原因。

fitted_trends_ dict of str to str

每个数值特征最终采用的趋势形态。

candidate_scores_ dict of str to dict of str to float

每个数值特征在各候选趋势下的惩罚后评分。

示例:

>>> import polars as pl
>>> X = pl.DataFrame({"score": [0.1, 0.2, 0.8, 0.9]})
>>> y = pl.Series("target", [0, 0, 1, 1])
>>> binner = MarsLiteOptBinner(n_bins=2, n_prebins=4)
>>> binner.fit(X, y).transform(X).columns
['score_bin']

__init__

__init__(*, n_bins: int = 10, min_bin_size: float = 0.05, monotonic_trend: TrendShape = 'auto', prebinning_method: PrebinningMethod = 'quantile', n_prebins: int = 50, special_values: List[Any] | None = None, missing_values: List[Any] | None = None, join_threshold: int = 100, n_jobs: int = -1) -> None

初始化轻量级最优分箱器。

参数:

名称 类型 描述 默认
n_bins int

最终正常分箱数量上限,不含缺失值箱和特殊值箱。

10
min_bin_size float

最终正常箱的最小全量样本占比。

0.05
monotonic_trend TrendShape

趋势约束,支持以下取值:

  • "ascending":强制坏账率随分箱序号非递减。
  • "descending":强制坏账率随分箱序号非递增。
  • "peak":允许先升后降的峰形趋势。
  • "valley":允许先降后升的谷形趋势。
  • "auto":在递增、递减、峰形和谷形中按惩罚后评分自动择优。
  • "auto_asc_desc":只在递增和递减中自动择优,适合只允许单调分箱但方向未知的场景。
'auto'
prebinning_method PrebinningMethod

预分箱策略,可选 "quantile""uniform""cart"

'quantile'
n_prebins int

预分箱数量上限。

50
special_values List[Any] | None

需要独立隔离的业务特殊值。

None
missing_values List[Any] | None

需要额外识别为缺失的取值。

None
join_threshold int

高基数类别转换时切换到 Join 映射的阈值。

100
n_jobs int

预分箱阶段可使用的并行核心数。

-1

引发:

类型 描述
ValueError

当分箱数量、趋势类型或预分箱策略配置非法时抛出。

fit

fit(X: DataFrame | DataFrame, y: Series | Series | ndarray | list[Any], *, features: list[str] | None = None, cat_features: list[str] | None = None) -> MarsLiteOptBinner

拟合轻量级最优分箱规则。

参数:

名称 类型 描述 默认
X DataFrame | DataFrame

输入特征矩阵。

必需
y Series | Series | ndarray | list[Any]

二分类目标变量,必须为 0/1 或布尔值,且不允许为空。

必需
features list[str] | None

本次拟合的特征列;不传时使用全部候选列。

None
cat_features list[str] | None

明确指定为类别型的特征列。

None

返回:

类型 描述
MarsLiteOptBinner

拟合完成后的当前实例。

引发:

类型 描述
ValueError

y 缺失、标签非法或输入列配置不满足拟合要求时抛出。

to_dict

to_dict() -> Dict[str, Any]

将轻量级分箱器状态序列化为字典。

返回:

类型 描述
Dict[str, Any]

包含构造参数与拟合后状态的可序列化字典。

from_dict classmethod

from_dict(data: Dict[str, Any]) -> MarsLiteOptBinner

从字典恢复轻量级分箱器实例。

参数:

名称 类型 描述 默认
data Dict[str, Any]

to_dict 生成的状态字典。

必需

返回:

类型 描述
MarsLiteOptBinner

恢复后的已拟合轻量级分箱器。

示例:

>>> binner = MarsLiteOptBinner.from_dict(
...     {
...         "params": {"n_bins": 2},
...         "state": {"bin_cuts_": {"x": [-float("inf"), float("inf")]}},
...     }
... )
>>> binner.fitted_trends_
{}

mars.feature.MarsOptimalBinner

Bases: MarsBinnerBase

基于数学规划的最优分箱器。

该组件集成了空间降维预分箱技术与 OptBinning 核心规划算法。通过在指定的目标事件率 (Event Rate)单调性约束、最小区间占比及最小事件数等边界条件下,求解信息值(IV)最大化 的混合整数规划或约束编程问题,生成具备极高鲁棒性与严格业务逻辑解释性的特征切点。

属性:

名称 类型 描述
bin_cuts_ dict of str to list of float

针对连续型特征求解生成的物理切点映射字典。

cat_cuts_ dict of str to list of list

针对类别型特征求解生成的离散组合分类映射字典。

fit_failures_ dict of str to str

记录在拟合过程中触发求解器异常、数据类型不支持或超时熔断的特征名称及其内部诊断原因。

Notes

该离散化评估器在执行过程中高度依赖底层预分箱产生的搜索边界。在面临极度偏态的特征分布时, 求解器可能因无法在给定的 min_bin_size 与单调性约束下找到可行解 (Infeasible) 而崩溃。 为此,引擎内部构建了完备的异常隔离与降级回退机制,确保流水线在处理高噪超宽表时具备 绝对的稳定性。

示例:

>>> import polars as pl
>>> binner = MarsOptimalBinner(n_bins=2, min_bin_n_event=30)
>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> y = pl.Series("y", [0, 0, 1, 1])
>>> binner.fit(X, y).transform(X).columns
['age_bin']

__init__

__init__(*, n_bins: int = 10, min_n_bins: int = 2, min_bin_size: float = 0.05, min_bin_n_event: int = 30, prebinning_method: Literal['quantile', 'uniform', 'cart'] = 'cart', n_prebins: int = 50, min_prebin_size: float = 0.01, monotonic_trend: Literal['ascending', 'descending', 'auto', 'auto_asc_desc'] = 'auto_asc_desc', solver: Literal['cp', 'mip'] = 'cp', time_limit: int = 10, max_cats_to_solver: int | None = 100, min_cat_fraction: float = 0.05, special_values: List[Any] | None = None, missing_values: List[Any] | None = None, cart_params: Dict[str, Any] | None = None, fallback_binner_params: Dict[str, Any] | None = None, join_threshold: int = 100, n_jobs: int = -1) -> None

初始化最优分箱器。

参数:

名称 类型 描述 默认
n_bins int

最大分箱数量,不含缺失值箱和特殊值箱。

10
min_n_bins int

允许求解器返回的最小分箱数。

2
min_bin_size float

单箱最小样本占比约束。

0.05
min_bin_n_event int

单箱最少事件数约束。

30
prebinning_method Literal['quantile', 'uniform', 'cart']

求解前的预分箱策略。

'cart'
n_prebins int

预分箱数量上限。

50
min_prebin_size float

预分箱阶段的最小样本占比。

0.01
monotonic_trend Literal['ascending', 'descending', 'auto', 'auto_asc_desc']

目标事件率的单调性约束方向。

'auto_asc_desc'
solver Literal['cp', 'mip']

数学规划求解器类型。

'cp'
time_limit int

单个特征的求解时间上限,单位为秒。

10
max_cats_to_solver int | None

进入求解器搜索空间的最大类别数。

100
min_cat_fraction float

类别特征单一类别的最小样本占比。

0.05
special_values List[Any] | None

需要独立隔离的特殊值集合。

None
missing_values List[Any] | None

需要额外识别为缺失的值集合。

None
cart_params Dict[str, Any] | None

透传给预分箱决策树的参数。

None
fallback_binner_params Dict[str, Any] | None

最优求解失败后使用的原生分箱回退参数。只允许覆盖 methodn_binsmin_bin_sizemerge_small_binsremove_empty_binscart_params

None
join_threshold int

高基数类别映射时切换到 Join 模式的阈值。

100
n_jobs int

并行计算使用的核心数限制。

-1

引发:

类型 描述
ValueError

当输入参数、列配置或数据状态不满足当前方法要求时抛出。

to_dict

to_dict() -> Dict[str, Any]

将最优分箱器状态序列化为字典。

返回:

类型 描述
Dict[str, Any]

包含构造参数与拟合状态的可序列化字典。

fit

fit(X: DataFrame | DataFrame, y: Series | Series | ndarray | list[Any], *, features: list[str] | None = None, cat_features: list[str] | None = None) -> MarsOptimalBinner

拟合最优分箱器。

参数:

名称 类型 描述 默认
X DataFrame | DataFrame

输入特征矩阵。

必需
y Series | Series | ndarray | list[Any]

目标变量。最优分箱依赖监督信息,必须提供。

必需
features list[str] | None

本次拟合的特征列;不传时使用全部候选列。

None
cat_features list[str] | None

明确指定的类别特征列。

None

返回:

类型 描述
MarsOptimalBinner

拟合完成后的最优分箱器实例。

引发:

类型 描述
ValueError

当输入参数、列配置或数据状态不满足当前方法要求时抛出。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> y = pl.Series("target", [0, 0, 1, 1])
>>> binner = MarsOptimalBinner(n_bins=2, min_bin_n_event=30)
>>> binner.fit(X, y).feature_names_in_
['age']

Selector

mars.feature.MarsStatsSelector

Bases: MarsBaseSelector

基于风控统计指标的特征筛选器。

该筛选器将数据质量、IV/Lift、PSI、相关性和白黑名单规则串成一个漏斗式筛选流程。 构造函数只保存阈值、分箱策略、缺失/特殊值配置以及运行资源参数;样本数据、 目标列、特征范围、分组列、时间列和最大抽样量都由 fit 传入。

典型用法是先用粗分箱低成本压缩特征空间,再用精细分箱和稳定性规则做最终筛选。 white_list 中的特征会尽量绕过自动剔除规则,black_list 中的特征会被强制排除。

示例:

>>> import polars as pl
>>> df = pl.DataFrame({"age": [20, 30, 40, 50], "y": [0, 0, 1, 1]})
>>> selector = MarsStatsSelector(skip_fine_scan=True)
>>> selector.fit(df, target="y", features=["age"]).selected_features_
['age']

__init__

__init__(*, missing_thr: float = 0.9, zeros_thr: float = 0.9, mode_thr: float = 0.9, iv_thr: float = 0.01, lift_thr: float | None = 1.2, min_sample_rate: float = 0.05, psi_thr: float | None = 0.25, rc_thr: float | None = 0.5, corr_thr: float | None = 0.95, feature_start_aware_reference: bool = False, risk_corr_baseline: RiskCorrBaseline = 'total', psi_include_missing: bool = False, psi_include_special: bool = False, skip_rough_scan: bool = False, skip_fine_scan: bool = False, rough_iv_thr: float = 0.01, rough_lift_thr: float = 1.2, rough_min_sample_rate: float = 0.02, missing_values: List[Any] | None = None, special_values: List[Any] | None = None, binning_params: Dict[str, Any] | None = None, rough_binning_params: Dict[str, Any] | None = None, batch_size: int | None = 100, n_jobs: int = -1) -> None

初始化统计筛选策略。

参数:

名称 类型 描述 默认
missing_thr float

缺失率剔除阈值。

0.9
zeros_thr float

零值率剔除阈值。

0.9
mode_thr float

单一众数占比剔除阈值。

0.9
iv_thr float

精筛阶段保留特征所需的最低 IV。

0.01
lift_thr float | None

精筛阶段保留特征所需的最低 Lift。

1.2
min_sample_rate float

计算 Lift 时单个分箱所需的最低样本占比。

0.05
psi_thr float | None

稳定性筛选的 PSI 上限。

0.25
rc_thr float | None

排名变化率筛选阈值。

0.5
corr_thr float | None

WOE 相关性筛选阈值。

0.95
feature_start_aware_reference bool

是否默认启用 feature-start aware reference,用于 PSI 基准重锚。

False
risk_corr_baseline RiskCorrBaseline

RC 的默认基准选择方式。

'total'
psi_include_missing bool

稳定性筛选和评估报告计算 PSI 时是否纳入缺失值箱。

False
psi_include_special bool

稳定性筛选和评估报告计算 PSI 时是否纳入特殊值箱。

False
skip_rough_scan bool

是否跳过粗筛分箱阶段。

False
skip_fine_scan bool

是否跳过精筛分箱阶段。

False
rough_iv_thr float

粗筛阶段保留特征所需的最低 IV。

0.01
rough_lift_thr float

粗筛阶段保留特征所需的最低 Lift。

1.2
rough_min_sample_rate float

粗筛阶段计算 Lift 时单个分箱所需的最低样本占比。

0.02
missing_values List[Any] | None

需要视为缺失的取值列表。

None
special_values List[Any] | None

需要单独处理的特殊值列表。

None
binning_params Dict[str, Any] | None

精筛阶段分箱器参数。支持增量更新,传入的字典将与默认配置合并,未指定的参数将保留默认值。 默认配置为:{"prebinning_method": "cart", "n_bins": 10, "min_bin_size": 0.05}

None
rough_binning_params Dict[str, Any] | None

粗筛阶段分箱器参数。支持增量更新,传入的字典将与默认配置合并,未指定的参数将保留默认值。 默认配置为:{"method": "quantile", "n_bins": 20, "min_bin_size": 0.02, "merge_small_bins": True}

None
batch_size int | None

批量评估时的特征批大小。

100
n_jobs int

并行任务数,含义遵循 joblib 约定。

-1

fit

fit(df: DataFrame | DataFrame, *, target: str, features: List[str] | None = None, feature_data_source: Dict[str, List[str]] | None = None, group_col: str | None = None, time_col: str | None = None, time_grain: str | None = None, white_list: List[str] | None = None, black_list: List[str] | None = None, max_samples: int | None = None, feature_start_aware_reference: bool | None = None, risk_corr_baseline: RiskCorrBaseline | None = None) -> MarsStatsSelector

在一次样本上下文中执行统计特征筛选。

参数:

名称 类型 描述 默认
df DataFrame | DataFrame

待筛选样本表。

必需
target str

二分类目标列名。

必需
features List[str] | None

候选特征列;不传时会从样本表中自动推断。

None
feature_data_source Dict[str, List[str]] | None

特征来源映射,用于报告中追踪特征所属来源。

None
group_col str | None

已存在的分组列名,用于趋势和稳定性筛选。

None
time_col str | None

原始日期列名;与 time_grain 配合时生成时间分组。

None
time_grain str | None

时间聚合粒度,例如 "day""week""month""7d"

None
white_list List[str] | None

白名单特征,尽量绕过自动剔除规则。

None
black_list List[str] | None

黑名单特征,会被强制剔除。

None
max_samples int | None

本次筛选允许使用的最大样本量。

None
feature_start_aware_reference bool | None

是否按特征首次出现分组选择 PSI 基准。传入 None 时沿用实例初始化时保存的默认值。

None
risk_corr_baseline RiskCorrBaseline | None

本次筛选使用的 RC 基准;传入 None 时沿用实例初始化时保存的默认值。

None

返回:

类型 描述
MarsStatsSelector

拟合后的筛选器,selected_features_ 中保存最终特征列表。

引发:

类型 描述
ValueError

当输入参数、列配置或数据状态不满足当前方法要求时抛出。

transform

transform(df: Union[DataFrame, DataFrame], *, keep_target: bool = True) -> Union[pl.DataFrame, pd.DataFrame]

根据筛选结果裁剪数据,可选择保留目标列。

show_summary

show_summary() -> None

展示特征筛选漏斗摘要。

返回:

类型 描述
None

函数仅展示或记录漏斗摘要,不返回表格对象。

Notes

在 Notebook 环境中优先返回富样式表格;若环境不支持,则退化为日志打印。

示例:

>>> selector = MarsStatsSelector()
>>> selector._record_funnel("Init", "Demo", {"iv": 0.02}, 2, 1)
>>> selector.show_summary() is None
True

clear_cache

clear_cache() -> None

释放缓存的分箱器上下文。

返回:

类型 描述
None

函数仅释放缓存资源,并记录调试日志。

Notes

该方法会清理最终分箱器中缓存的数据引用,并主动触发一次垃圾回收。

示例:

>>> selector = MarsStatsSelector()
>>> selector.clear_cache() is None
True

get_binning_report

get_binning_report(df: Union[DataFrame, DataFrame]) -> MarsBinningReport

为已选中特征生成最终风险评估报告。

参数:

名称 类型 描述 默认
df Union[DataFrame, DataFrame]

用于重新评估已选中特征的样本表。

必需

返回:

类型 描述
MarsBinningReport

基于 selected_features_ 生成的风险评估报告。

引发:

类型 描述
ValueError

当筛选器尚未拟合或没有选中特征时抛出。

示例:

>>> import polars as pl
>>> df = pl.DataFrame({"age": [20, 30, 40, 50], "y": [0, 0, 1, 1]})
>>> selector = MarsStatsSelector(skip_fine_scan=True)
>>> selector.fit(df, target="y", features=["age"])
>>> report = selector.get_binning_report(df)
>>> isinstance(report, MarsBinningReport)
True

export_selector_report

export_selector_report(path: str = 'mars_selector_report.xlsx') -> None

导出选择器决策报告。

参数:

名称 类型 描述 默认
path str

持久化导出路径。引擎根据扩展名执行 .csv 或复合样式 .xlsx 的落盘处理。

'mars_selector_report.xlsx'

返回:

类型 描述
None

报告直接写入 path,函数不返回文件句柄或表格对象。

示例:

>>> from pathlib import Path
>>> from tempfile import TemporaryDirectory
>>> selector = MarsStatsSelector()
>>> selector._is_fitted = True
>>> selector._register_feature_decision("age", "Selected", "demo", "demo")
>>> with TemporaryDirectory() as tmp:
...     path = Path(tmp) / "selector.csv"
...     selector.export_selector_report(str(path))
...     path.exists()
True

save_selector_lists

save_selector_lists(path: str = 'mars_lists.json', blacklist_stages: List[str] | None = None) -> None

保存当前筛选结果中的白名单与黑名单。

参数:

名称 类型 描述 默认
path str

JSON 结构存储路径。

'mars_lists.json'
blacklist_stages List[str] | None

界定需写入惩罚名单的阶段。支持字符串模糊匹配(例如 'quality' 匹配质量校验环节)。

None

返回:

类型 描述
None

白名单与黑名单直接写入 JSON 文件。

Notes

导出的 white_list 为当前最终入选特征;black_list 为被剔除特征与 用户预设黑名单的并集。

示例:

>>> from pathlib import Path
>>> from tempfile import TemporaryDirectory
>>> selector = MarsStatsSelector()
>>> selector._is_fitted = True
>>> selector.selected_features_ = ["age"]
>>> selector.report_records_ = [{"feature": "income", "status": "Dropped", "stage": "Quality"}]
>>> with TemporaryDirectory() as tmp:
...     path = Path(tmp) / "lists.json"
...     selector.save_selector_lists(str(path))
...     MarsStatsSelector.load_lists_from_json(str(path))["white_list"]
['age']

load_lists_from_json classmethod

load_lists_from_json(path: str) -> Dict[str, List[str]]

从 JSON 文件加载白名单与黑名单。

参数:

名称 类型 描述 默认
path str

JSON 结构存储路径。

必需

返回:

类型 描述
dict

包含 white_listblack_list 的字典。

示例:

>>> from pathlib import Path
>>> from tempfile import TemporaryDirectory
>>> with TemporaryDirectory() as tmp:
...     path = Path(tmp) / "lists.json"
...     _ = path.write_text(
...         json.dumps({"white_list": ["age"], "black_list": []}),
...         encoding="utf-8",
...     )
...     MarsStatsSelector.load_lists_from_json(str(path))["white_list"]
['age']

print_stats

print_stats(iv_thresholds: List[float] | None = None) -> None

打印最终入选特征的统计摘要。

参数:

名称 类型 描述 默认
iv_thresholds List[float] | None

自定义统计边界截断数组。默认渲染 [0.02, 0.05, 0.10] 区间梯度。

None

返回:

类型 描述
None

函数仅通过日志输出统计摘要。

示例:

>>> selector = MarsStatsSelector()
>>> selector._is_fitted = True
>>> selector.selected_features_ = ["age"]
>>> selector._feature_iv_dict = {"age": 0.12}
>>> selector.print_stats([0.05]) is None
True

mars.feature.MarsLinearSelector

Bases: MarsBaseSelector

面向传统 LR 建模的线性特征筛选器。

该选择器按相关性过滤、VIF 过滤和逐步回归三个阶段收敛候选特征。 输入可以是 Polars 或 Pandas;统计建模边界会转换为 Pandas/NumPy, 以复用 statsmodels 的 Logit、AIC/BIC 和 VIF 实现。

属性:

名称 类型 描述
selected_features_ list of str

最终入选特征。

coef_table_ DataFrame

最终 Logit 模型的系数、标准误和 p-value。

vif_table_ DataFrame

VIF 阶段的最终候选特征 VIF 表。

stepwise_history_ DataFrame

逐步回归每一步的 add/drop 决策记录。

示例:

>>> import pandas as pd
>>> df = pd.DataFrame({"age": [20, 30, 40, 50], "y": [0, 0, 1, 1]})
>>> selector = MarsLinearSelector(corr_thr=0.95)
>>> selector.fit(df[["age"]], df["y"], features=["age"]).selected_features_
['age']

__init__

__init__(enable_corr_filter: bool = True, corr_thr: float = 0.8, corr_method: str = 'spearman', enable_vif_filter: bool = False, vif_threshold: float = 5.0, enable_stepwise: bool = False, stepwise_direction: str = 'forward', stepwise_criterion: str = 'aic', max_features: int | None = None, n_jobs: int = -1) -> None

初始化线性筛选器配置。

参数:

名称 类型 描述 默认
enable_corr_filter bool

是否启用相关性去重阶段。

True
corr_thr float

相关性去重阈值。

0.8
corr_method str

相关性计算方法。

'spearman'
enable_vif_filter bool

是否启用 VIF 筛查阶段。

False
vif_threshold float

VIF 阈值。

5.0
enable_stepwise bool

是否启用逐步回归阶段。

False
stepwise_direction str

逐步回归方向。

'forward'
stepwise_criterion str

逐步回归优化准则。

'aic'
max_features int | None

最终保留特征数上限。

None
n_jobs int

并行任务数量。

-1

引发:

类型 描述
ValueError

当输入参数、列配置或数据状态不满足当前方法要求时抛出。

fit

fit(X: DataFrame | DataFrame, y: Any, *, features: Sequence[str] | None = None) -> MarsLinearSelector

执行相关性、VIF 与可选 stepwise 线性特征筛选。

参数:

名称 类型 描述 默认
X DataFrame | DataFrame

输入特征表。

必需
y Any

二分类目标数组。

必需
features Sequence[str] | None

本次参与筛选的特征列;不传时使用输入表中的全部候选列。

None

返回:

类型 描述
MarsLinearSelector

已拟合的线性筛选器实例。

示例:

>>> import pandas as pd
>>> df = pd.DataFrame({"age": [20, 30, 40, 50], "y": [0, 0, 1, 1]})
>>> selector = MarsLinearSelector().fit(X, y)
>>> selector.selected_features_
['age']

mars.feature.MarsImportanceSelector

Bases: MarsBaseSelector

基于模型重要性或 SHAP 的特征筛选器。

该选择器支持直接消费已有 importance table,也可以训练 sklearn/树模型 读取 feature_importances_coef_。当 method="shap" 时, 选择器计算 mean absolute SHAP value 并统一输出 MARS importance table。

属性:

名称 类型 描述
selected_features_ list of str

最终入选特征。

importance_table_ DataFrame

标准化后的重要性表。

estimator_ Any or None

由选择器训练得到的 estimator;使用外部 importance table 时为 None

示例:

>>> import pandas as pd
>>> df = pd.DataFrame({"age": [20, 30, 40, 50], "y": [0, 0, 1, 1]})
>>> importance = pd.DataFrame({"feature": ["age"], "importance": [1.0]})
>>> selector = MarsImportanceSelector()
>>> selector.fit(df[["age"]], df["y"], features=["age"], importance_table=importance).selected_features_
['age']

__init__

__init__(estimator: Union[str, Any] = 'lgbm', estimator_params: dict | None = None, method: Literal['importance', 'shap', 'rfe', 'sfm'] = 'importance', selection_mode: Literal['top_k', 'threshold', 'percentile'] = 'top_k', selection_threshold: Union[int, float, str] = 50, cv: int = 3, n_jobs: int = -1, random_state: int = 42) -> None

初始化重要性筛选器配置。

参数:

名称 类型 描述 默认
estimator Union[str, Any]

底层模型类型或实例。

'lgbm'
estimator_params dict | None

底层模型初始化参数。

None
method Literal['importance', 'shap', 'rfe', 'sfm']

重要性筛选策略。

'importance'
selection_mode Literal['top_k', 'threshold', 'percentile']

特征保留模式。

'top_k'
selection_threshold Union[int, float, str]

对应筛选模式下的阈值。

50
cv int

交叉验证折数。

3
n_jobs int

并行任务数量。

-1
random_state int

随机种子。

42

引发:

类型 描述
ValueError

当输入参数、列配置或数据状态不满足当前方法要求时抛出。

fit

fit(X: DataFrame | DataFrame, y: Any | None = None, *, features: Sequence[str] | None = None, importance_table: DataFrame | DataFrame | None = None) -> MarsImportanceSelector

执行基于模型重要性或 SHAP 的特征筛选。

参数:

名称 类型 描述 默认
X DataFrame | DataFrame

输入特征表。若未显式传入 y,则必须包含目标列。

必需
y Any | None

二分类目标数组。

None
features Sequence[str] | None

本次参与筛选的特征列;不传时使用输入表中的全部候选列。

None
importance_table DataFrame | DataFrame | None

预先计算好的重要性表,需包含 featureimportance 列。

None

返回:

类型 描述
MarsImportanceSelector

已拟合的重要性筛选器实例。

引发:

类型 描述
NotImplementedError

当当前选项尚未实现时抛出。

ValueError

当输入参数、列配置或数据状态不满足当前方法要求时抛出。

示例:

>>> import pandas as pd
>>> df = pd.DataFrame({"age": [20, 30, 40, 50], "y": [0, 0, 1, 1]})
>>> importance = pd.DataFrame({"feature": ["age"], "importance": [1.0]})
>>> selector = MarsImportanceSelector().fit(X, importance_table=importance)
>>> selector.selected_features_
['age']