跳转至

Feature

状态:Stable。 完整操作见分箱与风险评估和 特征筛选。

Binner

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 为 -1, Other 为 -2, Special 从 -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

正常分箱数量上限,不含 Missing、Other 和 Special 箱。 单调性约束、样本量或重复切点可能使实际箱数减少。

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

需要单独成箱的业务取值,例如 -999、-1。 这些值不参与正常区间切分,使用从 -3 开始的负数索引;默认不额外配置。

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

除原生 null 和 NaN 外,需要映射到 Missing 箱的取值;默认不额外配置。

None
join_threshold int

类别转换时选择映射实现的阈值,默认为 100。 已拟合类别映射的条目数大于该值时使用 Hash Join,否则使用 replace。

100
n_jobs int

并行任务数。-1 使用 CPU 核心数减 1,至少为 1; 1 使用单任务,其余值传给具体分箱算法。

-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
) -> _MarsBinnerT

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

参数:

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

输入特征矩阵。

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

与 X 按行对应的目标标签。CART、LiteOpt 和 Optimal 分箱要求提供; 无监督分箱可省略。提供标签后还会计算 WOE,标签要求由具体算法确定。

None
features list[str] | None

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

None
cat_features list[str] | None

强制按类别处理的列;不传时由具体分箱器按数据类型识别。

None

返回:

类型 描述
MarsBinnerBase

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

引发:

类型 描述
ValueError

请求的特征或类别特征不在输入中时抛出。

Notes

重复拟合会重新学习本轮规则、WOE 和诊断,保留构造配置。 update_bins 明确设置的规则在本轮仍有同类型特征时继续生效。 失败拟合后不能转换、评估或保存旧结果;可以读取本轮诊断并再次拟合。

示例:

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

get_fit_report

get_fit_report() -> pl.DataFrame

返回逐特征拟合诊断表。

返回:

类型 描述
DataFrame

固定包含 feature、dtype、feature_type、status、 usable、n_bins 与 reason。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> report = MarsNativeBinner(n_bins=2).fit(X).get_fit_report()
>>> report["status"].to_list()
['fitted']

transform

transform(
    X: Union[DataFrame, LazyFrame, DataFrame],
    *,
    features: list[str] | None = None,
    on_missing: Literal[
        "error", "warn", "ignore"
    ] = "error",
    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]

待转换的数据集。

必需
features list[str] | None

需要转换的已拟合规则子集。不传时要求输入包含全部可用规则特征。

None
on_missing Literal['error', 'warn', 'ignore']

输入缺少请求特征时的处理策略。默认报错;warn 与 ignore 只转换实际存在的已知规则列,其中 warn 还会记录缺列警告。

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

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

'index'
woe_batch_size int

当 return_type="woe" 且请求特征尚未物化 WOE 映射时, 计算必要训练统计的特征列批宽;已有映射复用,不准备未请求特征。

200
lazy bool

是否强制返回 pl.LazyFrame。默认 False 沿用输入的执行模式; 输入本身为 LazyFrame 时,结果仍为 LazyFrame。样本转换保持延迟, 但首次请求 WOE 时仍须先计算缺失的训练统计。

False

返回:

类型 描述
DataFrame or DataFrame or LazyFrame

保留原始列,并追加 _bin 或 _woe 转换列。非延迟结果默认返回 Polars 表; 设置 set_output("pandas") 后返回 Pandas 表。

引发:

类型 描述
ValueError

特征缺失、策略无效或 WOE 映射不完整时抛出。

示例:

>>> 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]

将分箱器状态编码为版本化 JSON-compatible 字典。

返回:

类型 描述
dict of str to Any

包含 artifact 类型、schema 版本、分箱器类型、参数与状态。

Notes

返回结果不包含缓存的训练数据本体。旧版仅含 params/state 的载荷 不再受支持。

示例:

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

from_dict classmethod

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

从当前版本的自描述字典恢复分箱器实例。

参数:

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

由 to_dict 生成的状态字典。

必需

返回:

类型 描述
MarsBinnerBase

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

引发:

类型 描述
ValueError

载荷类型、schema 版本、分箱器类型或状态结构不受支持时抛出。

示例:

>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> source = MarsNativeBinner(n_bins=2).fit(X)
>>> restored = MarsBinnerBase.from_dict(source.to_dict())
>>> type(restored).__name__
'MarsNativeBinner'

save_json

save_json(path: str | Path) -> None

将当前分箱规则原子写入正式 JSON artifact。

参数:

名称 类型 描述 默认
path str | Path

输出文件路径;父目录必须已经存在。

必需

返回:

类型 描述
None

方法仅写入 artifact 文件。

示例:

>>> from pathlib import Path
>>> from tempfile import TemporaryDirectory
>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> binner = MarsNativeBinner(n_bins=2).fit(X)
>>> with TemporaryDirectory() as tmp:
...     path = Path(tmp) / "binner.json"
...     binner.save_json(path)
...     path.exists()
True

load_json classmethod

load_json(path: str | Path) -> MarsBinnerBase

从正式 JSON artifact 恢复具体分箱器。

参数:

名称 类型 描述 默认
path str | Path

已存在的 artifact 文件路径。

必需

返回:

类型 描述
MarsBinnerBase

artifact 指定的具体分箱器子类实例。

示例:

>>> from pathlib import Path
>>> from tempfile import TemporaryDirectory
>>> X = pl.DataFrame({"age": [20, 30, 40, 50]})
>>> with TemporaryDirectory() as tmp:
...     path = Path(tmp) / "binner.json"
...     MarsNativeBinner(n_bins=2).fit(X).save_json(path)
...     restored = MarsBinnerBase.load_json(path)
...     type(restored).__name__
'MarsNativeBinner'

__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

分箱索引到标签的映射字典。

引发:

类型 描述
KeyError

特征没有可用分箱标签映射时抛出。

示例:

>>> 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",
    features: list[str] | None = None,
) -> pl.DataFrame | pd.DataFrame

计算分箱表现统计报告。

参数:

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

原始特征数据集。

必需
y Series | Series

二分类目标标签,仅接受 0/1、Boolean 及对应的合法字符串。 null、NaN 和空字符串表示未表现样本。-1 视为非法标签,不表示未表现。

必需
update_woe bool

是否用本次已表现样本计算的 WOE 更新 bin_woes_,默认为 True。 设为 False 时只返回统计结果,保留已有 WOE 映射。

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'
features list[str] | None

需要评估的已拟合规则子集;不传时要求 X 包含全部规则特征。

None

返回:

类型 描述
DataFrame or DataFrame

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

引发:

类型 描述
ValueError

标签含非法值、X 与 y 行数不一致,或没有任何已表现样本时抛出。

Notes

该方法依赖当前分箱器已完成拟合,并会复用 transform(return_type="index") 的输出结果来执行聚合统计。评估前会剔除未表现样本, 因此本表的样本数、分布和监督指标均使用已表现样本;分箱规则保持不变。合法单类别可生成计数和坏账率, 缺少两类支持的监督指标沿用缺失状态;校验失败不更新已有 WOE。

示例:

>>> 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,
    *,
    on_unknown: Literal["error", "warn", "ignore"] = "error"
) -> pl.DataFrame | pd.DataFrame

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

用传入的切点或类别分组替换已有规则,再计算已更新特征的 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

二分类目标标签,支持 0/1、Boolean 及既有字符串表示;null/NaN 和空字符串 不参与统计。此接口不将 -1 作为未表现哨兵。若为 None,尝试使用拟合缓存。

None
on_unknown Literal['error', 'warn', 'ignore']

bin_rules 包含未知或无规则特征时的处理策略,默认报错。 warn 记录警告并跳过,ignore 直接跳过;至少需要更新一个已知特征。

'error'

返回:

类型 描述
DataFrame or DataFrame

返回被修改特征的最新分箱统计分布表。

引发:

类型 描述
ValueError

缺少重算所需的 X/y、标签非法或长度不匹配、没有观测标签、 on_unknown 非法或没有已知特征被更新。标签校验失败不会修改规则和 WOE。

