Feature¶
特征分箱、特征筛选和底层 fit / transform 对象。
Binner¶
所有分箱器都继承 MarsBinnerBase,因此共享 fit_transform、transform、
profile_bin_performance、to_dict/from_dict、prune 等规则转换、评估和序列化能力。
mars.feature.MarsBinnerBase ¶
Bases: MarsTransformer
MARS 分箱器抽象基类。
该基类定义了分箱器的公共状态、索引协议以及数值/类别特征的统一转换行为。 子类负责学习切点或类别分组规则,基类则负责缓存管理、映射导出、 WOE 物化、统计报告和 SQL 生成。
属性:
| 名称 | 类型 | 描述 |
|---|---|---|
bin_cuts_ |
dict of str to list of float
|
数值型特征的物理切点,每个列表均以 |
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 为 -1,
Other 为 -2,
Special 从 -3 开始向负方向扩展,
正常分箱索引从 0 开始递增。
示例:
__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
|
自定义缺失值列表。除了原生的 |
None
|
join_threshold
|
int
|
在 |
100
|
n_jobs
|
int
|
并行计算的核心数:
- |
-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
|
拟合完成后的当前分箱器实例。 |
示例:
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'
|
woe_batch_size
|
int
|
当 |
200
|
lazy
|
bool
|
是否保持延迟执行。为 |
False
|
返回:
| 类型 | 描述 |
|---|---|
DataFrame or DataFrame or LazyFrame
|
分箱转换结果。若设置了 |
示例:
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
|
是否返回 |
False
|
返回:
| 类型 | 描述 |
|---|---|
DataFrame or DataFrame or LazyFrame
|
分箱转换结果。 |
示例:
to_dict ¶
将分箱器状态序列化为 Python 字典。
返回:
| 类型 | 描述 |
|---|---|
dict of str to Any
|
包含 |
Notes
返回结果只包含分箱规则和必要状态,不包含缓存的训练数据本体。
示例:
from_dict
classmethod
¶
从字典恢复分箱器实例。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
data
|
Dict[str, Any]
|
由 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
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'}
clear_cache ¶
清理缓存的训练数据引用。
Notes
该方法会清空 _cache_X 和 _cache_y,并主动触发一次垃圾回收。
适合在模型训练完成、无需再次即时重算统计量时调用。
返回:
| 类型 | 描述 |
|---|---|
None
|
函数仅清理训练数据缓存。 |
示例:
get_bin_mapping ¶
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 同步回写到 |
True
|
batch_size
|
int
|
特征分批处理大小。减小该值可进一步降低内存峰值。 |
100
|
include_bin_index
|
bool
|
是否在返回明细中保留内部 |
False
|
ordered_metric_sort_by
|
OrderedMetricSortBy
|
KS/AUC 的排序口径。默认 |
'woe'
|
返回:
| 类型 | 描述 |
|---|---|
DataFrame or DataFrame
|
包含各特征各分箱统计量的明细表,通常包括样本数、坏样本数、 分布占比、WOE、IV、KS、AUC 和 Lift 等指标。 |
Notes
该方法依赖当前分箱器已完成拟合,并会复用 transform(return_type="index")
的输出结果来执行聚合统计。
示例:
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
|
返回被修改特征的最新分箱统计分布表;若没有任何有效特征被更新,则返回 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
当缺少用于重算 WOE 的 |
示例:
prune ¶
裁剪分箱器内部状态,仅保留指定特征。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
keep_features
|
List[str]
|
需要保留状态的特征列表。 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
MarsBinnerBase
|
裁剪完成后的当前实例。 |
Notes
该方法会同步裁剪切点、类别分组、标签映射、WOE 映射以及 feature_names_in_,
常用于特征筛选完成后缩小序列化模型体积。
示例:
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 子句)。 |
示例:
mars.feature.MarsNativeBinner ¶
Bases: MarsBinnerBase
原生高性能特征分箱器。
基于 Polars 向量化计算与 Scikit-Learn 决策树算法构建。支持针对连续型变量的等频、 等宽与决策树(CART)离散化策略,以及针对类别型变量的头部频数保留策略。特殊值与 缺失值在执行核心分箱逻辑前会被强制物理隔离。
属性:
| 名称 | 类型 | 描述 |
|---|---|---|
bin_cuts_ |
dict of str to list of float
|
针对连续型特征拟合生成的物理切点映射字典。数组形态为 |
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
|
透传给 |
None
|
remove_empty_bins
|
bool
|
是否在 |
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
|
目标变量。仅当 |
None
|
features
|
list[str] | None
|
本次拟合的特征列;不传时使用全部候选列。 |
None
|
cat_features
|
list[str] | None
|
明确指定的类别特征列。 |
None
|
返回:
| 类型 | 描述 |
|---|---|
MarsNativeBinner
|
拟合完成后的原生分箱器实例。 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
当输入参数、列配置或数据状态不满足当前方法要求时抛出。 |
示例:
mars.feature.MarsLiteOptBinner ¶
Bases: MarsBinnerBase
轻量级启发式最优分箱器。
该分箱器面向宽表风控分析场景,先复用 MarsNativeBinner 生成细粒度预分箱,
再在预分箱统计表上执行趋势约束合并。它不依赖数学规划求解器,适合作为
MarsOptimalBinner 的高速轻量替代方案。
属性:
| 名称 | 类型 | 描述 |
|---|---|---|
bin_cuts_ |
dict of str to list of float
|
数值特征最终切点,形态为 |
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
|
趋势约束,支持以下取值:
|
'auto'
|
prebinning_method
|
PrebinningMethod
|
预分箱策略,可选 |
'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
|
当 |
to_dict ¶
将轻量级分箱器状态序列化为字典。
返回:
| 类型 | 描述 |
|---|---|
Dict[str, Any]
|
包含构造参数与拟合后状态的可序列化字典。 |
from_dict
classmethod
¶
从字典恢复轻量级分箱器实例。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
data
|
Dict[str, Any]
|
由 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
MarsLiteOptBinner
|
恢复后的已拟合轻量级分箱器。 |
示例:
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
|
最优求解失败后使用的原生分箱回退参数。只允许覆盖
|
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) -> MarsOptimalBinner
拟合最优分箱器。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
X
|
DataFrame | DataFrame
|
输入特征矩阵。 |
必需 |
y
|
Series | Series | ndarray | list[Any]
|
目标变量。最优分箱依赖监督信息,必须提供。 |
必需 |
features
|
list[str] | None
|
本次拟合的特征列;不传时使用全部候选列。 |
None
|
cat_features
|
list[str] | None
|
明确指定的类别特征列。 |
None
|
返回:
| 类型 | 描述 |
|---|---|
MarsOptimalBinner
|
拟合完成后的最优分箱器实例。 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
当输入参数、列配置或数据状态不满足当前方法要求时抛出。 |
示例:
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
|
精筛阶段分箱器参数。支持增量更新,传入的字典将与默认配置合并,未指定的参数将保留默认值。
默认配置为: |
None
|
rough_binning_params
|
Dict[str, Any] | None
|
粗筛阶段分箱器参数。支持增量更新,传入的字典将与默认配置合并,未指定的参数将保留默认值。
默认配置为: |
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
|
原始日期列名;与 |
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
|
是否按特征首次出现分组选择 PSI 基准。传入 |
None
|
risk_corr_baseline
|
RiskCorrBaseline | None
|
本次筛选使用的 RC 基准;传入 |
None
|
返回:
| 类型 | 描述 |
|---|---|
MarsStatsSelector
|
拟合后的筛选器, |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
当输入参数、列配置或数据状态不满足当前方法要求时抛出。 |
transform ¶
transform(df: Union[DataFrame, DataFrame], *, keep_target: bool = True) -> Union[pl.DataFrame, pd.DataFrame]
根据筛选结果裁剪数据,可选择保留目标列。
show_summary ¶
clear_cache ¶
get_binning_report ¶
为已选中特征生成最终风险评估报告。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
df
|
Union[DataFrame, DataFrame]
|
用于重新评估已选中特征的样本表。 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
MarsBinningReport
|
基于 |
引发:
| 类型 | 描述 |
|---|---|
ValueError
|
当筛选器尚未拟合或没有选中特征时抛出。 |
示例:
export_selector_report ¶
导出选择器决策报告。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
path
|
str
|
持久化导出路径。引擎根据扩展名执行 |
'mars_selector_report.xlsx'
|
返回:
| 类型 | 描述 |
|---|---|
None
|
报告直接写入 |
示例:
>>> 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
¶
从 JSON 文件加载白名单与黑名单。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
path
|
str
|
JSON 结构存储路径。 |
必需 |
返回:
| 类型 | 描述 |
|---|---|
dict
|
包含 |
示例:
>>> 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 ¶
打印最终入选特征的统计摘要。
参数:
| 名称 | 类型 | 描述 | 默认 |
|---|---|---|---|
iv_thresholds
|
List[float] | None
|
自定义统计边界截断数组。默认渲染 [0.02, 0.05, 0.10] 区间梯度。 |
None
|
返回:
| 类型 | 描述 |
|---|---|
None
|
函数仅通过日志输出统计摘要。 |
示例:
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
|
已拟合的线性筛选器实例。 |
示例:
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 时为 |
示例:
>>> 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
|
Any | None
|
二分类目标数组。 |
None
|
features
|
Sequence[str] | None
|
本次参与筛选的特征列;不传时使用输入表中的全部候选列。 |
None
|
importance_table
|
DataFrame | DataFrame | None
|
预先计算好的重要性表,需包含 |
None
|
返回:
| 类型 | 描述 |
|---|---|
MarsImportanceSelector
|
已拟合的重要性筛选器实例。 |
引发:
| 类型 | 描述 |
|---|---|
NotImplementedError
|
当当前选项尚未实现时抛出。 |
ValueError
|
当输入参数、列配置或数据状态不满足当前方法要求时抛出。 |
示例: