分箱 hscredit.core.binning

提供 17 种分箱算法与二维交互分箱,全部继承统一基类 BaseBinning,并由工厂类 OptimalBinning 作为统一入口。所有分箱指标统一通过 core.metrics 计算。

类别变量分箱

类别变量会先转换为有序编码,再交给所选 method 的原生数值分箱算法决定边界。 因此等宽、等频、树、卡方、KS、IV、MDLP 等方法仍分别使用自己的切分和合并标准, 不会在 OptimalBinning 中被替换为同一种类别合并结果。

默认顺序按训练集坏样本率升序生成;坏样本率相同的类别保持首次出现顺序。也可以通过 category_order 为指定字段提供完整顺序。下面使用 hscredit_hsk.xlsx工资 字段主动指定顺序:

import pandas as pd
from hscredit.core.binning import OptimalBinning

df = pd.read_excel("examples/hscredit_hsk.xlsx")
X = df.drop(columns="target")
y = df["target"]
wage_order = X["工资"].dropna().drop_duplicates().tolist()

binner = OptimalBinning(
    method="best_iv",
    max_n_bins=5,
    cat_cutoff=10,
    category_order={"工资": wage_order},
).fit(X, y)

assert binner._category_orders_["工资"] == wage_order

category_order 也可传入 callable(feature, x, y)。函数应返回当前字段的完整非缺失 类别序列;缺少类别、重复类别或包含训练集以外的类别都会抛出中文 ValueError。 数值编码的状态字段不会默认当作类别变量,需要通过 cat_cutoff 显式启用。例如 cat_cutoff=10 表示唯一值数量不超过 10 的数值字段按类别处理。

自定义类别分箱

自定义类别分箱使用 List[List],必须完整覆盖训练类别,且类别和缺失标记不能重复。 缺失值既可以单独成箱,也可以与普通类别放在同一箱:

import numpy as np

missing_alone = {
    "工资": [wage_order[:4], wage_order[4:8], wage_order[8:], [np.nan]],
}
missing_mixed = {
    "工资": [wage_order[:4], wage_order[4:8], [*wage_order[8:], np.nan]],
}

strict = OptimalBinning(
    user_splits=missing_alone,
    user_splits_fixed=True,
).fit(X[["工资"]], y)

mixed = OptimalBinning(
    user_splits=missing_mixed,
    user_splits_fixed=True,
    missing_separate=False,
).fit(X[["工资"]], y)

user_splits_fixed=True 会完整保留用户分组;非严格模式把每个用户组视为不可拆分的 原子单位,再用当前 method 决定是否合并相邻组。未知预测期类别默认转换为索引 -3、 标签 unknown 和中性 WOE 0.0handle_unknown='value' 与默认 -3 等价; handle_unknown='raise' 会在 transform 遇到训练期未知类别时直接报错;也可指定任意已记录的整数箱号。

max_n_binsmin_bin_sizemax_bin_sizemin_bad_rate 和明确的单调方向同样 适用于类别路径。如果单个类别或用户原子组本身已使约束不可满足,分箱器会指出字段、参数和 实际值,而不是静默忽略限制。

分箱算法模块 - 统一接口整合所有分箱方法.

提供多种分箱算法的统一接口,所有方法都可以通过 OptimalBinning 访问:

基础方法: - uniform: 等宽分箱 - quantile: 等频分箱 - tree: 决策树分箱 - chi: 卡方分箱

优化方法: - best_ks: 最优KS分箱 - best_iv: 最优IV分箱 - mdlp: MDLP分箱(基于信息论,默认)

运筹规划方法: - or_tools: OR-Tools 启发式+DP 最优化分箱 - cp_sat: CP-SAT 约束规划分箱(全局最优解)

高级方法: - cart: CART分箱(参考optbinning实现) - monotonic: 单调性约束分箱(支持U型/倒U型/凸/凹) - genetic: 遗传算法分箱 - smooth: 平滑/正则化分箱 - kernel_density: 核密度分箱 - best_lift: Best Lift分箱 - target_bad_rate: 目标坏样本率分箱

主要类

  • BaseBinning: 分箱算法基类

  • OptimalBinning: 统一分箱接口(推荐)

  • 各具体分箱类: UniformBinning, QuantileBinning, TreeBinning, CartBinning, ChiMergeBinning, BestKSBinning, BestIVBinning, MDLPBinning, ORBinning, CPSATBinning, CustomObjectives, KMeansBinning, MonotonicBinning, GeneticBinning, SmoothBinning, KernelDensityBinning, BestLiftBinning, TargetBadRateBinning

快速开始

>>> from hscredit.core.binning import OptimalBinning
>>> # 使用MDLP分箱(默认)
>>> binner = OptimalBinning(method='mdlp', max_n_bins=5)
>>>
>>> # 使用最优IV分箱
>>> binner = OptimalBinning(method='best_iv', max_n_bins=5)
>>> binner.fit(X_train, y_train)
>>> X_binned = binner.transform(X_test)
>>> bin_table = binner.get_bin_table('feature_name')
>>> # 使用单调性约束(支持U型/倒U型)
>>> binner = OptimalBinning(method='monotonic', monotonic='peak')
>>> binner.fit(X, y)
>>> # 指定切分点
>>> binner = OptimalBinning(user_splits={'age': [25, 35, 45]})
>>> binner.fit(X, y)
>>> # 自动选择最优方法
>>> best_method = OptimalBinning.auto_select_method(X, y, 'feature')
>>> binner = OptimalBinning(method=best_method)
>>> binner.fit(X, y)
class hscredit.core.binning.BaseBinning(target='target', missing_separate=True, min_n_bins=2, max_n_bins=5, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=False, special_codes=None, cat_cutoff=None, user_splits=None, user_splits_fixed=None, category_order=None, handle_unknown=-3, random_state=None, n_jobs=-1, verbose=False, decimal=4, woe_clip=None, parallel_backend=None, parallel_config=None)[源代码]

基类:ParallelizableMixin, ArtifactSerializableMixin, BaseEstimator, TransformerMixin, ABC

分箱算法基类.

所有分箱算法都继承此类,实现统一的fit/transform接口。 支持16种分箱方法,适用于风控评分卡开发场景。

参数

参数:
  • target (str) -- 目标变量列名,默认为'target'。在scorecardpipeline风格中使用, 当fit时只传入df且y为None时,从df中提取该列作为目标变量。

  • missing_separate (bool) -- 是否将缺失值单独分为一箱,默认为True

  • min_n_bins (int) -- 最小分箱数,默认为2

  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01 - 如果 < 1, 表示占比 (如 0.01 表示 1%) - 如果 >= 1, 表示绝对数量 (如 100 表示最少100个样本)

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,用于避免极端情况,默认为0.0

  • monotonic (bool | str) -- 坏样本率单调性约束,默认为False - False: 不要求单调性 - True 或 'auto': 自动检测最佳趋势(允许单增、单减、正U、倒U) - 'auto_asc_desc': 自动检测,但只允许单增或单减(不允许U型) - 'auto_heuristic': 使用启发式方法自动确定单调方向 - 'ascending': 强制坏样本率递增(分箱索引增大时坏样本率增大) - 'descending': 强制坏样本率递减(分箱索引增大时坏样本率减小) - 'peak': 倒U型/峰值(先增后降) - 'valley': U型/谷值(先降后增) - 'peak_heuristic': 使用启发式方法检测峰值 - 'valley_heuristic': 使用启发式方法检测谷值

  • special_codes (List | None) -- 特殊值列表,这些值会被单独分箱,例如[-99, -98, 'missing']

  • cat_cutoff (int | float | None) -- 类别型变量处理阈值,默认为None - 如果 < 1, 表示保留占比超过该值的类别 - 如果 >= 1, 表示保留频率最高的N个类别

  • user_splits (Dict[str, List] | Callable | None) -- 用户自定义分箱规则,例如{'feature': [0, 10, 20, 30]}

  • user_splits_fixed (bool | Mapping[str, bool | Sequence[bool]] | None) -- 用户切分点固定配置,可按字段或节点选择性固定

  • random_state (int | None) -- 随机种子,用于可复现性,默认为None

  • n_jobs (int | float | None) -- 并行工作数,默认为-1;None沿用旧串行行为

  • parallel_backend (str | None) -- joblib并行后端,默认为None

  • parallel_config (Mapping[str, Any] | None) -- joblib扩展配置,默认为None

  • verbose (bool | int) -- 是否输出详细信息,默认为False

  • decimal (int) -- 数值型切分点小数点保留精度,默认为4

  • woe_clip (float | None) -- WOE值截断阈值,默认为None 当某个分箱无坏样本或无好样本时,WOE可能变得极大(如±10以上), 这会导致评分卡中对应分箱的分数异常。 设置此参数可将WOE限制在[-woe_clip, woe_clip]范围内。 例如 woe_clip=5.0 可将WOE限制在[-5, 5]之间。

  • category_order (Dict[str, Sequence[Any]] | Callable[[str, Series, Series], Sequence[Any]] | None)

  • handle_unknown (int | Literal['value', 'raise'])

属性

  • splits_: 每个特征的分箱切分点,数值型特征为numpy数组,类别型特征为列表

  • n_bins_: 每个特征的实际分箱数

  • bin_tables_: 每个特征的分箱统计表,包含中文列名:
    • 分箱: 分箱索引

    • 分箱标签: 分箱区间标签

    • 样本总数: 样本数

    • 样本占比: 样本占比

    • 好样本数: 好样本数

    • 坏样本数: 坏样本数

    • 坏样本率: 坏样本率

    • 分档WOE值: WOE值

    • 分档IV值: IV值

    • 指标IV值: 总IV值

    • LIFT值: Lift值

    • 坏账改善: 坏账改善

    • 累积LIFT值: 累积Lift值

    • 累积坏账改善: 累积坏账改善

    • 累积好样本数: 累积好样本数

    • 累积坏样本数: 累积坏样本数

    • 分档KS值: KS值

  • feature_types_: 每个特征的类型 ('numerical' 或 'categorical')

支持的分箱方法

方法

类名

说明

uniform

UniformBinning

等宽分箱,将数值范围等分

quantile

QuantileBinning

等频分箱,每箱样本数相等

tree

TreeBinning

决策树分箱,基于信息增益

chi

ChiMergeBinning

卡方分箱,基于卡方统计量合并

best_ks

BestKSBinning

最优KS分箱,最大化KS统计量

best_iv

BestIVBinning

最优IV分箱,最大化IV值(推荐)

mdlp

MDLPBinning

MDLP分箱,信息论方法

or_tools

ORBinning

运筹规划分箱(基于Google OR-Tools)

cart

CartBinning

CART分箱,参考optbinning实现

monotonic

MonotonicBinning

单调性约束分箱,支持U型/倒U型

genetic

GeneticBinning

遗传算法分箱,全局优化

smooth

SmoothBinning

平滑分箱,正则化方法

kernel_density

KernelDensityBinning

核密度分箱,密度估计

best_lift

BestLiftBinning

Best Lift分箱,提升度优化

target_bad_rate

TargetBadRateBinning

目标坏样本率分箱

kmeans

KMeansBinning

K-Means聚类分箱

optimal

OptimalBinning

统一接口,支持上述所有方法

参考样例

基本使用 (sklearn风格):

>>> from hscredit.core.binning import OptimalBinning
>>> binner = OptimalBinning(method='best_iv', max_n_bins=5)
>>> binner.fit(X, y)
>>> X_binned = binner.transform(X)
>>> bin_table = binner.get_bin_table('feature_name')

scorecardpipeline风格 (目标列在DataFrame中):

>>> from hscredit.core.binning import OptimalBinning
>>> # 初始化时指定目标列名,fit时传入完整DataFrame
>>> binner = OptimalBinning(target='target', method='best_iv', max_n_bins=5)
>>> binner.fit(df)
>>> X_binned = binner.transform(df.drop(columns=['target']))
>>> bin_table = binner.get_bin_table('feature_name')

混合风格 (y参数优先):

>>> # 即使初始化时指定了target,fit时传入y会优先使用y
>>> binner = OptimalBinning(target='target', method='best_iv')
>>> binner.fit(df, y=external_y)

设置切分点精度:

>>> # 默认4位小数
>>> binner = OptimalBinning(method='best_iv', decimal=4)
>>> # 设置为2位小数
>>> binner = OptimalBinning(method='best_iv', decimal=2)

单调性约束:

>>> binner = OptimalBinning(method='best_iv', monotonic='descending')
>>> binner.fit(X, y)

使用独立分箱类:

>>> from hscredit.core.binning import ChiMergeBinning, BestIVBinning
>>> chi_binner = ChiMergeBinning(max_n_bins=5)
>>> chi_binner.fit(X, y)

注意

分箱算法的一般流程: 1. fit(): 训练分箱模型

  • 数据预处理 (缺失值处理、特殊值处理)

  • 检测特征类型 (数值型/类别型)

  • 计算最优分箱切分点

  • 对数值型切分点进行四舍五入(精度由decimal参数控制)

  • 生成分箱统计表

  1. transform(): 应用分箱 - 根据切分点对数据进行分箱 - 支持多种输出格式: 'indices'(分箱索引), 'labels'(分箱标签),

    'woe'(WOE值), 'bin_code'(分箱编码)

artifact_kind = '分箱器'
export(to_json=None)[源代码]

导出 hscredit 严格分箱规则.

数值型变量返回切分点列表,类别型变量返回分组列表。 同时导出WOE映射信息,支持加载后直接进行WOE转换。

参数:

to_json (str | None) -- 可选,JSON 文件保存路径。如果提供,将规则保存到该文件

返回:

分箱规则字典 - 数值型: {'age': [25, 35, 45, 55]} - 类别型: {'city': [['北京', '上海'], ['广州', '深圳'], [np.nan]]} - WOE映射: {'_woe_maps_': {'age': {0: 0.5, 1: -0.3, ...}}}

返回类型:

Dict[str, List | List[List]]

参考样例

>>> binner = OptimalBinning()
>>> binner.fit(X, y)
>>>
>>> # 导出为字典
>>> rules = binner.export()
>>>
>>> # 导出并保存到 JSON 文件
>>> rules = binner.export(to_json='binning_rules.json')

WOE转换支持

导出的规则包含WOE映射信息,加载后可直接进行WOE转换:

>>> binner = OptimalBinning()
>>> binner.load('binning_rules.json')
>>> X_woe = binner.transform(X_test, metric='woe')  # 直接使用,无需重新fit
export_rules()[源代码]

导出分箱规则.

数值型变量返回切分点列表,类别型变量返回分组列表。

返回:

分箱规则字典 - 数值型: key为特征名,value为切分点列表,如 [25, 35, 45, 55] - 类别型: key为特征名,value为分组列表,如 [['A', 'B'], ['C'], [np.nan]]

返回类型:

Dict[str, List | List[List]]

参考样例