示例:

>>> 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

裁剪完成后的当前实例。

引发:

类型 描述
ValueError

keep_features 包含未知或无可用规则的特征时抛出。

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

是否把 SQL NULL 映射到 Missing 箱对应的值,默认为 True; 设为 False 时输出 NULL。

True
map_special bool

是否把特殊值映射到 Special 箱对应的值,默认为 True; 设为 False 时保留特殊值原值。

True

返回:

类型 描述
str

逗号分隔的 SQL 表达式,可嵌入 SELECT 子句。

引发:

类型 描述
ValueError

特征未知、规则或 WOE 映射不完整、SQL 值不可安全表示时抛出。

示例:

>>> 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 和决策树学习分箱规则。

数值特征支持等频、等宽和决策树(CART)分箱。类别特征按频数保留 前 n_bins 个类别,其余类别进入 Other。拟合正常箱时排除缺失值和特殊值。

属性:

名称 类型 描述
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

长尾或零值集中的数值分布可能产生空箱或小样本箱。等频、等宽分箱可以通过 merge_small_bins=True 合并小箱;等宽分箱还可用 remove_empty_bins=True 移除空箱。两个选项默认均关闭。

示例:

>>> 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,
    join_threshold: int = 100,
    n_jobs: int = -1
) -> None

初始化原生分箱器。

参数:

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

数值分箱方法,默认为等频 "quantile";"uniform" 为等宽, "cart" 使用目标标签学习切点。类别特征始终按频数保留类别。

'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。 CART 用于最小叶子样本数;等频、等宽仅在 merge_small_bins=True 时生效。

0.05
merge_small_bins bool

是否在等频、等宽分箱后合并占比不足 min_bin_size 的箱,默认关闭。

False
cart_params Dict[str, Any] | None

仅在 method="cart" 时传给 DecisionTreeClassifier 的额外参数; 默认使用空字典。

None
remove_empty_bins bool

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

False
join_threshold int

高基数类别映射切换为 Hash Join 的阈值。

100
n_jobs int

CART 的并行任务数。-1 使用 CPU 核心数减 1,至少为 1; 1 使用单任务。

-1

mars.feature.MarsLiteOptBinner

Bases: MarsBinnerBase

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

先用 MarsNativeBinner 生成预分箱,再按坏账率趋势合并相邻数值箱。 适合需要趋势约束、且希望省去数学规划求解的宽表分析。

属性:

名称 类型 描述
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; 缺失值和特殊值仍计入分母。

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 使用 CPU 核心数减 1, 至少为 1;1 使用单任务。

-1

引发:

类型 描述
ValueError

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

mars.feature.MarsOptimalBinner

Bases: MarsBinnerBase

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

数值特征先由 MarsNativeBinner 预分箱,再交给 OptBinning 求解。 求解器在箱数、事件率趋势、最小样本量和事件数约束下优化 IV。 类别特征使用 OptBinning 的类别合并。

属性:

名称 类型 描述
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

预分箱切点限定数值求解的搜索范围。样本不足、预分箱不可用、求解异常 或无可行解时,数值特征回退到原生分箱,并在 fit_failures_ 中记录原因。 部分特征仍有可用规则时允许拟合成功;全部特征无可用规则时抛出异常。

示例:

>>> 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;回退规则可少于该值。

2
min_bin_size float

数值正常箱占拟合表总行数的最小比例,默认为 0.05。 排除该特征的缺失值和特殊值后,仍按总行数计算最小样本数。

0.05
min_bin_n_event int

数值最优求解中每箱最少的目标事件数,默认为 30。

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;其余合并为 __Mars_Other_Pre__。None 表示关闭这一步截断。

100
min_cat_fraction float

传给 OptBinning cat_cutoff 的低频类别合并阈值,默认为 0.05。

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

数值最优求解失败后使用的原生分箱配置。默认使用等频分箱, 继承 n_bins、min_bin_size,并开启小箱合并。只允许覆盖 method、n_bins、min_bin_size、merge_small_bins、 remove_empty_bins 和 cart_params。

None
join_threshold int

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

