4. 等距分箱方法:原理与实现
等距分箱,说白了就是把特征的取值范围切成等宽的几段。你想想看,给年龄分箱,0~100岁,切5箱,那每箱就是20岁。0~20、20~40、40~60、60~80、80~100。简单粗暴,对吧?
我在项目里碰到过不少新手,一上手就想用复杂的卡方分箱或决策树分箱。其实很多时候,等距分箱就是那个最省事、最不容易出错的基线方案。尤其是特征分布比较均匀、业务上又没明显自然分割点时,我建议先用等距分箱试试水。
4.1 原理:等距的核心逻辑
等距分箱的数学定义就一句话:把特征值范围 [min, max] 等分成 k 个区间,每个区间宽度 = (max - min) / k。
听起来像废话?但这里面有个隐藏假设:特征值本身是有实际意义的,而且业务场景允许你忽略数据稀疏问题。比如年龄、额度、月份这些连续量,天然适合等距。但如果你要对「用户评分」这种偏态分布用等距分箱……嗯,那很可能大部分样本都挤在同一个箱子里,其他箱子近乎空箱。那样分箱就失去意义了。
4.2 实现步骤
我个人习惯按下面几步走:
- 找出特征的最小值和最大值。记得检查是否有异常值,尤其是那些离谱的极大值。
- 确定箱数 k。没有硬性规则,一般取5~20箱。信用评分卡里常见的是10~15箱。
- 计算区间宽度:
width = (max - min) / k。 - 生成分割点:
min + width、min + 2*width……直到max。 - 用分割点将样本映射到各个箱子。
步骤很简单,但我曾经踩过一个坑:直接用 cut() 时,如果特征值正好等于某个分割点,pandas 默认是左闭右开区间,容易把边界值分到错误的箱子里。后面我会给你展示怎么处理。
right=False 或 include_lowest=True。我更喜欢显式自己定义 bins 列表,然后手动控制左闭右闭。
4.3 Python 实现
直接上代码。下面这个函数实现了等距分箱,并返回每个样本的箱号、箱区间标签以及箱的统计信息。
import numpy as np
import pandas as pd
def equal_width_binning(data, feature, k=10, right=True, precision=2):
"""
等距分箱
:param data: DataFrame
:param feature: 特征名称
:param k: 箱数
:param right: 区间是否右闭
:param precision: 标签小数位数
:return: DataFrame (增加分箱标签列), bins 列表
"""
s = data[feature].dropna()
min_val, max_val = s.min(), s.max()
# 避免因数值精度导致的边界问题,略扩展一点
eps = 1e-10
bins = np.linspace(min_val - eps, max_val + eps, k + 1)
# 生成标签
labels = []
for i in range(k):
left = round(bins[i], precision)
right_b = round(bins[i+1], precision)
if right:
labels.append(f'({left}, {right_b}]')
else:
labels.append(f'[{left}, {right_b})')
# 分箱
data['bin_' + feature] = pd.cut(data[feature], bins=bins, labels=labels, right=right, include_lowest=True)
# 统计每箱样本数(可选)
stats = data.groupby('bin_' + feature)[feature].agg(['min', 'max', 'count']).reset_index()
return data, bins, stats
# 示例使用
df = pd.DataFrame({'age': [22, 35, 48, 55, 64, 72, 81, 19, 27, 33, 45, 59, 68, 77, 85]})
df_result, bins, stats = equal_width_binning(df, 'age', k=5)
print(stats)
上面的代码里,我用 eps 把最小值往左挪了一点、最大值往右挪了一点,这样就避免了样本落在 bins 边界之外。你想想看,假如最小年龄正好是22,而左边界的 min_val 也是22,不加 eps 的话 22 这个值就会被 cut 排除在外(因为默认左开)。这个小技巧是我从业务上线后排查坏账时发现的,当时亏了我整整一下午。
4.4 等距分箱的优缺点
| 优点 | 缺点 |
|---|---|
| 实现简单,代码就几行 | 对异常值敏感,一个超大离群点会把整个区间拉宽 |
| 分箱结果可解释性强 | 数据分布不均匀时有些箱子可能极稀疏 |
| 计算效率高,适合大样本 | 无法自动适应数据的分割点(比如业务天然拐点) |
| 与其他分箱方法比较的天然基线 | 信用评分场景下通常不是最优分箱方式 |
4.5 等距分箱过程图解
下面这张图把整个流程走了一遍,从原始数据到分箱结果。你看着它,再对照代码,应该就能理解了。
4.6 什么时候用等距分箱?
我个人的经验是:在信用评分卡项目初期,特征勘探阶段,我会用等距分箱快速看每个连续变量与坏账率的单调性关系。
- 如果等距分箱后每个箱的样本数都大于500,而且坏账率单调递增或递减,那这个特征基本合格。
- 如果某个箱子样本数小于100,我会标记为「等距不适用」,换成等频或卡方分箱试试。
这么做的好处是你不用花时间调参,五分钟就能筛一遍所有候选特征。等确定候选集以后,再对每个特征用更精细的分箱方法去优化。