>>> binner = OptimalBinning()
>>> binner.fit(X, y)
>>> rules = binner.export_rules()
>>>
>>> # 数值型变量
>>> print(rules['age'])  # [25, 35, 45, 55]
>>>
>>> # 类别型变量
>>> print(rules['city'])  # [['北京', '上海'], ['广州', '深圳'], [np.nan]]
>>>
>>> # 保存规则
>>> import json
>>> import numpy as np
>>>
>>> # 处理np.nan以便JSON序列化
>>> def convert_nan(obj):
...     if isinstance(obj, dict):
...         return {k: convert_nan(v) for k, v in obj.items()}
...     elif isinstance(obj, list):
...         return [convert_nan(item) for item in obj]
...     elif isinstance(obj, float) and np.isnan(obj):
...         return "NaN"
...     return obj
>>>
>>> with open('binning_rules.json', 'w') as f:
...     json.dump(convert_nan(rules), f, indent=2)
abstractmethod fit(X, y=None, **kwargs)[源代码]

拟合分箱。

支持两种API风格: 1. sklearn风格: fit(X, y) - X是特征矩阵,y是目标变量 2. scorecardpipeline风格: fit(df) - df是完整数据框,目标列名在初始化时通过target参数传入

优先级规则:如果y不是None,直接使用y(优先);否则从X中提取target列。

参数:
  • X (DataFrame | ndarray) -- 训练数据 - sklearn风格: 特征矩阵,shape (n_samples, n_features),可以是数值型或类别型特征 - scorecardpipeline风格: 完整数据框,包含特征列和目标列 - 支持DataFrame或numpy数组

  • y (ndarray | Series | None) -- 目标变量(可选) - sklearn风格: 传入目标变量,必须是二分类 (0/1 或 False/True) - scorecardpipeline风格: 不传,从X中提取 - 如果传入y,优先使用y而忽略X中的target列

  • kwargs -- 其他参数,传递给具体的分箱算法

返回:

拟合后的分箱器

返回类型:

BaseBinning

注意

fit方法会进行以下操作: 1. 数据验证和预处理(通过_check_input方法) 2. 识别特征类型 (数值型/类别型) 3. 处理缺失值和特殊值 4. 计算最优分箱切分点 5. 生成分箱统计表

使用示例

sklearn风格:

>>> X = pd.DataFrame({'age': [25, 30, 35], 'income': [5000, 6000, 7000]})
>>> y = pd.Series([0, 1, 0])
>>> binner.fit(X, y)

scorecardpipeline风格:

>>> df = pd.DataFrame({
...     'age': [25, 30, 35],
...     'income': [5000, 6000, 7000],
...     'target': [0, 1, 0]
... })
>>> binner = OptimalBinning(target='target')
>>> binner.fit(df)  # 自动从df中提取'target'列

混合风格(y参数优先):

>>> binner = OptimalBinning(target='target')
>>> binner.fit(df, y=external_y)
fit_transform(X, y=None, metric='indices', **kwargs)[源代码]

拟合并应用分箱。

支持两种API风格: 1. sklearn风格: fit_transform(X, y) - X是特征矩阵,y是目标变量 2. scorecardpipeline风格: fit_transform(df) - df是完整数据框,目标列名在初始化时通过target参数传入

参数:
  • X (DataFrame | ndarray) -- 训练数据 - sklearn风格: 特征矩阵,shape (n_samples, n_features) - scorecardpipeline风格: 完整数据框,包含特征列和目标列

  • y (ndarray | Series | None) -- 目标变量(可选) - sklearn风格: 传入目标变量 - scorecardpipeline风格: 不传,从X中提取

  • metric (str) -- 返回值的类型,默认为'indices' - 'indices': 返回分箱索引 - 'bins': 返回分箱标签 - 'woe': 返回WOE值

返回:

分箱后的数据

返回类型:

DataFrame | ndarray

使用示例

sklearn风格:

>>> X_binned = binner.fit_transform(X, y, metric='woe')

scorecardpipeline风格:

>>> binner = OptimalBinning(target='target')
>>> X_binned = binner.fit_transform(df, metric='woe')
get_bin_table(feature)[源代码]

获取指定特征的分箱表.

参数:

feature (str) -- 特征名

返回:

分箱统计表(返回副本,修改不会影响分箱器内部数据)

抛出:
返回类型:

DataFrame

get_splits(feature)[源代码]

获取指定特征的切分点(scorecardpipeline 格式).

数值型特征:np.nan 的位置表示缺失值归属的普通箱。 类别型特征:返回 List[List] 分组列表。

参数:

feature (str) -- 特征名

返回:

切分点列表

返回类型:

ndarray | list

import_rules(rules)[源代码]

导入分箱规则.

支持数值型切分点和类别型分组列表。

参数:

rules (Dict[str, List | List[List]]) -- 分箱规则字典 - 数值型: {'age': [25, 35, 45, 55]} - 类别型: {'city': [['北京', '上海'], ['广州', '深圳'], [np.nan]]}

调用本方法时沿用增量覆盖语义,导入后可立即 transform。随后调用 fit 时, 仅把最近一次导入规则中同时属于本轮 X 的特征作为候选输入;普通分箱器仍 重新运行其算法,OptimalBinning 则保留这些导入切点并补充分箱统计。

参考样例

>>> # 导入数值型规则
>>> rules = {'age': [25, 35, 45, 55]}
>>> binner.import_rules(rules)
>>>
>>> # 导入类别型规则
>>> rules = {'city': [['北京', '上海'], ['广州', '深圳'], [np.nan]]}
>>> binner.import_rules(rules)
>>>
>>> # 从JSON文件导入
>>> import json
>>> import numpy as np
>>>
>>> def convert_nan_back(obj):
...     if isinstance(obj, dict):
...         return {k: convert_nan_back(v) for k, v in obj.items()}
...     elif isinstance(obj, list):
...         return [convert_nan_back(item) for item in obj]
...     elif obj == "NaN":
...         return np.nan
...     return obj
>>>
>>> with open('binning_rules.json', 'r') as f:
...     rules = json.load(f)
>>>     rules = convert_nan_back(rules)
>>> binner.import_rules(rules)
load(from_json, update=False)[源代码]

加载 hscredit 严格分箱规则.

从字典或 JSON 文件加载数值规则或严格 List[List] 类别规则。 同时加载WOE映射信息,支持加载后直接进行WOE转换。

参数:
  • from_json (str | Dict) -- 分箱规则字典或 JSON 文件路径 - 字典: {'age': [25, 35, 45, 55]} - 文件路径: 'binning_rules.json'

  • update (bool) -- 是否更新现有规则(而非替换),默认为 False

返回:

self,支持链式调用

返回类型:

BaseBinning

参考样例

>>> binner = OptimalBinning()
>>>
>>> # 从字典加载
>>> rules = {'age': [25, 35, 45, 55], 'gender': [['M'], ['F']]}
>>> binner.load(rules)
>>>
>>> # 从 JSON 文件加载
>>> binner.load('binning_rules.json')
>>>
>>> # 更新现有规则
>>> binner.load({'new_feature': [1, 2, 3]}, update=True)

WOE转换支持

加载包含WOE映射信息的规则后,可直接进行WOE转换:

>>> binner.load('binning_rules.json')
>>> X_woe = binner.transform(X_test, metric='woe')  # 直接使用,无需重新fit
plot(feature, save=None, **kwargs)[源代码]

绘制分箱图.

参数:
  • feature (str) -- 特征名

  • save (str | None) -- 图片保存路径,默认为None

  • kwargs -- 其他绘图参数

注意

绘制内容包括: 1. 各分箱的样本数分布 2. 各分箱的坏样本率 3. 各分箱的WOE值

返回:

matplotlib Figure 对象

参数:
  • feature (str)

  • save (str | None)

set_params(**params)[源代码]

设置 sklearn 参数,并立即规范化未知类别策略。

返回类型:

BaseBinning

abstractmethod transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。 这是分箱器的核心方法,用于将新数据应用到已训练的分箱规则。

参数:
  • X (DataFrame | ndarray) -- 待转换的数据,shape (n_samples, n_features) - 支持DataFrame或numpy数组 - 列名必须与fit时的特征名一致

  • metric (str) --

    转换类型,默认为'indices' - 'indices': 返回分箱索引 (0, 1, 2, ...)

    • 用途: 后续处理、特征工程

    • 示例: [0, 1, 2, 0, 1, ...]

    • 'bins': 返回分箱标签字符串
      • 用途: 可视化、报告展示

      • 示例: ['(-inf, 25]', '(25, 35]', '(35, 45]', ...]

      • 类别型: ['北京,上海', '广州,深圳', ...]

    • 'woe': 返回WOE值
      • 用途: 逻辑回归建模

      • 示例: [0.234, -0.456, 0.123, ...]

  • kwargs -- 其他参数

返回:

转换后的数据,返回类型与输入类型一致

返回类型:

DataFrame | ndarray

重要说明

  1. metric参数是枚举值,只能使用以下3个值之一: - 'indices' (不是'分箱'、'索引'等中文) - 'bins' (不是'分箱标签'等中文) - 'woe' (不是'分档WOE值'等中文)

  2. 中文列名出现在分箱结果表中: - 使用 binner.get_bin_table(feature) 查看 - 列名: '分箱', '样本总数', '坏样本率', '分档WOE值'等

参考样例

>>> binner = OptimalBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>> print(X_binned.head())
>>>
>>> # 获取分箱标签
>>> X_labels = binner.transform(X_test, metric='bins')
>>> print(X_labels.head())
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
>>> print(X_woe.head())
>>>
>>> # 错误示例 - 不要使用中文
>>> # X_error = binner.transform(X_test, metric='分档WOE值')  # ❌ ValueError!

处理特殊值

transform方法会自动处理: 1. 缺失值: 如果missing_separate=True,分配到专门的缺失箱 (索引=-1) 2. 特殊值: 如果指定了special_codes,分配到专门的特殊值箱 (索引=-2) 3. 超出范围的值: 分配到最近的分箱

update(splits_dict, X=None, y=None)[源代码]

手动更新特征的切分点并重新计算相关属性.

参考 toad.Combiner.update 方法,允许在分箱器训练完成后手工修改切分点。 更新后会自动重新计算 n_bins_feature_types_、_cat_bins_ 等属性。 如果提供 X 和 y,还会重新计算 bin_tables_ 分箱统计表。

参数

参数:
  • splits_dict (Dict[str, List | List[List]]) -- 新的切分点字典,格式与 export_rules() 返回的相同 - 数值型: {'age': [25, 35, 45, 55]} - 类别型: {'city': [['北京', '上海'], ['广州', '深圳'], [np.nan]]}

  • X (DataFrame | ndarray | None) -- 可选,训练数据。如果提供,会重新计算分箱统计表

  • y (ndarray | Series | None) -- 可选,目标变量

返回类型:

BaseBinning

返回

返回:

self,支持链式调用

参数:
  • splits_dict (Dict[str, List | List[List]])

  • X (DataFrame | ndarray | None)

  • y (ndarray | Series | None)

返回类型:

BaseBinning

参考样例

>>> # 只更新切分点(不重新计算统计表)
>>> binner.update({'age': [20, 30, 40, 50]})
>>> # 更新切分点并重新计算统计表
>>> binner.update({'age': [20, 30, 40, 50]}, X=X_train, y=y_train)
>>> # 批量更新多个特征
>>> binner.update({
...     'age': [20, 30, 40],
...     'income': [5000, 10000, 20000],
...     'city': [['北京', '上海'], ['广州', '深圳']]
... })
>>> # 链式调用
>>> binner.update({'age': [20, 30, 40]}).transform(X_test)
class hscredit.core.binning.UniformBinning(max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=False, missing_separate=True, special_codes=None, cat_cutoff=None, category_order=None, handle_unknown=-3, left_clip=None, right_clip=None, force_numerical=False, random_state=None, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None, **kwargs)[源代码]

基类:BaseBinning

等距分箱.

将特征值的范围等分为指定数量的区间,每个区间宽度相同。 适用于数据分布相对均匀的场景。

参数:
  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本占比,默认为0.01

  • max_bin_size (int | float | None) -- 每箱最大样本占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0

  • monotonic (bool | str) -- 是否要求单调性,默认为False

  • missing_separate (bool) -- 缺失值是否单独分箱,默认为True

  • special_codes (List | None) -- 特殊值列表,默认为None,如[-999, -98]

  • left_clip (float | None) -- 左侧截断分位数,默认为None,如0.01表示截断1%分位数以下的值

  • right_clip (float | None) -- 右侧截断分位数,默认为None,如0.99表示截断99%分位数以上的值

  • force_numerical (bool) -- 是否强制作为数值型处理,默认为False(自动识别类别型) - True: 将所有特征视为数值型进行等距分箱(默认,因为等距分箱适用于数值型) - False: 自动检测特征类型(根据dtype判断)

  • random_state (int | None) -- 随机种子,默认为None

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | Sequence[bool]] | None)

参考样例

>>> from hscredit.core.binning import UniformBinning
>>> # 基础用法
>>> binner = UniformBinning(max_n_bins=5)
>>> binner.fit(X_train, y_train)
>>> X_binned = binner.transform(X_test)
>>>
>>> # 使用截断处理异常值
>>> binner = UniformBinning(max_n_bins=5, left_clip=0.01, right_clip=0.99)
>>> binner.fit(X_train, y_train)
>>>
>>> # 指定特殊值
>>> binner = UniformBinning(max_n_bins=5, special_codes=[-999, -98])
>>> binner.fit(X_train, y_train)

注意

等距分箱的特点: 1. 每个分箱的区间宽度相同 2. 分箱边界由 (max - min) / n_bins 计算得出 3. 支持通过left_clip/right_clip截断异常值 4. 支持通过special_codes处理特殊值(如-999表示缺失) 5. 默认force_numerical=False,自动识别类别型;如需强制数值等距分箱可显式设为 True 6. 计算速度快,实现简单;为无监督方法,不使用标签 y 决定切分 7. 对偏态分布或含极端值的特征不友好(可能某些箱样本极少),此时优先用等频分箱

引用

等距(equal-width)离散化综述见 Dougherty, J., Kohavi, R., & Sahami, M. (1995). Supervised and Unsupervised Discretization of Continuous Features. ICML-95. https://ai.stanford.edu/~ronnyk/disc.pdf

fit(X, y=None, **kwargs)[源代码]

拟合等距分箱.

参数:
  • X (DataFrame | ndarray) -- 训练数据

  • y (ndarray | Series | None) -- 目标变量

返回:

拟合后的分箱器

返回类型:

UniformBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = UniformBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.QuantileBinning(target='target', min_n_bins=2, max_n_bins=10, quantiles=None, force_numerical=False, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=False, special_codes=None, missing_separate=True, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, verbose=False, decimal=4, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None)[源代码]

基类:BaseBinning

等频分箱算法.

将特征值按照分位数切分成多个区间,确保每个区间的样本数大致相等。 适用于数据分布不均匀或存在异常值的场景。