100
n_jobs int

预分箱与逐特征求解的并行任务数。-1 使用 CPU 核心数减 1, 至少为 1;1 使用单任务。

-1

引发:

类型 描述
ValueError

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

Selector

mars.feature.MarsStatsSelector

Bases: MarsBaseSelector

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

依次检查数据质量、IV/Lift、PSI、RC 和 WOE 相关性,并应用白黑名单。 构造函数只保存阈值、分箱策略、缺失/特殊值配置以及运行资源参数;样本数据、 目标列、特征范围、分组列和时间列都由 fit 传入。 质量、分布和 PSI 使用全量样本;监督分箱、IV/Lift、RC 与 WOE 相关性只使用 target 非空的已表现样本。

可以先用粗分箱减少候选特征,再用精细分箱和稳定性阈值筛选。 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, psi_thr=None, rc_thr=None)
>>> 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.90;超过上限时剔除特征。

0.9
zeros_thr float

全量样本零值率上限,默认为 0.90;超过上限时剔除特征。

0.9
mode_thr float

全量样本众数占比上限,默认为 0.90;超过上限时剔除特征。

0.9
iv_thr float

精筛 IV 下限,默认为 0.01;IV 大于等于该值时保留。 IV 不达标的特征仍可通过 Lift 条件召回。

0.01
lift_thr float | None

精筛 Lift 召回阈值,默认为 1.2。至少一个 Total 分箱的 Lift 大于该值、且样本占比大于 min_sample_rate 时可召回;None 关闭召回。

1.2
min_sample_rate float

精筛 Lift 召回所需的单箱样本占比下限,默认为 0.05,使用严格大于比较。

0.05
psi_thr float | None

各监控分组最大 PSI 的上限,默认为 0.25;PSI 必须小于该值。 None 关闭 PSI 筛选。

0.25
rc_thr float | None

各监控分组最小风险排序相关系数 RC 的下限,默认为 0.5; RC 必须大于等于该值。None 关闭 RC 筛选。

0.5
corr_thr float | None

已表现样本上的绝对 WOE 相关系数上限,默认为 0.95。 超过上限时按 IV 优先级剔除一侧;None 关闭相关性筛选。

0.95
feature_start_aware_reference bool

是否默认启用按特征上线时间重锚的稳定性参考,默认为 False。启用后, fit 必须收到可解析的 time_col;仅有 group_col 不能识别上线日期。 上线日按数据中实际存在的自然日识别:日缺失率不低于 99% 为 inactive, 候选日前至少 90% 日期 inactive,且候选日起最多 3 日内至少 2/3 日期 active。这些阈值固定且不可配置;不补齐不存在的自然日,尾部不足 3 日 时缩短确认窗口。显式 benchmark_df 优先并禁用该逻辑。

成功识别的特征使用上线首期分布作为 PSI 基准,并只在上线后计算 PSI/RC 监控指标;其他特征沿用默认参考。risk_corr_baseline="total" 只调整 RC 监控窗口,"benchmark" 可在没有显式 benchmark 时使用上线首期坏率, "first_group" 仍使用全局首组。该参数只影响 Stage 4 PSI 和 Stage 5 RC, 不改变 Stage 1 数据质量、Stage 2/3 IV/Lift、分箱或 WOE 相关性筛选。

False
risk_corr_baseline RiskCorrBaseline

RC 坏率排序的参考分布,默认为 "total"。"benchmark" 使用显式基准样本或识别出的上线首期,"first_group" 使用最早分组。

'total'
psi_include_missing bool

稳定性筛选和评估报告的 PSI 是否纳入 Missing 箱,默认不纳入。

False
psi_include_special bool

稳定性筛选和评估报告的 PSI 是否纳入 Special 箱,默认不纳入。

False
skip_rough_scan bool

是否跳过粗筛分箱阶段。

False
skip_fine_scan bool

是否跳过精筛分箱阶段。

False
rough_iv_thr float

粗筛 IV 阈值,默认为 0.01,使用严格大于比较;未通过时可由 Lift 召回。

0.01
rough_lift_thr float

粗筛 Lift 召回阈值,默认为 1.2;至少一个分箱的 Lift 和样本占比 分别大于该值和 rough_min_sample_rate 时可召回。

1.2
rough_min_sample_rate float

粗筛 Lift 召回所需的单箱样本占比下限,默认为 0.02,使用严格大于比较。

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;None 也按 100 处理,必须为正整数。 贯穿质量 overview、粗筛表现、精筛、稳定性和 WOE 转换;相关性另按私有 行块合并完整 Pearson。原始表、规则、报告和全局 P² 结果仍占内存, 此参数不表示行数、总内存上限或线程/进程并发数。

100
n_jobs int

分箱器的并行任务数;-1 使用 CPU 核心数减 1,至少为 1。 精筛分箱默认继承该值,显式 binning_params['n_jobs'] 优先。

-1

引发:

类型 描述
ValueError

batch_size 不是正整数或 None,或参考口径参数无效时抛出。

fit

fit(
    df: DataFrame | DataFrame,
    *,
    target: str,
    benchmark_df: DataFrame | DataFrame | None = None,
    features: list[str] | None = None,
    feature_data_source: dict[str, list[str]] | None = None,
    feature_metadata: FeatureMetadata | None = None,
    business_context: dict[str, Any] | 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,
    feature_start_aware_reference: bool | None = None,
    risk_corr_baseline: RiskCorrBaseline | None = None
) -> MarsStatsSelector

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

参数:

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

待筛选样本表。

必需
target str

二分类目标列名。

必需
benchmark_df DataFrame | DataFrame | None

基准样本表。提供后用于拟合粗筛、精筛规则,并提供 PSI 参考分布; 监督分箱只使用基准表中已表现样本。质量和 PSI 使用完整 df, IV、Lift、RC 和相关性使用 df 中 target 非空的已表现样本。

None
features list[str] | None

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

None
feature_data_source dict[str, list[str]] | None

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

None
feature_metadata FeatureMetadata | None

本次候选特征的业务字典或含 feature 列的 Pandas/Polars 表。

None
business_context dict[str, Any] | None

可选 JSON 业务上下文,会传递给下游评估报告。

None
group_col str | None

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

None
time_col str | None

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

None
time_grain str | None

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

None
white_list list[str] | None

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

None
black_list list[str] | None

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

None
feature_start_aware_reference bool | None

是否按特征上线时间重锚稳定性参考。传入 None 时沿用构造函数中的默认 配置,传入布尔值时覆盖当前实例配置并用于本次筛选及后续报告。启用后 必须提供可解析的 time_col;仅有 group_col 不能识别上线日期。识别先 按数据中实际存在的自然日执行:日缺失率不低于 99% 为 inactive,候选日 前至少 90% 日期 inactive,候选日起最多 3 日内至少 2/3 日期 active。 这些阈值固定且不可配置;不补齐不存在的自然日,尾部不足 3 日时缩短窗口。

成功识别的特征按上线日映射到 time_grain 或 group_col 分组,使用上线 首期分布作为 PSI 基准,并排除上线前 PSI/RC 监控分组;其他特征沿用默认 参考。risk_corr_baseline="total" 只调整 RC 监控窗口,"benchmark" 可在未传显式 benchmark 时使用上线首期坏率,"first_group" 仍使用全局 首组。显式 benchmark_df 优先,此参数会被忽略并记录一次 warning。 它不影响 Stage 1 数据质量、Stage 2/3 IV/Lift、分箱或 WOE 相关性筛选。

None
risk_corr_baseline RiskCorrBaseline | None

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

None

返回:

类型 描述
MarsStatsSelector

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

引发:

类型 描述
ValueError

当标签、稳定性分组、benchmark schema 或分箱结果不满足要求时抛出。

Notes

psi_thr 或 rc_thr 任一非 None 时,必须提供 group_col 或 time_col。传入 benchmark 后不会把其行合并进 df 的趋势分组或 Total。 start-aware 的实际状态、识别特征和上线日期可通过分箱报告 report_meta 中的 feature_start_aware_reference、feature_start_reference_features 和 feature_start_reference_dates 查看。前者表示是否实际构造出 reference, 不会直接回显调用参数。晚接入特征若已因全量缺失率超过 missing_thr 在 Stage 1 被删除,不会进入后续 start-aware 稳定性计算。