参数:
  • min_n_bins (int) -- 最小分箱数,默认为2

  • max_n_bins (int) -- 最大分箱数,默认为10

  • quantiles (List[float] | None) --

    自定义分位点列表,如[0, 0.2, 0.5, 0.8, 1.0],默认为None - 如果提供,将直接使用这些分位点进行分箱 - 首尾的 0 与 1 支持自动补齐:可传入完整的 [0, ..., 1],

    也可只传中间分位点(如 [0.2, 0.5, 0.8]),缺失的 0 / 1 会自动补齐

  • force_numerical (bool) -- 是否强制作为数值型处理,默认为False(自动识别类别型) - True: 将所有特征视为数值型进行等频分箱 - False: 自动检测特征类型

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0

  • monotonic (bool | str) -- 是否要求坏样本率单调,默认为False

  • special_codes (List | None) -- 特殊值列表,默认为None

  • missing_separate (bool) -- 是否将缺失值单独分为一箱,默认为True

  • random_state (int | None) -- 随机种子,默认为None

  • verbose (bool | int) -- 是否输出详细信息,默认为False

  • target (str)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • decimal (int)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

属性

  • splits_: 每个特征的分箱切分点

  • n_bins_: 每个特征的实际分箱数

  • bin_tables_: 每个特征的分箱统计表

参考样例

>>> from hscredit.core.binning import QuantileBinning
>>> # 基础用法
>>> binner = QuantileBinning(max_n_bins=5)
>>> binner.fit(X, y)
>>> X_binned = binner.transform(X)
>>>
>>> # 使用自定义分位点
>>> binner = QuantileBinning(quantiles=[0, 0.1, 0.3, 0.7, 0.9, 1.0])
>>> binner.fit(X, y)

注意

等频分箱为无监督方法,仅依据特征自身分布切分、不使用标签 y``(``y 仅用于 生成分箱统计表),因此对异常值稳健、各箱样本量均衡,常用作有监督分箱的预分箱。

引用

等频(equal-frequency)离散化综述见 Dougherty, J., Kohavi, R., & Sahami, M. (1995). Supervised and Unsupervised Discretization of Continuous Features. ICML-95. https://ai.stanford.edu/~ronnyk/disc.pdf

fit(X, y=None, **kwargs)[源代码]

拟合等频分箱.

参数:
  • X (DataFrame | ndarray) -- 训练数据,shape (n_samples, n_features)

  • y (ndarray | Series | None) -- 目标变量,二分类 (0/1)

  • kwargs -- 其他参数

返回:

拟合后的分箱器

返回类型:

QuantileBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = QuantileBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.TreeBinning(target='target', max_depth=5, max_leaf_nodes=None, min_samples_leaf=0.05, min_n_bins=2, max_n_bins=10, force_numerical=False, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=False, special_codes=None, missing_separate=True, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, verbose=False, decimal=4, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None)[源代码]

基类:BaseBinning

决策树分箱算法.

以 sklearn DecisionTreeClassifier 对单特征拟合一棵决策树, 取其内部节点的分裂阈值作为切分点。分裂以基尼系数 / 信息增益最大化为准则,因而切分 天然贴合目标变量。支持最大深度、叶子节点数与单调性约束。

参数:
  • max_depth (int) -- 决策树最大深度,默认为5(越大切分越细)

  • max_leaf_nodes (int | None) -- 最大叶子节点数(约等于最大分箱数上限),默认为None

  • min_samples_leaf (float | int) -- 叶子节点最小样本数(<1 为占比,>=1 为绝对数),默认为0.05

  • min_n_bins (int) -- 最小分箱数,默认为2

  • max_n_bins (int) -- 最大分箱数,默认为10

  • force_numerical (bool) -- 是否强制作为数值型处理,默认为False

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0

  • monotonic (bool | str) -- 是否要求坏样本率单调,默认为False

  • special_codes (List | None) -- 特殊值列表,默认为None

  • missing_separate (bool) -- 是否将缺失值单独分为一箱,默认为True

  • random_state (int | None) -- 随机种子,默认为None

  • verbose (bool | int) -- 是否输出详细信息,默认为False

  • target (str)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • decimal (int)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

属性

  • splits_: 每个特征的分箱切分点

  • n_bins_: 每个特征的实际分箱数

  • bin_tables_: 每个特征的分箱统计表

  • tree_models_: 每个特征的决策树模型

参考样例

>>> from hscredit.core.binning import TreeBinning
>>> binner = TreeBinning(max_depth=5, monotonic=True)
>>> binner.fit(X, y)
>>> X_binned = binner.transform(X)

引用

决策树分裂准则参见 Breiman, L. et al. (1984). Classification and Regression Trees. Wadsworth;实现基于 sklearn https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html

fit(X, y=None, **kwargs)[源代码]

拟合决策树分箱.

参数:
  • X (DataFrame | ndarray) -- 训练数据,shape (n_samples, n_features)

  • y (ndarray | Series | None) -- 目标变量,二分类 (0/1)

  • kwargs -- 其他参数

返回:

拟合后的分箱器

返回类型:

TreeBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = TreeBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.CartBinning(target='target', max_n_bins=10, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, min_event_rate_diff=0.0, max_pvalue=None, max_pvalue_policy='consecutive', monotonic=False, class_weight=None, special_codes=None, missing_separate=True, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, verbose=False, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None, **kwargs)[源代码]

基类:BaseBinning

CART 分箱算法.

基于决策树的分箱方法,参考 optbinning 的 CART 预分箱实现。 使用 sklearn 的 DecisionTreeClassifier/Regressor 提取最优分割点。

参数:
  • max_n_bins (int) -- 最大分箱数,默认为10

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01 - 如果 < 1, 表示占比 (如 0.01 表示 1%) - 如果 >= 1, 表示绝对数量 (如 100 表示最少100个样本)

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None

  • min_event_rate_diff (float) -- 相邻箱最小坏样本率差异,默认为0 - 如果设置,会合并坏样本率差异过小的相邻箱

  • max_pvalue (float | None) -- 最大 p-value 阈值,默认为None - 如果设置,会进行统计检验,合并差异不显著的相邻箱

  • max_pvalue_policy (str) -- p-value 检验策略,默认为"consecutive" - "all": 检验所有箱对 - "consecutive": 只检验相邻箱

  • monotonic (bool | str) -- 是否要求单调性,默认为False - False: 不要求 - True 或 'auto': 自动判断单调方向 - 'ascending': 强制递增 - 'descending': 强制递减

  • class_weight (str | Dict | None) -- 类别权重,默认为None - None: 不调整 - "balanced": 自动根据类别频率调整 - dict: 自定义权重,如 {0: 1, 1: 2}

  • special_codes (List | None) -- 特殊值列表,默认为None

  • missing_separate (bool) -- 缺失值是否单独分箱,默认为True

  • random_state (int | None) -- 随机种子,默认为None

  • target (str)

  • min_bad_rate (float)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • verbose (bool)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

属性

  • splits_: 每个特征的分箱切分点

  • n_bins_: 每个特征的实际分箱数

  • bin_tables_: 每个特征的分箱统计表

  • tree_models_: 每个特征的决策树模型

参考样例

>>> from hscredit.core.binning import CartBinning
>>> binner = CartBinning(max_n_bins=5, monotonic=True)
>>> binner.fit(X_train, y_train)
>>> X_binned = binner.transform(X_test)
>>> bin_table = binner.get_bin_table('feature_name')

注意

CART 分箱的特点: 1. 基于决策树的信息增益选择切分点 2. 支持分类(二分类/多分类)和回归目标变量 3. 可设置类别权重处理不平衡数据 4. 支持 p-value 检验确保分箱统计显著性 5. 支持单调性约束

TreeBinning 的区别:CART 额外提供 p-value 显著性检验合并、相邻箱坏样本率 最小差异约束(min_event_rate_diff)及回归目标支持,预分箱流程对齐 optbinning。

引用

Breiman, L., Friedman, J., Olshen, R., & Stone, C. (1984). Classification and Regression Trees. Wadsworth;预分箱实现参考 optbinning https://gnpalencia.org/optbinning/

fit(X, y=None, **kwargs)[源代码]

拟合 CART 分箱.

参数:
  • X (DataFrame | ndarray) -- 训练数据,shape (n_samples, n_features)

  • y (ndarray | Series | None) -- 目标变量,可以是二分类、多分类或连续型

  • kwargs -- 其他参数

返回:

拟合后的分箱器

返回类型:

CartBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = CARTBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.ChiMergeBinning(target='target', max_n_bins=10, min_n_bins=2, min_chi2_threshold=None, significance_level=0.05, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=False, special_codes=None, missing_separate=True, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, verbose=False, decimal=4, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None)[源代码]

基类:BaseBinning

卡方分箱算法 (ChiMerge)。

一种自底向上(bottom-up)的有监督分箱方法。其核心假设是:若相邻两箱的好坏样本 分布无显著差异(卡方值小),则可以合并。算法流程:

  1. 初始化:将每个唯一值(或预分位点)各作为一个箱;

  2. 迭代合并:对所有相邻箱对计算 2×2 列联表的卡方统计量,合并卡方值最小的一对;

  3. 停止:当最小卡方值超过阈值 min_chi2_threshold,或箱数降至 max_n_binsmin_n_bins 限制时停止。

卡方值越大表示相邻两箱坏样本率差异越显著、越不应合并。继承 BaseBinning, 完整的分箱通用参数、属性与转换语义见基类。

参数(本算法特有及关键项)

参数:
  • target (str) -- 目标列名(scorecardpipeline 风格),默认为 'target'

  • max_n_bins (int) -- 最大分箱数,默认为 10

  • min_n_bins (int) -- 最小分箱数,默认为 2

  • min_chi2_threshold (float | None) -- 卡方合并阈值(停止合并的下限),默认为 None。 为 None 时取自由度 1、显著性水平 significance_level 的卡方临界值 (如 0.05 对应约 3.841)。当相邻箱的最小卡方值大于该阈值即停止合并

  • significance_level (float) -- 显著性水平,用于在 min_chi2_thresholdNone 时 换算卡方临界值,默认为 ``0.05``(值越小阈值越大、分箱越粗)

  • min_bin_size (float | int) -- 每箱最小样本数(>=1)或占比(<1),默认为 0.01

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为 None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为 0.0

  • monotonic (bool | str) -- 坏样本率单调性约束,取值见 BaseBinning,默认为 False

  • special_codes (List | None) -- 特殊值列表,单独成箱,默认为 None

  • missing_separate (bool) -- 是否将缺失值单独成箱,默认为 True

  • random_state (int | None) -- 随机种子,默认为 None

  • verbose (bool | int) -- 是否输出合并过程日志,默认为 False

  • decimal (int) -- 数值切分点保留小数位,默认为 4

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