示例:

>>> benchmark = pl.DataFrame(
...     {"age": [20, 30, 40, 50], "y": [0, 0, 1, 1]}
... )
>>> df = benchmark.with_columns(pl.lit("current").alias("period"))
>>> selector = MarsStatsSelector(
...     skip_fine_scan=True,
...     rough_iv_thr=-1.0,
...     psi_thr=100.0,
...     rc_thr=None,
...     corr_thr=None,
... )
>>> selector.fit(
...     df,
...     target="y",
...     benchmark_df=benchmark,
...     features=["age"],
...     group_col="period",
... ).selected_features_
['age']
>>> temporal_df = pl.DataFrame(
...     {
...         "dt": [
...             "2024-01-01", "2024-01-02", "2024-01-03",
...             "2024-02-15", "2024-02-16", "2024-02-17",
...         ],
...         "score": [None, None, None, 0.1, 0.5, 0.9],
...         "y": [0, 1, 0, 0, 1, 1],
...     }
... )
>>> temporal_selector = MarsStatsSelector(
...     skip_fine_scan=True,
...     rough_iv_thr=-1.0,
...     psi_thr=100.0,
...     rc_thr=None,
...     corr_thr=None,
...     feature_start_aware_reference=True,
... )
>>> temporal_selector.fit(
...     temporal_df,
...     target="y",
...     features=["score"],
...     time_col="dt",
...     time_grain="month",
... )
>>> temporal_selector.get_binning_report(temporal_df).report_meta[
...     "feature_start_reference_features"
... ]
['score']

fit_transform

fit_transform(
    df: DataFrame | DataFrame,
    *,
    target: str,
    benchmark_df: DataFrame | DataFrame | None = None,
    features: list[str] | None = None,
    feature_data_source: dict[str, list[str]] | None = None,
    feature_metadata: FeatureMetadata | None = None,
    business_context: dict[str, Any] | 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,
    feature_start_aware_reference: bool | None = None,
    risk_corr_baseline: RiskCorrBaseline | None = None
) -> Union[pl.DataFrame, pd.DataFrame]

使用与 :meth:fit 相同的参数拟合,并转换当前数据。

参数:

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

待筛选并转换的样本表。

必需
target str

二分类目标列名。

必需
benchmark_df DataFrame | DataFrame | None

可选基准样本;提供后优先用于分箱和稳定性参考,并禁用 feature_start_aware_reference。

None
features list[str] | None

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

None
feature_data_source dict[str, list[str]] | None

特征来源映射,用于筛选报告的数据源标识。

None
feature_metadata FeatureMetadata | None

本次候选特征的业务字典或含 feature 列的 Pandas/Polars 表。

None
business_context dict[str, Any] | None

可选 JSON 业务上下文,会传递给下游评估报告。

None
group_col str | None

已存在的趋势分组列。

None
time_col str | None

原始日期列;启用 start-aware 时必须提供且能够解析。

None
time_grain str | None

time_col 的聚合粒度,例如 "day"、"week"、"month" 或 "7d"。

None
white_list list[str] | None

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

None
black_list list[str] | None

强制剔除的黑名单特征。

None
feature_start_aware_reference bool | None

是否按特征上线时间重锚稳定性参考。传入 None 时沿用构造函数配置, 传入布尔值时覆盖当前实例配置。识别按实际存在的自然日执行:日缺失率 不低于 99% 为 inactive,候选日前至少 90% 日期 inactive,候选日起最多 3 日内至少 2/3 日期 active;阈值固定且不可配置,不补齐不存在的日期, 尾部不足 3 日时缩短确认窗口。

成功识别的特征使用上线首期 PSI 基准并排除上线前 PSI/RC 监控分组;其他 特征沿用默认参考。RC 参考仍由 risk_corr_baseline 控制:"total" 只 调整监控窗口,"benchmark" 可使用上线首期坏率,"first_group" 仍 使用全局首组。显式 benchmark_df 优先并产生忽略提示。该参数不影响 Stage 1 数据质量、Stage 2/3 IV/Lift、分箱或 WOE 相关性筛选。

None
risk_corr_baseline RiskCorrBaseline | None

本次筛选使用的 RC 基准;传入 None 时沿用构造函数配置。

None

返回:

类型 描述
DataFrame | DataFrame

保留已选特征,并在目标列存在时附加目标列;输出格式由 set_output 控制。

Notes

该方法等价于依次调用 fit(...) 和 transform(df)。start-aware 的实际状态、 识别特征与上线日期可在随后生成的分箱报告 report_meta 中查看。

transform

transform(
    df: Union[DataFrame, DataFrame],
    *,
    keep_target: bool = True,
    on_missing: Literal["error", "warn", "ignore"] = "error"
) -> Union[pl.DataFrame, pd.DataFrame]

按筛选结果保留特征,并按需附加目标列。

参数:

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

待转换的样本表。

必需
keep_target bool

是否附加拟合时指定的目标列,默认为 True。输入未包含目标列时不附加。

True
on_missing Literal['error', 'warn', 'ignore']

输入缺少已选特征时的处理策略,默认报错。warn 记录警告后跳过, ignore 直接跳过;两者均只返回实际存在的已选特征。

'error'

返回:

类型 描述
DataFrame or DataFrame

按已选特征顺序裁剪的表;保留目标时,目标列放在末尾。 输出格式由 set_output 控制。

Notes

未拟合、缺少已选特征或 on_missing 无效时,继承的校验会抛出 ValueError。

show_summary

show_summary() -> None

展示特征筛选漏斗摘要。

返回:

类型 描述
None

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

引发:

类型 描述
ValueError

尚无可展示的漏斗统计时抛出。

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: DataFrame | DataFrame,
    *,
    benchmark_df: DataFrame | DataFrame | None = None
) -> MarsBinningReport

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

参数:

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

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

必需
benchmark_df DataFrame | DataFrame | None

PSI expected distribution 和可选 benchmark RC 的基准样本。若 fit 使用过 benchmark,本方法必须重新传入;固定分箱器不会重新拟合。

None

返回:

类型 描述
MarsBinningReport

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

引发:

类型 描述
ValueError

当筛选器尚未拟合、没有选中特征、缺少所需 benchmark 或输入无效时抛出。

示例:

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

selector 不保存原始 benchmark。重新生成报告时显式重传可避免 PSI 基准静默 回退到 df 的最早分组。

export_selector_report

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

导出选择器决策报告。

参数:

名称 类型 描述 默认
path str

输出路径。按扩展名写入 .csv 或带样式的 .xlsx 文件。

'mars_selector_report.xlsx'

返回:

类型 描述
None

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

引发:

类型 描述
ValueError

决策报告为空时抛出。

示例:

>>> 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_list 与 black_list 的字典。

引发:

类型 描述
FileNotFoundError

名单文件不存在时抛出。

ValueError

JSON 顶层不是对象,或白黑名单字段不是字符串列表时抛出。

示例:

>>> 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

IV 统计阈值,按升序输出达到各阈值的特征数;默认 [0.02, 0.05, 0.10]。

None

返回:

类型 描述
None

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

引发:

类型 描述
ValueError

没有任何特征通过筛选时抛出。

示例:

>>> 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: _MarsXYSelector

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

依次按配置执行相关性、VIF 和逐步回归筛选。输入支持 Polars 和 Pandas, 计算时转为 Pandas/NumPy。VIF 和 Logit 诊断使用 statsmodels。

属性:

名称 类型 描述
selected_features_ list of str

最终入选特征。

coef_table_ DataFrame

Logit 系数表。逐步回归成功时还包含标准误和 p-value; 未执行或无法完成 Logit 诊断时可能为空。

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,达到阈值即剔除一侧。 优先保留与目标的绝对 Spearman 相关系数较大的特征,相等时保留靠前者。