属性

  • splits_: 每个特征的分箱切分点

  • n_bins_: 每个特征的实际分箱数

  • bin_tables_: 每个特征的分箱统计表(中文列名,见 BaseBinning

参考样例

>>> from hscredit.core.binning import ChiMergeBinning
>>> binner = ChiMergeBinning(max_n_bins=5, significance_level=0.05)
>>> binner.fit(X, y)                       # sklearn 风格
>>> X_woe = binner.transform(X, metric='woe')
>>> binner.get_bin_table('age')           # 查看某特征分箱明细

指定卡方阈值并要求坏样本率单调递减:

>>> binner = ChiMergeBinning(min_chi2_threshold=6.635, monotonic='descending')
>>> binner.fit(X, y)

引用

Kerber, R. (1992). ChiMerge: Discretization of Numeric Attributes. Proceedings of AAAI-92. https://www.aaai.org/Papers/AAAI/1992/AAAI92-019.pdf

fit(X, y=None, **kwargs)[源代码]

拟合卡方分箱。

对每个特征执行 ChiMerge 合并,得到切分点与分箱统计表。支持 sklearn 风格 fit(X, y) 与 scorecardpipeline 风格 fit(df)``(目标列由 ``target 指定), 详见 BaseBinning.fit()

参数:
  • X (DataFrame | ndarray) -- 训练数据,shape (n_samples, n_features);可为 DataFrame 或 ndarray

  • y (ndarray | Series | None) -- 目标变量,二分类(0=好/1=坏);scorecardpipeline 风格下可省略

  • kwargs -- 透传给基类的其他参数

返回:

拟合后的分箱器自身(便于链式调用)

返回类型:

ChiMergeBinning

参考样例

>>> ChiMergeBinning(max_n_bins=5).fit(X, y).transform(X, metric='woe')
transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = ChiMergeBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.BestKSBinning(target='target', max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=False, missing_separate=True, special_codes=None, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None, **kwargs)[源代码]

基类:BaseBinning

Best KS 分箱.

基于最大化KS统计量的分箱方法,寻找能够最大化区分能力的分箱点。 使用贪心算法逐步优化。

参数:
  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01 - 如果 < 1, 表示占比 (如 0.01 表示 1%) - 如果 >= 1, 表示绝对数量 (如 100 表示最少100个样本)

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0

  • monotonic (bool | str) -- 坏样本率单调性约束,默认为False - False: 不要求单调性 - True 或 'auto': 自动检测并应用最佳单调方向 - 'ascending': 强制坏样本率递增 - 'descending': 强制坏样本率递减

  • missing_separate (bool) -- 缺失值是否单独分箱,默认为True

  • special_codes (List | None) -- 特殊值列表,默认为None

  • random_state (int | None) -- 随机种子,默认为None

  • target (str)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

参考样例

>>> from hscredit.core.binning import BestKSBinning
>>> binner = BestKSBinning(max_n_bins=5)
>>> binner.fit(X_train, y_train)
>>> X_binned = binner.transform(X_test)
>>> bin_table = binner.get_bin_table('feature_name')

注意

Best KS 分箱的特点: 1. 以最大化 KS(Kolmogorov–Smirnov)统计量为目标选择切分点 2. KS = max |累计好样本占比 - 累计坏样本占比|,衡量好坏样本累积分布的最大差异 3. 使用贪心算法逐步优化,支持单调性约束 4. 相比等频/等距计算复杂度较高,但区分度更优

引用

Kolmogorov–Smirnov 检验:https://en.wikipedia.org/wiki/Kolmogorov–Smirnov_test ; KS 统计量在信用风险中的应用见 Siddiqi, N. (2006). Credit Risk Scorecards. Wiley.

fit(X, y=None, **kwargs)[源代码]

拟合 Best KS 分箱。

对每个特征预分割为细箱后,在单调性约束下贪心选择切分点以最大化 KS 统计量。 支持 sklearn 风格 fit(X, y) 与 scorecardpipeline 风格 fit(df), 详见 BaseBinning.fit()

参数:
  • X (DataFrame | ndarray) -- 训练数据,shape (n_samples, n_features),DataFrame 或 ndarray

  • y (ndarray | Series | None) -- 二分类目标变量(0=好/1=坏);scorecardpipeline 风格下可省略

  • kwargs -- 透传给基类的其他参数

返回:

拟合后的分箱器自身(便于链式调用)

返回类型:

BestKSBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = BestKSBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.BestIVBinning(target='target', max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=False, missing_separate=True, special_codes=None, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None, **kwargs)[源代码]

基类:BaseBinning

Best IV 分箱.

基于最大化IV的分箱方法,寻找能够最大化预测能力的分箱点。 IV是衡量特征预测能力的重要指标。

参数:
  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01 - 如果 < 1, 表示占比 (如 0.01 表示 1%) - 如果 >= 1, 表示绝对数量 (如 100 表示最少100个样本)

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0

  • monotonic (bool | str) -- 坏样本率单调性约束,默认为False - False: 不要求单调性 - True 或 'auto': 自动检测并应用最佳单调方向 - 'ascending': 强制坏样本率递增 - 'descending': 强制坏样本率递减

  • missing_separate (bool) -- 缺失值是否单独分箱,默认为True

  • special_codes (List | None) -- 特殊值列表,默认为None

  • random_state (int | None) -- 随机种子,默认为None

  • target (str)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

参考样例

>>> from hscredit.core.binning import BestIVBinning
>>> binner = BestIVBinning(max_n_bins=5)
>>> binner.fit(X_train, y_train)
>>> X_binned = binner.transform(X_test)
>>> bin_table = binner.get_bin_table('feature_name')

注意

Best IV 分箱的特点: 1. 以最大化 IV(Information Value,信息价值)为目标,逐步贪心优化切分点 2. IV < 0.02:几乎无预测能力 3. 0.02 ≤ IV < 0.1:弱预测能力 4. 0.1 ≤ IV < 0.3:中等预测能力 5. IV ≥ 0.3:强预测能力(过高时需警惕标签泄漏或过拟合)

其中 IV = Σ (好样本占比 - 坏样本占比) × WOEWOE = ln(箱内好样本占比 / 箱内坏样本占比)

引用

Information Value / WOE 经典出处:Siddiqi, N. (2006). Credit Risk Scorecards: Developing and Implementing Intelligent Credit Scoring. Wiley. IV 阈值经验区间参考业界通行标准(见 scorecard / toad / optbinning 文档)。

fit(X, y=None, **kwargs)[源代码]

拟合 Best IV 分箱。

对每个特征预分割为细箱后,在单调性约束下贪心合并以最大化 IV,得到切分点与分箱 统计表。支持 sklearn 风格 fit(X, y) 与 scorecardpipeline 风格 fit(df), 详见 BaseBinning.fit()

参数:
  • X (DataFrame | ndarray) -- 训练数据,shape (n_samples, n_features),DataFrame 或 ndarray

  • y (ndarray | Series | None) -- 二分类目标变量(0=好/1=坏);scorecardpipeline 风格下可省略

  • kwargs -- 透传给基类的其他参数

返回:

拟合后的分箱器自身(便于链式调用)

返回类型:

BestIVBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = BestIVBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.OptimalBinning(target='target', method='mdlp', max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=False, missing_separate=True, user_splits=None, user_splits_fixed=None, prebinning=None, prebinning_params=None, special_codes=None, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, verbose=False, decimal=4, woe_clip=None, n_jobs=-1, parallel_backend=None, parallel_config=None, **kwargs)[源代码]

基类:BaseBinning

统一分箱接口 - 整合所有分箱方法.

提供统一的 fit/transform 接口,支持所有分箱方法。 融合 MonotonicBinning 的单调性约束功能。 支持指定切割点 (user_splits) 和预分箱。

架构设计原则

  1. OptimalBinning 作为统一入口:集成所有分箱方法,支持预分箱功能

  2. 独立分箱模块保持简单:各个具体分箱类(如BestIVBinning、MDLPBinning等) 只执行一次分箱,不包含预分箱逻辑

  3. 预分箱在 OptimalBinning 层面实现:通过 prebinning 参数在统一接口层实现 预分箱+二次分箱的两阶段分箱流程

参数:
  • target (str) -- 目标变量列名,默认为'target'

  • method (str) --

    分箱方法,默认为 'mdlp'。可取以下枚举值(按类别):

    无监督(不使用标签决定切分)

    • 'uniform':等距分箱,按数值范围等宽切分,快但对偏态敏感

    • 'quantile':等频分箱,各箱样本量均衡,对异常值稳健,常作预分箱

    • 'kmeans':K-Means 聚类分箱,按数值聚类结构切分,适合自然分组

    • 'kernel_density':核密度分箱,以分布谷值为边界,适合多峰分布

    有监督(结合标签寻优)

    • 'tree':决策树分箱,取决策树分裂点,贴合目标

    • 'cart':CART 分箱(对齐 optbinning 预分箱),支持 p-value 检验/回归目标

    • 'chi':卡方分箱(ChiMerge),合并分布无显著差异的相邻箱

    • 'mdlp':MDLP 信息论分箱,自动确定分箱数(默认)

    • 'best_ks':最大化 KS 统计量

    • 'best_iv':最大化 IV(信息价值),评分卡常用

    • 'best_lift':最大化头部箱提升度 Lift,偏策略拒绝场景

    • 'target_bad_rate':按目标坏样本率梯度切分

    • 'monotonic':单调最优分箱,强约束坏样本率/WOE 单调(含 U/倒U)

    • 'genetic':遗传算法全局寻优,约束复杂时使用

    • 'smooth':平滑分箱,对箱内坏样本率做平滑收缩,适合小样本

    运筹规划(数学规划全局最优)

    • 'or_tools':基于 Google OR-Tools 的整数规划分箱

    • 'cp_sat':基于 CP-SAT 求解器的约束规划分箱

  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None(不限制)

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0。坏样本率低于该值的分箱将与相邻 分箱合并;无论该参数取值,坏样本率为 0/1 的退化分箱都会被合并以避免 WOE 异常 (等宽 uniform / 等频 quantile 为保持切分结构精确,不参与该约束)

  • monotonic (bool | str) -- 坏样本率单调性约束,默认为False - False: 不要求单调性 - True 或 'auto': 自动检测最佳趋势(允许单增、单减、正U、倒U) - 'auto_asc_desc': 自动检测,但只允许单增或单减(不允许U型) - 'auto_heuristic': 使用启发式方法自动检测 - 'ascending': 强制坏样本率递增 - 'descending': 强制坏样本率递减 - 'peak': 允许单峰形态(先升后降,倒U型) - 'valley': 允许单谷形态(先降后升,正U型) - 'peak_heuristic': 使用启发式方法检测峰值 - 'valley_heuristic': 使用启发式方法检测谷值

  • user_splits (Dict[str, List] | Callable | None) -- 用户指定的切分点,支持: - Dict[str, List]: 每个特征的切分点,如 {'age': [25, 35, 45]} - Callable: 函数返回切分点

  • user_splits_fixed (bool | Mapping[str, bool | Sequence[bool]] | None) -- 用户切分点固定配置。支持全局布尔值,或按字段配置布尔值/布尔列表

  • prebinning (str | BaseBinning | Dict | None) -- 预分箱方法,支持: - str: 预分箱方法名(所有VALID_METHODS中的方法都可作为预分箱方法) - BaseBinning: 预分箱器实例 - Dict: 预分箱配置,如 {'method': 'cart', 'max_n_bins': 20} 默认为None(不进行预分箱)

  • prebinning_params (Dict | None) -- 预分箱参数,当prebinning为str时使用

  • special_codes (List | None) -- 特殊值列表,默认为None

  • cat_cutoff (int | float | None) -- 类别型变量处理阈值,默认为None

  • random_state (int | None) -- 随机种子,默认为None

  • verbose (bool | int) -- 是否输出详细信息,默认为False

  • decimal (int) -- 数值型切分点保留的小数位数,默认为4

  • woe_clip (float | None) -- WOE值截断阈值,默认为None 当某个分箱无坏样本或无好样本时,WOE可能变得极大(如±10以上), 这会导致评分卡中对应分箱的分数异常。 设置此参数可将WOE限制在[-woe_clip, woe_clip]范围内。

  • kwargs -- 其他分箱方法特定参数

  • missing_separate (bool)

  • category_order (Dict[str, Sequence[Any]] | Callable[[str, Series, Series], Sequence[Any]] | None)

  • handle_unknown (int | Literal['value', 'raise'])

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

参考样例

>>> from hscredit.core.binning import OptimalBinning
>>> # 使用MDLP分箱(默认,直接分箱)
>>> binner = OptimalBinning(method='mdlp', max_n_bins=5)
>>> binner.fit(X, y)
>>> # 使用最优IV分箱(直接分箱)
>>> binner = OptimalBinning(method='best_iv', max_n_bins=5)
>>> binner.fit(X, y)
>>> # 使用CART分箱(直接分箱)
>>> binner = OptimalBinning(method='cart', max_n_bins=5)
>>> binner.fit(X, y)
>>> # 使用预分箱(MDLP先进行CART预分箱成20箱,再优化为5箱)
>>> binner = OptimalBinning(method='mdlp', prebinning='cart', prebinning_params={'max_n_bins': 20})
>>> binner.fit(X, y)
>>> # 使用预分箱器实例
>>> pre_binner = OptimalBinning(method='cart', max_n_bins=20)
>>> binner = OptimalBinning(method='best_iv', prebinning=pre_binner)
>>> binner.fit(X, y)
>>> # 使用quantile预分箱(先将数据分成20等份,再进行MDLP分箱)
>>> binner = OptimalBinning(method='mdlp', prebinning='quantile', prebinning_params={'max_n_bins': 20})
>>> binner.fit(X, y)
>>> # 自动为某特征选择最优分箱方法
>>> best = OptimalBinning.auto_select_method(X, y, 'age')
>>> binner = OptimalBinning(method=best).fit(X, y)

引用

最优分箱(optimal binning)的两阶段(预分箱 + 二次合并)框架与单调/规划求解参考 optbinning:Navas-Palencia, G. (2020). Optimal binning: mathematical programming formulation. arXiv:2001.08025. https://arxiv.org/abs/2001.08025 ; 各子方法的具体出处见对应分箱类文档。

VALID_METHODS = ['uniform', 'quantile', 'tree', 'chi', 'best_ks', 'best_iv', 'mdlp', 'or_tools', 'cp_sat', 'cart', 'kmeans', 'monotonic', 'genetic', 'smooth', 'kernel_density', 'best_lift', 'target_bad_rate']
static auto_select_method(X, y, feature, methods=None, criterion='iv', n_jobs=-1, parallel_backend=None, parallel_config=None)[源代码]

自动选择最优分箱方法.

对指定特征遍历多种分箱方法,选择最优的一个。 适用于在不了解特征分布时自动选择最佳分箱策略。

参数:
  • X (DataFrame) -- 特征数据 DataFrame

  • y (Series) -- 目标变量 Series,二分类 (0/1)

  • feature (str) -- 待评估的特征名(必须是X中的列)

  • methods (List[str] | None) -- 待评估的方法列表,默认为 ['uniform', 'quantile', 'tree', 'chi', 'best_ks', 'best_iv', 'mdlp', 'cart', 'kmeans']

  • criterion (str) -- 选择标准,默认为 'iv' - 'iv': 选择IV值最大的方法 - 'ks': 选择KS值最大的方法

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

返回:

最优方法名(字符串)

抛出:

Warning -- 某个方法执行失败时输出警告但继续评估其他方法

返回类型:

str

参考样例

>>> binner = OptimalBinning()
>>> best_method = OptimalBinning.auto_select_method(X, y, 'age')
>>> print(f"最优方法: {best_method}")
>>>
>>> # 自定义方法列表
>>> best = OptimalBinning.auto_select_method(
...     X, y, 'income',
...     methods=['best_iv', 'cart', 'mdlp'],
...     criterion='ks'
... )
>>>
>>> # 使用最优方法进行分箱
>>> binner = OptimalBinning(method=best_method)
>>> binner.fit(X[[feature]], y)
fit(X, y=None, **kwargs)[源代码]

拟合分箱.

参数:
  • X (DataFrame | ndarray) -- 训练数据

  • y (ndarray | Series | None) -- 目标变量

  • kwargs -- 其他参数

返回:

拟合后的分箱器

返回类型:

OptimalBinning

get_params(deep=True)[源代码]

在不改变 **kwargs 入口的前提下暴露方法专属参数。

参数:

deep (bool)

返回类型:

Dict[str, Any]

get_stats(feature=None)[源代码]

获取分箱统计信息.

返回各特征的IV值、KS值、分箱表等统计指标。

参数:

feature (str | None) -- 特征名,如果为None则返回所有特征的统计,默认为None

返回:

统计信息字典 - 如果指定了feature,返回 {'n_bins_': int, 'bin_table': DataFrame, 'ks': float, 'iv': float, 'monotonic_trend': str} - 如果未指定feature,返回 {feature_name: stats, ...} 格式的字典

抛出:
  • ValueError -- 如果分箱器尚未拟合

  • KeyError -- 如果指定特征不存在

返回类型:

Dict[str, Any]

参考样例

>>> binner = OptimalBinning(method='best_iv')
>>> binner.fit(X, y)
>>>
>>> # 获取单个特征的统计
>>> stats = binner.get_stats('age')
>>> print(stats['n_bins_'])   # 分箱数
>>> print(stats['iv'])      # IV值
>>> print(stats['ks'])      # KS值
>>> print(stats['bin_table'])  # 分箱统计表
>>>
>>> # 获取所有特征的统计
>>> all_stats = binner.get_stats()
>>> for feat, s in all_stats.items():
...     print(f"{feat}: IV={s.get('iv', 'N/A')}")
set_params(**params)[源代码]

支持 sklearn 为显式参数和方法专属 **kwargs 参数赋值。

返回类型:

OptimalBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = OptimalBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
classmethod validate_method(method)[源代码]

校验并归一化分箱方法名.

统一所有入口的 method 校验逻辑:类型检查、大小写与首尾空白归一化、 枚举值校验。不支持别名(如 'iv''chi2' 会被拒绝)。

参数:

method (str) -- 分箱方法名

返回:

归一化后的方法名(小写、去除首尾空白)

抛出:

ValueError -- method 不是字符串或不在 VALID_METHODS 中时抛出

返回类型:

str

class hscredit.core.binning.MDLPBinning(target='target', max_n_bins=10, min_n_bins=2, min_samples_split=2, min_samples_leaf=2, max_candidates=32, min_iv_gain=0.0001, force_min_bins=True, mdlp_weight=0.7, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=False, special_codes=None, missing_separate=True, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, verbose=False, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None, **kwargs)[源代码]

基类:BaseBinning

MDLP 分箱算法.

基于最小描述长度原理的递归分箱方法,自动确定最优分箱数。 使用信息增益和 MDLP 准则决定是否继续分割。

优化版本V3特点(针对平滑分布): - 放宽终止条件,支持force_min_bins强制最小分箱数 - 改进候选切分点选择,结合IV值评估 - 更好的平滑分布处理

参数:
  • target (str) -- 目标变量列名,默认为'target'

  • max_n_bins (int) -- 最大分箱数,默认为10

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_samples_split (int) -- 分割内部节点所需的最小样本数,默认为2

  • min_samples_leaf (int) -- 叶子节点所需的最小样本数,默认为2

  • max_candidates (int) -- 每次评估的最大候选切分点数,默认为32

  • min_iv_gain (float) -- 最小IV增益阈值,默认为0.0001(降低以允许更多分箱)

  • force_min_bins (bool) -- 是否强制满足最小分箱数,默认为True

  • mdlp_weight (float) -- MDLP准则权重(0-1之间),默认为0.7(降低以放宽终止条件)

  • special_codes (List | None) -- 特殊值列表,默认为None

  • missing_separate (bool) -- 是否将缺失值单独分为一箱,默认为True

  • random_state (int | None) -- 随机种子,默认为None

  • verbose (bool | int) -- 是否输出详细信息,默认为False

  • min_bin_size (float | int)

  • max_bin_size (int | float | None)

  • min_bad_rate (float)

  • monotonic (bool | str)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

参考样例

>>> from hscredit.core.binning import MDLPBinning
>>> binner = MDLPBinning(max_n_bins=5, min_n_bins=2)
>>> binner.fit(X_train, y_train)
>>> X_binned = binner.transform(X_test)

引用

Fayyad, U. M., & Irani, K. B. (1993). Multi-interval discretization of continuous-valued attributes for classification learning. IJCAI-93. https://trs.jpl.nasa.gov/handle/2014/35171 ; MDLP(最小描述长度原理)参见 https://en.wikipedia.org/wiki/Minimum_description_length

fit(X, y=None, **kwargs)[源代码]

拟合 MDLP 分箱.

参数:
  • X (DataFrame | ndarray) -- 特征数据

  • y (ndarray | Series | None) -- 目标变量

返回:

self

返回类型:

MDLPBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = MDLPBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.ORBinning(target='target', max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic='auto', objective='iv', custom_objective=None, n_prebins=20, max_candidates=100, time_limit=60, use_cp_sat=False, num_workers=None, missing_separate=True, special_codes=None, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None, **kwargs)[源代码]

基类:BaseBinning

OR-Tools 运筹规划分箱.

基于 Google OR-Tools CP-SAT 求解器的最优化分箱方法。 支持多种优化目标和约束条件,能够找到全局最优分箱方案。 支持自定义目标函数,可实现复合指标优化。

参数

参数:
  • target (str) -- 目标变量列名,默认为'target'。在scorecardpipeline风格中使用, 当fit时只传入df且y为None时,从df中提取该列作为目标变量。

  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (Union[float, int]) -- 每箱最小样本数或占比,默认为0.01 - 如果 < 1, 表示占比 (如 0.01 表示 1%) - 如果 >= 1, 表示绝对数量 (如 100 表示最少100个样本)

  • max_bin_size (Optional[Union[float, int]]) -- 每箱最大样本数或占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0

  • monotonic (Union[bool, str]) -- 坏样本率单调性约束,默认为auto - False: 不要求单调性 - True 或 'auto': 自动检测并应用最佳单调方向 - 'ascending': 强制坏样本率递增 - 'descending': 强制坏样本率递减

  • objective (str) -- 优化目标,默认为'iv' - 'iv': 最大化 IV 值 - 'ks': 最大化 KS 统计量 - 'gini': 最大化 Gini 系数 - 'entropy': 最小化熵(信息增益最大) - 'chi2': 最大化卡方统计量 - 'custom': 使用自定义目标函数(通过 custom_objective 参数传入)

  • custom_objective (Optional[callable]) -- 自定义目标函数,当 objective='custom' 时使用 - 类型: Callable[[List[Dict], int, int], float] - 参数: bin_stats(List[Dict]) 每个箱的统计信息, total_good(int) 总好样本数, total_bad(int) 总坏样本数 - 返回: float 目标函数值,越大越好(OR-Tools 求解器始终最大化) - 箱统计字典包含: 'count', 'good', 'bad', 'bad_rate', 'good_rate', 'lift', 'woe'

  • n_prebins (int) -- 预分箱数量(候选分割点数),默认为20 - 候选点越多,求解越精确,但计算时间越长

  • max_candidates (int) -- 最大候选分割点数,默认为100 - 如果唯一值超过此数,将使用分位数采样

  • time_limit (int) -- 求解时间限制(秒),默认为60 - 超过此时间将返回当前找到的最优解

  • use_cp_sat (bool) -- 是否使用真正的 CP-SAT 求解器,默认为False - False: 使用启发式+DP组合算法,速度快,结果接近最优 - True: 使用 CP-SAT 约束规划求解器,保证全局最优解

  • num_workers (Optional[int]) -- 原生求解器线程数;默认 None,继承统一 n_jobs 预算 - 可以设置为大于1以加速求解(仅在 use_cp_sat=True 时生效)

  • missing_separate (bool) -- 缺失值是否单独分箱,默认为True

  • special_codes (Optional[List]) -- 特殊值列表,默认为None

  • random_state (Optional[int]) -- 随机种子,默认为None

  • cat_cutoff (Optional[Union[float, int]])

  • handle_unknown (Union[int, str])

  • n_jobs (Union[int, float])

  • parallel_backend (Optional[str])

  • parallel_config (Optional[Dict[str, Any]])

  • user_splits (Optional[Dict[str, List]])

  • user_splits_fixed (Optional[Union[bool, Dict[str, Union[bool, List[bool]]]]])

参考样例

sklearn风格 (推荐):

>>> from hscredit.core.binning import ORBinning
>>> # 最大化 IV
>>> binner = ORBinning(max_n_bins=5, objective='iv', monotonic=True)
>>> binner.fit(X_train, y_train)
>>> X_binned = binner.transform(X_test)
>>> bin_table = binner.get_bin_table('feature_name')

scorecardpipeline风格 (目标列在DataFrame中):

>>> from hscredit.core.binning import ORBinning
>>> # 初始化时指定目标列名,fit时传入完整DataFrame
>>> binner = ORBinning(target='target', max_n_bins=5, objective='ks', time_limit=60)
>>> binner.fit(df)  # df包含特征列和目标列'target'
>>> X_binned = binner.transform(df.drop(columns=['target']))

混合风格 (y参数优先):

>>> # 即使初始化时指定了target,fit时传入y会优先使用y
>>> binner = ORBinning(target='target', objective='iv')
>>> binner.fit(df, y=external_y)  # 使用external_y,忽略df中的'target'列
>>>
>>> # 自定义目标:最大化 LIFT + IV
>>> def custom_obj(bin_stats, total_good, total_bad):
...     total_iv = sum(stat.get('woe', 0) * (stat.get('bad_rate', 0) - stat.get('good_rate', 0))
...                    for stat in bin_stats if 'woe' in stat)
...     total_lift = sum(abs(stat.get('lift', 1) - 1) for stat in bin_stats)
...     return total_iv + total_lift * 0.1  # IV + 0.1 * LIFT偏差
>>>
>>> binner = ORBinning(objective='custom', custom_objective=custom_obj)
>>> binner.fit(X_train, y_train)

使用 CP-SAT 求解器(全局最优)

>>> from hscredit.core.binning import ORBinning
>>> # 使用真正的 CP-SAT 约束规划求解器
>>> binner = ORBinning(
...     max_n_bins=5,
...     objective='iv',
...     monotonic='auto',
...     use_cp_sat=True,  # 启用 CP-SAT 求解器
...     time_limit=60,   # 求解时间限制
...     num_workers=4   # 并行工作线程数
... )
>>> binner.fit(X_train, y_train)
>>> X_binned = binner.transform(X_test)

注意

OR-Tools 分箱的特点: 1. 能够找到全局最优解(而非贪心算法的局部最优) 2. 支持复杂的约束条件组合 3. 支持自定义目标函数,实现复合指标优化 4. 计算时间较长,适合对分箱质量要求高的场景 5. 可以设置时间限制,在时间和精度之间权衡

自定义目标函数示例

  1. 最大 LIFT + IV:

    def max_lift_iv(bin_stats, total_good, total_bad):
        total_iv = sum(stat['woe'] * (stat['bad_rate'] - stat['good_rate'])
                      for stat in bin_stats)
        total_lift = sum(stat['lift'] for stat in bin_stats)
        return total_iv + total_lift * 0.01
    
  2. 最小 LIFT + IV(LIFT 越接近1越好):

    def min_lift_iv(bin_stats, total_good, total_bad):
        total_iv = sum(stat['woe'] * (stat['bad_rate'] - stat['good_rate'])
                      for stat in bin_stats)
        lift_penalty = sum(abs(stat['lift'] - 1) for stat in bin_stats)
        return total_iv - lift_penalty * 0.1  # 减去惩罚项
    
  3. 最大/最小 LIFT 离1的距离求和 + IV:

    def lift_distance_iv(bin_stats, total_good, total_bad):
        total_iv = sum(stat['woe'] * (stat['bad_rate'] - stat['good_rate'])
                      for stat in bin_stats)
        max_lift_dist = max(abs(stat['lift'] - 1) for stat in bin_stats)
        min_lift_dist = min(abs(stat['lift'] - 1) for stat in bin_stats)
        return total_iv + (max_lift_dist + min_lift_dist) * 0.1
    

引用

最优分箱的数学规划建模参考 optbinning:Navas-Palencia, G. (2020). Optimal binning: mathematical programming formulation. arXiv:2001.08025. https://arxiv.org/abs/2001.08025 ;求解器为 Google OR-Tools https://developers.google.com/optimization 。与 CPSATBinning 相比, 本类额外支持自定义目标函数与启发式+DP 快速模式(use_cp_sat=False)。

fit(X, y=None, **kwargs)[源代码]

拟合 OR-Tools 运筹规划分箱.

支持两种API风格: 1. sklearn风格: fit(X, y) - X是特征矩阵,y是目标变量 2. scorecardpipeline风格: fit(df) - df是完整数据框,目标列名在初始化时通过target参数传入

优先级规则:如果y不是None,直接使用y(优先);否则从X中提取target列。

参数:
  • X (DataFrame | ndarray) -- 训练数据 - sklearn风格: 特征矩阵,shape (n_samples, n_features) - scorecardpipeline风格: 完整数据框,包含特征列和目标列

  • y (ndarray | Series | None) -- 目标变量(可选) - sklearn风格: 传入目标变量 - scorecardpipeline风格: 不传,从X中提取 - 如果传入y,优先使用y而忽略X中的target列

返回:

拟合后的分箱器

返回类型:

ORBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = ORBinning(objective='iv')
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.CustomObjectives[源代码]

基类:object

常用自定义目标函数集合.

提供预定义的复合指标目标函数,可与 ORBinning 的 custom_objective 参数配合使用.

使用示例

>>> from hscredit.core.binning import ORBinning, CustomObjectives
>>>
>>> # 使用预定义的最大 LIFT + IV 目标
>>> binner = ORBinning(
...     objective='custom',
...     custom_objective=CustomObjectives.max_lift_iv(lift_weight=0.1)
... )
>>> binner.fit(X_train, y_train)
>>>
>>> # 使用自定义权重
>>> binner = ORBinning(
...     objective='custom',
...     custom_objective=CustomObjectives.min_lift_distance_iv(
...         iv_weight=1.0,
...         lift_weight=0.5
...     )
... )
static lift_distance_sum_iv(lift_weight=0.1, iv_weight=1.0)[源代码]

最大/最小LIFT离1的距离求和 + IV 目标函数.

目标:最大化(最大LIFT离1的距离 + 最小LIFT离1的距离)+ IV 值

参数:
  • lift_weight (float) -- LIFT距离和项权重

  • iv_weight (float) -- IV 项权重

返回:

目标函数

原理

同时考虑最强和最弱分箱与基准线的偏离程度,平衡极端区分能力.

static max_ks_iv(ks_weight=0.5, iv_weight=1.0)[源代码]

最大 KS + IV 复合目标函数.

同时考虑 KS 统计量和 IV 值。

参数:
  • ks_weight (float) -- KS 项权重

  • iv_weight (float) -- IV 项权重

返回:

目标函数

static max_lift_distance_iv(lift_weight=0.1, iv_weight=1.0)[源代码]

最大LIFT离1的距离 + IV 目标函数.

目标:最大化(最大LIFT离1的距离)+ IV 值

参数:
  • lift_weight (float) -- 最大LIFT距离项权重

  • iv_weight (float) -- IV 项权重

返回:

目标函数

原理

鼓励产生至少一个与基准(LIFT=1)有明显偏离的强区分分箱.

static max_lift_iv(lift_weight=0.1, iv_weight=1.0)[源代码]

最大 LIFT + IV 目标函数.

目标:最大化(所有分箱中LIFT最大的那一箱的LIFT值)+ IV 值

参数:
  • lift_weight (float) -- 最大LIFT项权重

  • iv_weight (float) -- IV 项权重

返回:

目标函数

原理

LIFT = 箱内坏样本率 / 总体坏样本率 - LIFT > 1: 该箱坏样本率高于平均水平 - LIFT < 1: 该箱坏样本率低于平均水平

通过最大化最大LIFT,鼓励产生至少一个强区分能力的分箱.

static max_min_lift_sum_iv(lift_weight=0.1, iv_weight=1.0)[源代码]

最大LIFT + 最小LIFT + IV 目标函数.

目标:最大化(最大LIFT值 + 最小LIFT值)+ IV 值

参数:
  • lift_weight (float) -- LIFT和项权重

  • iv_weight (float) -- IV 项权重

返回:

目标函数

原理

同时考虑最强和最弱分箱的LIFT值,确保分箱既有强区分箱,整体区分度也较好.

static min_lift_distance_iv(lift_weight=0.1, iv_weight=1.0)[源代码]

最小LIFT离1的距离 + IV 目标函数.

目标:最大化(最小LIFT离1的距离)+ IV 值

参数:
  • lift_weight (float) -- 最小LIFT距离项权重

  • iv_weight (float) -- IV 项权重

返回:

目标函数

原理

鼓励最弱分箱也有较好的区分能力,避免某些分箱过于接近基准线.

static min_lift_iv(lift_weight=0.1, iv_weight=1.0)[源代码]

最小 LIFT + IV 目标函数.

目标:最大化(所有分箱中LIFT最小的那一箱的LIFT值)+ IV 值

参数:
  • lift_weight (float) -- 最小LIFT项权重

  • iv_weight (float) -- IV 项权重

返回:

目标函数

原理

通过最大化最小LIFT,鼓励产生均匀分布的区分能力,避免某些分箱过于弱势.

static woe_variance_iv(variance_weight=0.1, iv_weight=1.0)[源代码]

WOE 方差 + IV 目标函数.

鼓励 WOE 在各箱之间有较大差异,提高区分度。

参数:
  • variance_weight (float) -- WOE 方差项权重

  • iv_weight (float) -- IV 项权重

返回:

目标函数

class hscredit.core.binning.CPSATBinning(target='target', max_n_bins=5, min_n_bins=2, min_bin_size=0.02, max_bin_size=None, min_bad_rate=0.0, monotonic='auto', objective='iv', n_prebins=50, max_candidates=100, time_limit=30, num_workers=None, missing_separate=True, special_codes=None, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None, **kwargs)[源代码]

基类:BaseBinning

CP-SAT 运筹规划分箱.

基于 Google OR-Tools CP-SAT 求解器的最优化分箱方法。 将分箱问题建模为约束规划问题,通过 CP-SAT 求解器找到全局最优分箱方案。

参数

参数:
  • target (str) -- 目标变量列名,默认为'target'。在scorecardpipeline风格中使用, 当fit时只传入df且y为None时,从df中提取该列作为目标变量。

  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (Union[float, int]) -- 每箱最小样本数或占比,默认为0.02 - 如果 < 1, 表示占比 (如 0.02 表示 2%) - 如果 >= 1, 表示绝对数量 (如 100 表示最少100个样本)

  • max_bin_size (Optional[Union[float, int]]) -- 每箱最大样本数或占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0

  • monotonic (Union[bool, str]) -- 坏样本率单调性约束,默认为'auto' - False: 不要求单调性 - True 或 'auto': 自动检测并应用最佳单调方向 - 'ascending': 强制坏样本率递增 - 'descending': 强制坏样本率递减

  • objective (str) -- 优化目标,默认为'iv' - 'iv': 最大化 IV 值(Information Value) - 'ks': 最大化 KS 统计量 - 'gini': 最大化 Gini 系数

  • n_prebins (int) -- 预分箱数量(候选分割点数),默认为50 - 候选点越多,求解越精确,但计算时间越长

  • max_candidates (int) -- 最大候选分割点数,默认为100 - 如果唯一值超过此数,将使用分位数采样

  • time_limit (int) -- 求解时间限制(秒),默认为30 - 超过此时间将返回当前找到的最优解

  • num_workers (Optional[int]) -- 原生求解器线程数;默认 None,继承统一 n_jobs 预算 - 可以设置为大于1以加速求解

  • missing_separate (bool) -- 缺失值是否单独分箱,默认为True

  • special_codes (Optional[List]) -- 特殊值列表,默认为None

  • random_state (Optional[int]) -- 随机种子,默认为None

  • cat_cutoff (Optional[Union[float, int]])

  • handle_unknown (Union[int, str])

  • n_jobs (Union[int, float])

  • parallel_backend (Optional[str])

  • parallel_config (Optional[Dict[str, Any]])

  • user_splits (Optional[Dict[str, List]])

  • user_splits_fixed (Optional[Union[bool, Dict[str, Union[bool, List[bool]]]]])

参考样例

sklearn风格 (推荐):

>>> from hscredit.core.binning import CPSATBinning
>>> # 最大化 IV
>>> binner = CPSATBinning(max_n_bins=5, objective='iv', monotonic='auto')
>>> binner.fit(X_train, y_train)
>>> X_binned = binner.transform(X_test)
>>> bin_table = binner.get_bin_table('feature_name')

scorecardpipeline风格 (目标列在DataFrame中):

>>> from hscredit.core.binning import CPSATBinning
>>> binner = CPSATBinning(target='target', max_n_bins=5, objective='ks', time_limit=60)
>>> binner.fit(df)
>>> X_binned = binner.transform(df.drop(columns=['target']))

注意

CP-SAT 分箱的特点: 1. 能够找到全局最优解(而非贪心算法的局部最优) 2. 支持复杂的约束条件组合 3. 计算时间可控,可设置时间限制 4. 适合对分箱质量要求高的场景 5. 依赖可选包 ortools,未安装时实例化会抛出 ImportError

引用

将最优分箱建模为数学规划问题参考 optbinning:Navas-Palencia, G. (2020). Optimal binning: mathematical programming formulation. arXiv:2001.08025. https://arxiv.org/abs/2001.08025 ;求解器为 Google OR-Tools CP-SAT https://developers.google.com/optimization/cp/cp_solver

fit(X, y=None, **kwargs)[源代码]

拟合 CP-SAT 运筹规划分箱.

参数:
  • X (DataFrame | ndarray) -- 训练数据

  • y (ndarray | Series | None) -- 目标变量(可选)

返回:

拟合后的分箱器

返回类型:

CPSATBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

参数:
  • X (DataFrame | ndarray)

  • metric (str)

返回类型:

DataFrame | ndarray

class hscredit.core.binning.KMeansBinning(target='target', max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=False, special_codes=None, missing_separate=True, force_numerical=False, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, n_init=10, max_iter=300, verbose=False, decimal=4, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None)[源代码]

基类:BaseBinning

K-Means聚类分箱算法.

使用K-Means算法将特征值聚类成K个簇,每个簇作为一个分箱。 根据聚类中心排序确定分箱边界(相邻聚类中心的中点)。

参数:
  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0

  • monotonic (bool | str) -- 是否要求坏样本率单调,默认为False

  • special_codes (List | None) -- 特殊值列表,默认为None

  • missing_separate (bool) -- 是否将缺失值单独分为一箱,默认为True

  • random_state (int | None) -- 随机种子,用于K-Means初始化,默认为None

  • force_numerical (bool) -- 是否强制作为数值型处理,默认为False(自动识别类别型) - True: 将所有特征视为数值型进行K-Means聚类分箱 - False: 自动检测特征类型

  • n_init (int) -- K-Means初始化次数,默认为10

  • max_iter (int) -- K-Means最大迭代次数,默认为300

  • verbose (bool | int) -- 是否输出详细信息,默认为False

  • target (str)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • decimal (int)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

属性

  • splits_: 每个特征的分箱切分点

  • n_bins_: 每个特征的实际分箱数

  • bin_tables_: 每个特征的分箱统计表

参考样例

>>> from hscredit.core.binning import KMeansBinning
>>> # 基础用法
>>> binner = KMeansBinning(max_n_bins=5, random_state=42)
>>> binner.fit(X, y)
>>> X_binned = binner.transform(X)
>>>
>>> # 查看分箱统计
>>> bin_table = binner.get_bin_table('feature_name')

注意

K-Means 为无监督分箱,依据特征数值的聚类结构切分、不使用标签 y 决定边界 (切分点取相邻聚类中心的中点);对存在自然分组的特征效果好,对均匀分布的特征则 与等距分箱接近。

引用

K-Means 聚类:MacQueen, J. (1967) 与 Lloyd, S. (1982); https://en.wikipedia.org/wiki/K-means_clustering

fit(X, y=None, **kwargs)[源代码]

拟合 K-Means 分箱。

对每个数值特征做一维 K-Means 聚类,以相邻聚类中心的中点作为切分点;类别特征按 类别成箱。支持 sklearn 风格 fit(X, y) 与 scorecardpipeline 风格 fit(df), 详见 BaseBinning.fit()

参数:
  • X (DataFrame | ndarray) -- 训练数据,shape (n_samples, n_features),DataFrame 或 ndarray

  • y (ndarray | Series | None) -- 二分类目标变量(0=好/1=坏),仅用于生成分箱统计表; scorecardpipeline 风格下可省略

  • kwargs -- 透传给基类的其他参数

返回:

拟合后的分箱器自身(便于链式调用)

返回类型:

KMeansBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = KMeansBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.MonotonicBinning(target='target', monotonic='auto', init_method='quantile', init_n_bins=20, max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, special_codes=None, missing_separate=True, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, verbose=False, decimal=4, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None)[源代码]

基类:BaseBinning

单调性约束分箱算法 - 支持U型和倒U型.

通过初始分箱后合并相邻箱,确保坏样本率或WOE值满足指定的单调性约束。 支持多种单调性模式,包括递增、递减、峰值、谷值、凸函数、凹函数等。 参考optbinning的monotonic_trend参数实现。

参数:
  • monotonic (bool | str | None) -- 单调性约束类型,默认为'auto' - 'auto': 自动检测最佳趋势(允许单增、单减、正U、倒U) - 'auto_asc_desc': 自动检测,但只允许单增或单减 - 'auto_heuristic': 使用启发式方法自动检测 - 'ascending': 强制坏样本率递增 - 'descending': 强制坏样本率递减 - 'peak': 倒U型/峰值(先增后减) - 'valley': U型/谷值(先减后增) - 'convex': 凸函数(U型近似) - 'concave': 凹函数(倒U型近似) - 'peak_heuristic': 使用启发式方法检测峰值 - 'valley_heuristic': 使用启发式方法检测谷值 - False/None: 不强制单调性

  • init_method (str) -- 初始分箱方法,默认为'quantile' - 'quantile': 等频分箱 - 'uniform': 等距分箱

  • init_n_bins (int) -- 初始分箱数,默认为20

  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0

  • special_codes (List | None) -- 特殊值列表,默认为None

  • missing_separate (bool) -- 是否将缺失值单独分为一箱,默认为True

  • random_state (int | None) -- 随机种子,默认为None

  • verbose (bool | int) -- 是否输出详细信息,默认为False

  • target (str)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • decimal (int)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

属性

  • splits_: 每个特征的分箱切分点

  • n_bins_: 每个特征的实际分箱数

  • bin_tables_: 每个特征的分箱统计表

  • monotonic_trend_: 每个特征检测到的单调趋势

参考样例

>>> from hscredit.core.binning import MonotonicBinning
>>> # 峰值模式(倒U型)
>>> binner = MonotonicBinning(monotonic='peak', max_n_bins=5)
>>> binner.fit(X, y)
>>>
>>> # 谷值模式(U型)
>>> binner = MonotonicBinning(monotonic='valley', max_n_bins=5)
>>> binner.fit(X, y)
>>>
>>> # 自动检测
>>> binner = MonotonicBinning(monotonic='auto', max_n_bins=5)
>>> binner.fit(X, y)
>>> print(f"检测到的模式: {binner.monotonic_trend_}")

引用

单调最优分箱(monotonic_trend:ascending/descending/peak/valley/convex/concave) 设计参考 optbinning:Navas-Palencia, G. (2020). Optimal binning: mathematical programming formulation. arXiv:2001.08025. https://arxiv.org/abs/2001.08025

VALID_MONOTONIC_MODES = ['auto', 'auto_asc_desc', 'auto_heuristic', 'ascending', 'descending', 'peak', 'valley', 'convex', 'concave', 'peak_heuristic', 'valley_heuristic', None, False]
fit(X, y=None, **kwargs)[源代码]

拟合单调性约束分箱.

参数:
  • X (DataFrame | ndarray) -- 训练数据,shape (n_samples, n_features)

  • y (ndarray | Series | None) -- 目标变量,二分类 (0/1)

  • kwargs -- 其他参数

返回:

拟合后的分箱器

返回类型:

MonotonicBinning

plot_binning(feature, metric='bad_rate', figsize=(10, 6), save_path=None)[源代码]

绘制分箱结果可视化.

参数:
  • feature (str) -- 特征名

  • metric (str) -- 绘制的指标,'bad_rate' 或 'woe'

  • figsize (Tuple[int, int]) -- 图形大小

  • save_path (str | None) -- 保存路径

返回:

matplotlib图形对象

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = MonotonicBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.GeneticBinning(target='target', population_size=50, generations=100, mutation_rate=0.1, crossover_rate=0.8, elitism_rate=0.1, objective='iv', max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=False, special_codes=None, missing_separate=True, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, verbose=False, decimal=4, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None)[源代码]

基类:BaseBinning

遗传算法分箱.

使用遗传算法在候选切分点中搜索最优分箱方案,支持多种优化目标。 通过交叉、变异、选择等遗传操作,逐步逼近全局最优解。

参数:
  • population_size (int) -- 种群大小,默认为50

  • generations (int) -- 迭代代数,默认为100

  • mutation_rate (float) -- 变异率,默认为0.1

  • crossover_rate (float) -- 交叉率,默认为0.8

  • elitism_rate (float) -- 精英保留率(每代直接保留的最优个体比例),默认为0.1

  • objective (str) --

    适应度(优化目标)函数,默认为 'iv'。可取以下枚举值:

    • 'iv':最大化 Information Value(信息价值),最常用,衡量整体预测力

    • 'ks':最大化 KS 统计量,衡量好坏样本累积分布的最大区分度

    • 'gini':最大化 Gini 系数(≈ 2×AUC−1),衡量排序区分能力

  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0

  • monotonic (bool | str) -- 是否要求坏样本率单调,默认为False

  • special_codes (List | None) -- 特殊值列表,默认为None

  • missing_separate (bool) -- 是否将缺失值单独分为一箱,默认为True

  • random_state (int | None) -- 随机种子,默认为None

  • verbose (bool | int) -- 是否输出详细信息,默认为False

  • target (str)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • decimal (int)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

参考样例

>>> from hscredit.core.binning import GeneticBinning
>>> binner = GeneticBinning(objective='iv', max_n_bins=5, generations=100)
>>> binner.fit(X, y)
>>> X_binned = binner.transform(X)

注意

遗传算法为随机全局优化,结果依赖 random_state;相比贪心方法更可能跳出局部最优, 但计算开销随 population_size × generations 增长,适合约束复杂、对分箱质量要求高的场景。

引用

遗传算法:Holland, J. H. (1975). Adaptation in Natural and Artificial Systems. https://en.wikipedia.org/wiki/Genetic_algorithm

fit(X, y=None, **kwargs)[源代码]

拟合遗传算法分箱。

对每个特征以遗传算法(选择/交叉/变异/精英保留)在候选切分点中搜索使 objective 最大化的分箱方案。支持 sklearn 与 scorecardpipeline 两种调用风格,详见 BaseBinning.fit()

参数:
  • X (DataFrame | ndarray) -- 训练数据,shape (n_samples, n_features),DataFrame 或 ndarray

  • y (ndarray | Series | None) -- 二分类目标变量(0=好/1=坏);scorecardpipeline 风格下可省略

  • kwargs -- 透传给基类的其他参数

返回:

拟合后的分箱器自身(便于链式调用)

返回类型:

GeneticBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签或WOE值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = GeneticBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
class hscredit.core.binning.SmoothBinning(target='target', method='adaptive', smoothing_param=0.5, max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, prior_bad_rate=None, monotonic=None, n_prebins=100, merge_criterion='iv_chi2', chi2_threshold=3.84, min_iv_improvement=0.001, special_codes=None, missing_separate=True, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, verbose=False, decimal=4, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None)[源代码]

基类:BaseBinning

平滑/正则化分箱.

通过平滑技术和正则化约束防止分箱过拟合,提高模型泛化能力。 支持多种平滑方法:Laplace平滑、贝叶斯平滑、Beta平滑等。

优化版本V3特点(针对平滑分布): - 改进合并逻辑,避免过度合并 - 支持IV变化率检测,保留有价值的切分点 - 自适应平滑强度

参数:
  • method (str) --

    坏样本率平滑方法,默认为 'adaptive'。可取以下枚举值:

    • 'laplace':拉普拉斯(加性)平滑,坏样本率 = (坏数 + k) / (总数 + 2k)

    • 'bayesian':贝叶斯平滑,以全局/先验坏样本率为先验做收缩

    • 'beta':Beta 分布共轭先验平滑

    • 'adaptive':自适应平滑,按各箱样本量动态调整平滑强度(样本越少收缩越强)

  • smoothing_param (float) -- 平滑强度参数(越大越向先验收缩),默认为0.5

  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None

  • min_bad_rate (float) -- 每箱最小坏样本率,默认为0.0

  • prior_bad_rate (float | None) -- 先验坏样本率,默认为None(使用全局坏样本率)

  • monotonic (str | None) -- 单调性约束,默认为None,可选 'ascending' / 'descending' / 'peak' / 'valley' / None,含义见 BaseBinning

  • n_prebins (int) -- 预分箱数量,默认为100(提高预分箱数以获得更多候选点)

  • merge_criterion (str) --

    相邻箱合并准则,默认为 'iv_chi2'。可取以下枚举值:

    • 'iv':仅按合并前后 IV 损失最小决定合并

    • 'chi2':仅按相邻箱卡方值(分布差异显著性)决定合并

    • 'iv_chi2':综合 IV 损失与卡方显著性(推荐)

  • chi2_threshold (float) -- 卡方检验阈值,默认为3.84(自由度1、p=0.05)

  • min_iv_improvement (float) -- 最小IV改进阈值,默认为0.001

  • special_codes (List | None) -- 特殊值列表,默认为None

  • missing_separate (bool) -- 是否将缺失值单独分为一箱,默认为True

  • random_state (int | None) -- 随机种子,默认为None

  • verbose (bool | int) -- 是否输出详细信息,默认为False

  • target (str)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • decimal (int)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

参考样例

>>> from hscredit.core.binning import SmoothBinning
>>> binner = SmoothBinning(method='adaptive', max_n_bins=5)
>>> binner.fit(X, y)
>>> X_binned = binner.transform(X)

注意

平滑分箱通过对各箱坏样本率做收缩(向先验靠拢)来抑制小样本箱的 WOE/IV 虚高, 适合样本量小或噪声大的场景,可显著降低分箱在跨期数据上的不稳定(PSI)。

引用

加性(拉普拉斯)平滑与贝叶斯收缩:https://en.wikipedia.org/wiki/Additive_smoothing ; 经验贝叶斯收缩思想参见 Efron & Morris (1975), James–Stein estimator。

fit(X, y=None, **kwargs)[源代码]

拟合平滑分箱。

预分箱后按 merge_criterion 合并相邻箱,并以 method 指定的平滑方法对各箱 坏样本率做收缩。支持 sklearn 与 scorecardpipeline 两种调用风格,详见 BaseBinning.fit()

参数:
  • X (DataFrame | ndarray) -- 训练数据,shape (n_samples, n_features),DataFrame 或 ndarray

  • y (ndarray | Series | None) -- 二分类目标变量(0=好/1=坏);scorecardpipeline 风格下可省略

  • kwargs -- 透传给基类的其他参数

返回:

拟合后的分箱器自身(便于链式调用)

返回类型:

SmoothBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

参数:
  • X (DataFrame | ndarray)

  • metric (str)

返回类型:

DataFrame | ndarray

class hscredit.core.binning.KernelDensityBinning(target='target', kernel='gaussian', bandwidth='isj', min_peak_height=0.05, min_peak_distance=0.05, max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, monotonic=None, use_target=True, n_grid_points=1000, smooth_density=True, iv_weight=0.7, fallback_to_iv=True, special_codes=None, missing_separate=True, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, verbose=False, decimal=4, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None)[源代码]

基类:BaseBinning

核密度分箱.

使用核密度估计识别数据分布的局部极大值(峰)和极小值(谷), 以谷值作为分箱边界,使分箱反映数据的自然分布结构。

优化版本V3特点(针对平滑分布): - 当KDE峰谷检测失败时,自动切换到基于IV的切分策略 - 支持检测数据分布的平滑程度 - 改进的带宽自适应

参数:
  • kernel (str) -- 核密度估计的核函数类型,默认为 ``'gaussian'``(高斯核,最常用且平滑)

  • bandwidth (str | float) --

    核密度估计带宽(平滑程度),默认为 'isj'。可取以下枚举值或具体数值:

    • 'isj':Improved Sheather–Jones 法自适应选择(对多峰分布更稳健,推荐)

    • 'scott':Scott 经验法则 n^(-1/5),计算快,适合近正态分布

    • 'silverman':Silverman 经验法则,与 Scott 类似、对长尾略保守

    • 'normal_reference':正态参考法则

    • float:直接指定固定带宽(值越大曲线越平滑、峰越少)

  • min_peak_height (float) -- 最小峰高(相对于最大密度),默认为0.05

  • min_peak_distance (float) -- 峰之间的最小距离(相对于数据范围),默认为0.05

  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01

  • monotonic (str | None) -- 单调性约束,默认为None

  • use_target (bool) -- 是否结合目标变量优化切分点,默认为True

  • n_grid_points (int) -- 核密度估计的网格点数,默认为1000

  • smooth_density (bool) -- 是否对密度曲线进行平滑处理,默认为True

  • iv_weight (float) -- IV值在切分点选择中的权重,默认为0.7

  • fallback_to_iv (bool) -- 当KDE失败时是否回退到IV策略,默认为True

  • special_codes (List | None) -- 特殊值列表,默认为None

  • missing_separate (bool) -- 是否将缺失值单独分为一箱,默认为True

  • random_state (int | None) -- 随机种子,默认为None

  • verbose (bool | int) -- 是否输出详细信息,默认为False

  • target (str)

  • max_bin_size (int | float | None)

  • min_bad_rate (float)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • decimal (int)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

参考样例

>>> from hscredit.core.binning import KernelDensityBinning
>>> binner = KernelDensityBinning(bandwidth='isj', max_n_bins=5)
>>> binner.fit(X, y)
>>> X_binned = binner.transform(X)

注意

核密度分箱以数据分布的"谷值"(密度局部极小处)作为切分点,使分箱边界落在自然的 低密度间隔上,适合明显多峰的特征;当 fallback_to_iv=True 且峰谷检测失败时, 自动回退到基于 IV 的切分策略。

引用

核密度估计(KDE):Rosenblatt (1956), Parzen (1962), https://en.wikipedia.org/wiki/Kernel_density_estimation ; 带宽选择 ISJ 见 Botev, Z. I. et al. (2010). Kernel density estimation via diffusion. Annals of Statistics.

fit(X, y=None, **kwargs)[源代码]

拟合核密度分箱。

对每个特征做核密度估计,以密度曲线的谷值作为切分点(必要时回退到 IV 策略)。 支持 sklearn 与 scorecardpipeline 两种调用风格,详见 BaseBinning.fit()

参数:
  • X (DataFrame | ndarray) -- 训练数据,shape (n_samples, n_features),DataFrame 或 ndarray

  • y (ndarray | Series | None) -- 二分类目标变量(0=好/1=坏);当 use_target=True 时参与切分点优化, scorecardpipeline 风格下可省略

  • kwargs -- 透传给基类的其他参数

返回:

拟合后的分箱器自身(便于链式调用)

返回类型:

KernelDensityBinning

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

参数:
  • X (DataFrame | ndarray)

  • metric (str)

返回类型:

DataFrame | ndarray

class hscredit.core.binning.BestLiftBinning(target='target', max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=0.5, min_bad_rate=0.0, min_lift=0.0, monotonic=True, n_prebins=50, optimization='extreme', missing_separate=True, special_codes=None, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None, **kwargs)[源代码]

基类:BaseBinning

Best Lift 分箱.

基于最大化 Lift 差异的分箱方法,特别关注头部或尾部的极端值。 Lift = 箱内坏样本率 / 总体坏样本率。

业务场景: - 高风险识别:寻找头部 Lift > 2 或尾部 Lift < 0.5 的分箱 - 风险分层:最大化不同分箱间的风险差异

参数:
  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01 - 如果 < 1, 表示占比 (如 0.01 表示 1%) - 如果 >= 1, 表示绝对数量 (如 100 表示最少100个样本)

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为0.5

  • min_lift (float) -- 最小 Lift 阈值,默认为0(不限制) - 设为0:不限制,允许任何 Lift 值 - 设为0.5:过滤掉 Lift > 0.5 的箱(用于识别极低风险) - 设为1.5:只保留 Lift > 1.5 的箱(用于识别极高风险)

  • monotonic (bool | str) -- 坏样本率单调性约束,默认为True - False: 不要求单调性 - True 或 'auto': 自动检测并应用最佳单调方向 - 'ascending': 强制坏样本率递增 - 'descending': 强制坏样本率递减

  • n_prebins (int) -- 预分箱数量,默认为50 - 预分箱越细,结果越精确,但计算量越大

  • optimization (str) -- 优化目标,默认为'extreme' - 'extreme': 最大化极端箱的 Lift(头部最高或尾部最低) - 'spread': 最大化 Lift 分布范围(max - min) - 'iv': 最大化 IV 值

  • missing_separate (bool) -- 缺失值是否单独分箱,默认为True

  • special_codes (List | None) -- 特殊值列表,默认为None

  • random_state (int | None) -- 随机种子,默认为None

  • target (str)

  • min_bad_rate (float)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

参考样例

>>> from hscredit.core.binning import BestLiftBinning
>>> # 识别高风险客群
>>> binner = BestLiftBinning(max_n_bins=5, optimization='extreme')
>>> binner.fit(X_train, y_train)
>>> X_binned = binner.transform(X_test)
>>> bin_table = binner.get_bin_table('feature_name')

注意

Best Lift 分箱的特点: 1. 关注头部/尾部的极端风险识别 2. 支持单调性约束,保证业务可解释性 3. 自动确定最优单调方向 4. 高效的动态规划风格实现

其中 Lift(提升度)= 箱内坏样本率 / 总体坏样本率,Lift>1 表示该箱风险高于均值。

引用

Lift / 提升度是响应模型与风险分层的标准评估口径,参见 Siddiqi, N. (2006). Credit Risk Scorecards. Wiley,以及营销响应模型中的 lift chart 概念 https://en.wikipedia.org/wiki/``Lift_``(data_mining)

fit(X, y=None, **kwargs)[源代码]

拟合 Best Lift 分箱.

参数:
  • X (DataFrame | ndarray) -- 训练数据

  • y (ndarray | Series | None) -- 目标变量

返回:

拟合后的分箱器

返回类型:

BestLiftBinning

get_bin_table(feature)[源代码]

获取分箱统计表.

参数:

feature (str) -- 特征名

返回:

分箱统计表

返回类型:

DataFrame

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

将原始特征值转换为分箱索引、分箱标签、WOE值或LIFT值。

参数:
  • X (DataFrame | ndarray) -- 待转换数据, DataFrame或数组格式

  • metric (str) -- 转换类型, 可选值: - 'indices': 返回分箱索引 (0, 1, 2, ...), 用于后续处理 - 'bins': 返回分箱标签字符串, 用于可视化或报告 - 'woe': 返回WOE值, 用于逻辑回归建模 - 'lift': 返回LIFT值, 用于评估分箱效果

  • kwargs -- 其他参数

返回:

转换后的数据, 格式与输入X相同

Example:

返回类型:

DataFrame | ndarray

>>> binner = BestLiftBinning()
>>> binner.fit(X_train, y_train)
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取WOE编码 (用于建模)
>>> X_woe = binner.transform(X_test, metric='woe')
>>>
>>> # 获取LIFT值
>>> X_lift = binner.transform(X_test, metric='lift')
class hscredit.core.binning.TargetBadRateBinning(target='target', target_bad_rates=None, max_n_bins=5, min_n_bins=2, min_bin_size=0.01, max_bin_size=None, min_bad_rate=0.0, strict_mode=True, merge_empty_bins=True, monotonic=True, missing_separate=True, special_codes=None, cat_cutoff=None, category_order=None, handle_unknown=-3, random_state=None, decimal=4, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits=None, user_splits_fixed=None, **kwargs)[源代码]

基类:BaseBinning

目标坏样本率分箱.

支持两种分箱模式:

**模式1:严格边界模式**(指定 target_bad_rates) 按目标坏样本率边界严格划分,确保每箱的坏样本率在指定区间内。

参数:
  • target_bad_rates (List[float] | None) -- 目标坏样本率边界列表,例如 [0.05, 0.10, 0.20] - 会产生 len(target_bad_rates)+1 个分箱 - 第0箱:坏样本率 <= target_bad_rates[0] - 第1箱:target_bad_rates[0] < 坏样本率 <= target_bad_rates[1] - 依此类推

  • target (str)

  • max_n_bins (int)

  • min_n_bins (int)

  • min_bin_size (float | int)

  • max_bin_size (int | float | None)

  • min_bad_rate (float)

  • strict_mode (bool)

  • merge_empty_bins (bool)

  • monotonic (bool)

  • missing_separate (bool)

  • special_codes (List | None)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • random_state (int | None)

  • decimal (int)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

**模式2:自动模式**(不指定 target_bad_rates,指定 max_n_bins) 自动寻找使每箱之间坏样本率差异最大的划分。

参数:
  • max_n_bins (int) -- 最大分箱数,默认为5

  • min_n_bins (int) -- 最小分箱数,默认为2

  • min_bin_size (float | int) -- 每箱最小样本数或占比,默认为0.01

  • max_bin_size (int | float | None) -- 每箱最大样本数或占比,默认为None

  • strict_mode (bool) -- 是否严格模式(严格限制边界),默认为True - True: 严格按照目标坏样本率边界划分,可能产生空箱 - False: 在满足约束下尽量接近目标坏样本率

  • merge_empty_bins (bool) -- 是否合并空箱,默认为True

  • monotonic (bool) -- 是否要求单调性,默认为True

  • missing_separate (bool) -- 缺失值是否单独分箱,默认为True

  • special_codes (List | None) -- 特殊值列表,默认为None

  • decimal (int) -- 切分点小数点保留精度,默认为4

  • target (str)

  • target_bad_rates (List[float] | None)

  • min_bad_rate (float)

  • cat_cutoff (int | float | None)

  • handle_unknown (int | str)

  • random_state (int | None)

  • n_jobs (int | float)

  • parallel_backend (str | None)

  • parallel_config (Dict[str, Any] | None)

  • user_splits (Dict[str, List] | None)

  • user_splits_fixed (bool | Dict[str, bool | List[bool]] | None)

参考样例

严格边界模式:

>>> # 指定坏样本率边界:5%, 10%, 20%
>>> binner = TargetBadRateBinning(
...     target_bad_rates=[0.05, 0.10, 0.20],
...     strict_mode=True
... )
>>> # 结果:4个分箱,坏样本率分别在 <=5%, 5%-10%, 10%-20%, >20%

自动模式:

>>> # 自动寻找最优划分
>>> binner = TargetBadRateBinning(max_n_bins=5)
>>> # 结果:5个分箱,每箱间坏样本率差异最大

注意

本方法以"业务目标坏样本率"为切分依据,属业务驱动的风险分层分箱(risk-based segmentation),无单一学术出处;严格边界模式便于将分箱直接对齐既定的风险定价/ 准入档位。坏样本率(bad rate)即各箱内坏样本占比。

fit(X, y=None, **kwargs)[源代码]

拟合目标坏样本率分箱.

参数:
  • X (DataFrame | ndarray) -- 训练数据

  • y (ndarray | Series | None) -- 目标变量

返回:

拟合后的分箱器

返回类型:

TargetBadRateBinning

get_bad_rate_summary(feature)[源代码]

获取坏样本率摘要.

参数:

feature (str) -- 特征名

返回:

分箱坏样本率摘要表

返回类型:

DataFrame

transform(X, metric='indices', **kwargs)[源代码]

应用分箱转换.

参数:
  • X (DataFrame | ndarray)

  • metric (str)

返回类型:

DataFrame | ndarray

class hscredit.core.binning.OptimalBinning2D(target='target', max_n_bins=5, min_bin_size=0.02, method='quantile', monotonic=False, max_n_bins_2d=None, max_n_bins_x=None, min_bin_size_x=None, method_x=None, monotonic_x=None, user_splits_x=None, special_codes_x=None, dtype_x='numerical', max_n_bins_y=None, min_bin_size_y=None, method_y=None, monotonic_y=None, user_splits_y=None, special_codes_y=None, dtype_y='numerical', x_params=None, y_params=None, missing_separate=True, missing_separate_x=None, missing_separate_y=None, random_state=None, decimal=4, woe_clip=None, verbose=False, n_jobs=-1, parallel_backend=None, parallel_config=None, user_splits_fixed_x=None, user_splits_fixed_y=None)[源代码]

基类:ParallelizableMixin, ArtifactSerializableMixin, BaseEstimator, TransformerMixin

二维分箱器.

对两个特征进行交叉分箱分析,生成二维分箱矩阵,用于揭示特征间的交互效应。 每个单元格包含该交叉区间的样本数、坏样本率、WOE、IV等统计指标。

接口与 OptimalBinning 保持一致,支持 sklearn 和 scorecardpipeline 两种调用风格。

参数

目标与分箱控制
param target:

目标变量列名,默认为 'target'

param max_n_bins:

两个特征的最大分箱数,默认 5

param min_bin_size:

两个特征的每箱最小样本占比,默认 0.02

param method:

分箱方法,默认 'quantile'(等频)

param monotonic:

单调性约束,默认 False。设为 'ascending'/'descending'/True 时, 作为**硬约束**作用于二维合并:最终各轴向相邻分箱的坏样本率保证满足单调趋势 (通过持续合并违例相邻分箱实现,可能使二维分箱数低于 max_n_bins_2d) ascending 表示特征值越大坏样本率越高(越大越差),descending 表示 特征值越大坏样本率越低(越大越好);自动模式复用内部一维分箱器识别的方向。

param max_n_bins_2d:

相邻格子合并后的最大二维分箱数,默认使用 max_n_bins

特征1 专用参数(以 _x 后缀区分)
param max_n_bins_x:

特征1的最大分箱数

param min_bin_size_x:

特征1的每箱最小样本占比

param method_x:

特征1的分箱方法

param monotonic_x:

特征1的单调性约束

param user_splits_x:

特征1的自定义切分点,包含 np.nan/None 时显式预留缺失箱

param special_codes_x:

特征1的特殊值列表

param dtype_x:

特征1的数据类型

特征2 专用参数(以 _y 后缀区分)
param max_n_bins_y:

特征2的最大分箱数

param min_bin_size_y:

特征2的每箱最小样本占比

param method_y:

特征2的分箱方法

param monotonic_y:

特征2的单调性约束

param user_splits_y:

特征2的自定义切分点,包含 np.nan/None 时显式预留缺失箱

param special_codes_y:

特征2的特殊值列表

param dtype_y:

特征2的数据类型

扩展参数
param x_params:

额外参数仅传递给特征1的内部 OptimalBinning

param y_params:

额外参数仅传递给特征2的内部 OptimalBinning 参数优先级统一为:显式 _x/_y 参数 > x_params/y_params > 全局参数。 所有参数会在构造内部 OptimalBinning 前完成合并和校验。

其他参数
param missing_separate:

是否将缺失值单独分箱,默认 True

param missing_separate_x:

是否将特征1缺失值单独分箱,None 时继承 missing_separate

param missing_separate_y:

是否将特征2缺失值单独分箱,None 时继承 missing_separate

param random_state:

随机种子

param decimal:

数值精度

param woe_clip:

WOE截断阈值

param verbose:

是否输出详细信息

属性

  • binner_x_: 特征1的分箱器

  • binner_y_: 特征2的分箱器

  • splits_x_: 特征1的切分点

  • splits_y_: 特征2的切分点

  • n_bins_x_: 特征1的分箱数

  • n_bins_y_: 特征2的分箱数

  • solution_: 预分箱网格到最终二维分箱索引的映射矩阵;存在缺失值时追加缺失行/列

  • n_bins_2d_: 合并后的最终二维分箱数

  • binning_table_: 合并后的二维分箱统计表

  • cross_table_: 二维交叉分箱统计表

  • iv_interaction_: 交互IV值

参考样例

sklearn 风格:

>>> binner = OptimalBinning2D(max_n_bins=5)
>>> binner.fit(X_2d, y_array)  # X_2d shape=(n, 2)

scorecardpipeline 风格:

>>> binner = OptimalBinning2D(max_n_bins=5)
>>> binner.fit(df, y=df['target'], features=['age', 'income'])

获取统计:

>>> cross = binner.get_cross_table()      # 交叉分箱表
>>> table_x = binner.get_bin_table('age')  # 特征1独立分箱表
>>> stats = binner.get_stats()          # 两特征统计
>>> splits = binner.get_splits()        # 两特征切分点
>>> rules = binner.export_rules()       # 分箱规则(末尾 np.nan 表示缺失箱)

引用

二维交互最优分箱接口与求解思路参考 optbinning 的 OptimalBinning2D: Navas-Palencia, G. (2020). Optimal binning: mathematical programming formulation. arXiv:2001.08025. https://arxiv.org/abs/2001.08025 ; 交互效应(feature interaction)背景见 https://gnpalencia.org/optbinning/binning_2d.html

参数:
  • target (str)

  • max_n_bins (int)

  • min_bin_size (Union[float, int])

  • method (str)

  • monotonic (Union[bool, str])

  • max_n_bins_2d (Optional[int])

  • max_n_bins_x (Optional[int])

  • min_bin_size_x (Optional[Union[float, int]])

  • method_x (Optional[str])

  • monotonic_x (Optional[Union[bool, str]])

  • user_splits_x (Optional[List])

  • special_codes_x (Optional[List])

  • dtype_x (str)

  • max_n_bins_y (Optional[int])

  • min_bin_size_y (Optional[Union[float, int]])

  • method_y (Optional[str])

  • monotonic_y (Optional[Union[bool, str]])

  • user_splits_y (Optional[List])

  • special_codes_y (Optional[List])

  • dtype_y (str)

  • x_params (Optional[Dict])

  • y_params (Optional[Dict])

  • missing_separate (bool)

  • missing_separate_x (Optional[bool])

  • missing_separate_y (Optional[bool])

  • random_state (Optional[int])

  • decimal (int)

  • woe_clip (Optional[float])

  • verbose (Union[bool, int])

  • n_jobs (int | float | None)

  • parallel_backend (str | None)

  • parallel_config (Mapping[str, Any] | None)

  • user_splits_fixed_x (Optional[Union[bool, List[bool]]])

  • user_splits_fixed_y (Optional[Union[bool, List[bool]]])

artifact_kind = '分箱器'
export_rules()[源代码]

导出分箱规则.

与 OptimalBinning.export_rules 保持一致。数值规则中的 np.nan 位置只表示 缺失值归属的普通箱;独立 -1 缺失箱由 missing_separate 配置表达。

返回:

分箱规则字典,格式同 OptimalBinning.export_rules

返回类型:

Dict[str, List]

参考样例

>>> binner = OptimalBinning2D()
>>> binner.fit(df, y=df['target'], features=['age', 'income'])
>>> rules = binner.export_rules()
>>> print(rules['age'])      # [25, 35, 45]
>>> print(rules['income'])   # [5000, 10000, 20000]
fit(X, y=None, features=None)[源代码]

在干净候选对象上完整拟合并于成功后一次提交。

参数:
  • X (DataFrame | ndarray)

  • y (ndarray | Series | None)

  • features (List[str] | None)

返回类型:

OptimalBinning2D

get_bad_rate_matrix()[源代码]

获取坏样本率矩阵(用于热力图).

返回类型:

DataFrame

get_bin_table(feature=None)[源代码]

获取分箱统计表.

与 OptimalBinning 的 get_bin_table 保持一致。 - 若指定特征名,返回该特征的独立分箱表(等同于 OptimalBinning.get_bin_table) - 若不指定(默认 None),返回合并后的二维分箱表

参数:

feature (str | None) -- 特征名,None 时返回交叉分箱表

返回:

分箱统计表

返回类型:

DataFrame

参考样例

>>> binner = OptimalBinning2D()
>>> binner.fit(df, y=df['target'], features=['age', 'income'])
>>>
>>> # 获取交叉分箱表(默认)
>>> cross = binner.get_bin_table()
>>>
>>> # 获取特征1的分箱表
>>> table_x = binner.get_bin_table(binner.feature_x_)
get_count_matrix()[源代码]

获取样本数矩阵(用于热力图标注).

返回类型:

DataFrame

get_cross_table()[源代码]

获取二维交叉分箱统计表.

返回:

交叉分箱统计表,包含以下列: - 分箱, 分箱标签: 最终二维分箱索引和标签 - 特征1名称, 特征2名称: 特征名 - 特征1分箱, 特征2分箱: 单特征分箱索引 - 特征1标签, 特征2标签: 单特征分箱标签 - 样本总数, 好样本数, 坏样本数: 样本统计 - 坏样本率: 坏样本占比 - 样本占比: 交叉区间样本占全量样本的比例 - 分档WOE值, 分档IV值: WOE/IV统计 - LIFT值: 提升度

返回类型:

DataFrame

get_feature_names_out(input_features=None)[源代码]

返回二维交叉分箱转换后的特征名.

返回类型:

ndarray

get_iv_matrix()[源代码]

获取 IV 值矩阵.

返回类型:

DataFrame

get_lift_matrix()[源代码]

获取 LIFT 值矩阵.

返回类型:

DataFrame

get_marginal_stats()[源代码]

获取边缘分箱统计(各特征独立分箱的统计).

返回类型:

Dict[str, DataFrame]

get_splits(feature=None)[源代码]

获取切分点.

与 OptimalBinning 的 get_splits 保持一致。

参数:

feature (str | None) -- 特征名,None 时返回两个特征的切分点字典

返回:

切分点数组或字典

返回类型:

ndarray | Dict[str, ndarray]

参考样例

>>> binner = OptimalBinning2D()
>>> binner.fit(df, y=df['target'], features=['age', 'income'])
>>>
>>> # 获取两个特征的切分点
>>> splits = binner.get_splits()
>>> print(splits['age'])
>>> print(splits['income'])
>>>
>>> # 获取单个特征切分点
>>> splits_x = binner.get_splits(binner.feature_x_)
get_stats(feature=None)[源代码]

获取分箱统计信息.

与 OptimalBinning 的 get_stats 保持一致。

参数:

feature (str | None) -- 特征名,None 时返回两个特征的统计字典

返回:

统计信息字典 - 'n_bins': 分箱数 - 'bin_table': 分箱统计表 - 'iv': IV值 - 'ks': KS值

返回类型:

Dict[str, Any]

参考样例

>>> binner = OptimalBinning2D()
>>> binner.fit(df, y=df['target'], features=['age', 'income'])
>>>
>>> # 获取两个特征的统计
>>> stats = binner.get_stats()
>>> for feat, s in stats.items():
...     print(f"{feat}: IV={s.get('iv', 'N/A'):.4f}")
>>>
>>> # 获取单个特征统计
>>> s = binner.get_stats(binner.feature_x_)
get_woe_matrix()[源代码]

获取 WOE 值矩阵.

返回类型:

DataFrame

import_rules(rules)[源代码]

导入分箱规则.

参数:

rules (Dict[str, List]) -- 分箱规则字典,格式同 export_rules

返回:

self

返回类型:

OptimalBinning2D

参考样例

>>> rules = {'age': [25, 35, 45], 'income': [5000, 10000]}
>>> binner = OptimalBinning2D(user_splits_x=[25, 35, 45],
...                          user_splits_y=[5000, 10000])
>>> # 先 fit(用于初始化结构),再 import_rules 覆盖切分点
>>> binner.fit(df, y=df['target'], features=['age', 'income'])
>>> binner.import_rules(rules)
plot(metric='bad_rate', figsize=None, cmap=None, annot=True, fmt='.2%', title=None, xlabel=None, ylabel=None, save=None, ax=None, **kwargs)[源代码]

绘制二维分箱热力图.

参数:
  • metric (Literal['bad_rate', 'woe', 'iv', 'lift', 'count']) -- 显示指标,可选 'bad_rate'(默认)、'woe'、'iv'、'lift'、'count'

  • figsize (tuple | None) -- 图像尺寸

  • cmap (str | None) -- 配色方案

  • annot (bool) -- 是否在热力图中显示数值

  • fmt (str) -- 数值格式

  • title (str | None) -- 图表标题

  • xlabel (str | None) -- X轴标签

  • ylabel (str | None) -- Y轴标签

  • save (str | None) -- 保存路径

  • ax (Any | None) -- 可选的 matplotlib Axes 对象

  • kwargs -- 其他参数传递给 seaborn.heatmap

返回:

matplotlib Figure 或 Axes

返回类型:

Any

plot2d(figsize=None, colors=None, title=None, annot=True, fontsize=10, save=None)[源代码]

快捷绘制二维分箱联合分析图.

该方法等价于 hscredit.core.viz.bin_2d_plot(self, ...)

参数:
  • figsize (tuple | None) -- 图像尺寸

  • colors (List[str] | None) -- 配色方案

  • title (str | None) -- 图表总标题

  • annot (bool) -- 热力图是否标注数值

  • fontsize (int) -- 单元格字体大小

  • save (str | None) -- 保存路径

返回:

matplotlib Figure

返回类型:

Any

plot_3d(metric='bad_rate', figsize=None, title=None, save=None, **kwargs)[源代码]

绘制三维表面图展示交互效应.

参数:
  • metric (Literal['bad_rate', 'woe', 'lift'])

  • figsize (tuple | None)

  • title (str | None)

  • save (str | None)

返回类型:

Any

transform(X, metric='indices')[源代码]

将新数据映射到二维分箱.

参数:
  • X (DataFrame | ndarray) -- 待转换的数据

  • metric (Literal['indices', 'bins', 'woe', 'event_rate']) -- 转换类型,可选值: - 'indices': 返回合并后的二维分箱索引 (0, 1, 2, ...),默认 - 'bins': 返回合并后的二维分箱标签 - 'woe': 返回合并后的 WOE 值 - 'event_rate': 返回合并后的坏样本率

返回:

转换后的数据

返回类型:

DataFrame

参考样例

>>> binner = OptimalBinning2D()
>>> binner.fit(df, y=df['target'], features=['age', 'income'])
>>>
>>> # 获取分箱索引
>>> X_binned = binner.transform(X_test, metric='indices')
>>>
>>> # 获取分箱标签
>>> X_labels = binner.transform(X_test, metric='bins')
>>>
>>> # 获取 WOE 编码
>>> X_woe = binner.transform(X_test, metric='woe')