0.8
corr_method str

特征间相关系数的 Pandas 计算方法,默认为 "spearman"。

'spearman'
enable_vif_filter bool

是否启用 VIF 筛查阶段。

False
vif_threshold float

启用 VIF 筛选时的上限,默认为 5.0;每轮剔除 VIF 最高且超过上限的特征。

5.0
enable_stepwise bool

是否启用逐步回归阶段。

False
stepwise_direction str

仅在启用逐步回归时生效。支持 "forward"、"backward" 和 "both",默认前向加入特征。

'forward'
stepwise_criterion str

仅在启用逐步回归时生效。支持 "aic" 和 "bic",默认优化 AIC; 只有信息准则下降时才接受加入或移除。

'aic'
max_features int | None

最终特征数上限,默认不限。超出时按与目标的绝对 Spearman 相关系数保留前 N 个;前向加入阶段也受该上限约束。

None
n_jobs int

保留的并行配置,默认为 -1;当前筛选实现仅保存该值。

-1

引发:

类型 描述
ValueError

逐步回归方向或信息准则不受支持时抛出。

fit

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

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

参数:

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

输入特征表。候选列先尝试转为数值,完全无法转换的列会被剔除。

必需
y Any

按位置与 X 对应的二分类目标数组。候选数值列或目标存在 缺失、NaN 或无穷值的行会整行删除;清理后必须保留两个目标类别。

必需
features Sequence[str] | None

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

None
feature_metadata FeatureMetadata | None

特征英文 ID 对应的展示名、业务来源、单位和描述,用于相关性报告。

None
business_context dict[str, Any] | None

可序列化为 JSON 的业务上下文;未提供的样本单位和训练集含义保持 unknown。

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: _MarsXYSelector

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

可读取已有重要性表,也可训练模型后读取 feature_importances_ 或绝对系数。 method="shap" 使用平均绝对 SHAP 值。独热编码列的重要性会求和到原始特征, 最终统一输出 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"] = "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"。名称支持 "rf"、"extra_trees"、"lr"、"lgbm"、"xgb" 和 "cat"。 传入实例时先复制再训练;提供外部重要性表时不训练模型。

'lgbm'
estimator_params dict | None

按模型名称创建实例时使用的参数,默认空字典;传入模型实例时不应用。

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

重要性计算方式。默认 "importance" 读取模型重要性或绝对系数; "shap" 训练模型后对最多前 300 行计算平均绝对 SHAP 值。

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

默认 "top_k" 按重要性保留前 K 个;"threshold" 保留重要性 大于等于阈值的特征;"percentile" 保留排名靠前的指定比例。

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

top_k 时为保留数量,默认 50;threshold 时为重要性下限; percentile 时为保留比例,支持 0~1 的比例、1 以上的百分数或 "50%"。 比例会限制在 0~1 内,保留数量向上取整。

50
cv int

保留的交叉验证配置,默认为 3;当前实现仅保存该值,不执行交叉验证。

3
n_jobs int

按名称创建且支持 n_jobs 的模型所用任务数,默认为 -1; 显式 estimator_params 中的配置优先。

-1
random_state int

随机种子。

42

引发:

类型 描述
ValueError

method 或 selection_mode 不受支持时抛出。

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

模型训练标签,按位置与 X 对应。提供 importance_table 时可省略。

None
features Sequence[str] | None

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

None
importance_table DataFrame | DataFrame | None

预先计算的重要性表,至少包含 feature 和 importance 列。 提供后直接排序和筛选,不训练模型;候选范围外的特征会被忽略。

None

返回:

类型 描述
MarsImportanceSelector

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

引发:

类型 描述
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(
...     df[["age"]],
...     importance_table=importance,
... )
>>> selector.selected_features_
['age']

fit_transform

fit_transform(
    X: DataFrame | DataFrame,
    y: Any | None = None,
    *,
    features: Sequence[str] | None = None,
    importance_table: DataFrame | DataFrame | None = None
) -> Union[pl.DataFrame, pd.DataFrame]

使用与 :meth:fit 相同的参数拟合,并转换当前特征表。