2. 等距分箱:原理、实现步骤、优缺点与Python代码
等距分箱(Equal-Width Binning)是最直观的连续变量离散化方法。它将变量的取值范围均匀划分为 k 个等宽的区间,每个区间内的样本被赋予相同的类别标签。该方法不依赖目标变量,属于无监督分箱。
2.1 等距分箱原理
假设连续变量 x 的最小值为 min,最大值为 max,计划分为 k 个区间。则每个区间的宽度 w 为:
w = (max - min) / k
第 i 个区间的边界为:
[min + (i-1)*w, min + i*w), i = 1, 2, ..., k
最后一个区间为闭区间 [min + (k-1)*w, max]。
核心思想: 将数值域均匀切分,使每个区间在数值尺度上长度相等,但区间内样本数量可能差异很大。
2.2 实现步骤
- 确定区间数 k:根据业务经验或探索性分析设定,常用值如 5、10、20。
- 计算区间宽度 w:
w = (max - min) / k。 - 划分边界:从最小值开始,依次加上宽度 w,生成 k+1 个边界点。
- 分配样本:将每个样本值落入的区间编号作为分箱结果。
- 编码转换:通常将区间映射为整数标签(0, 1, …, k-1)或区间标签(如 “[0-10]”)。
2.3 优缺点分析
| 维度 | 说明 |
|---|---|
| 优点 |
|
| 缺点 |
|
避坑提示: 当数据存在长尾分布或离群点时,等距分箱容易产生大量空箱。建议先做截尾处理(如 1% 和 99% 分位数截断)再分箱。
2.4 等距分箱流程示意图
2.5 Python 代码实现:使用 pandas.cut
pandas.cut 是 Python 中实现等距分箱的标准函数。以下示例展示完整流程:
import pandas as pd
import numpy as np
# 生成示例数据:100个年龄值,范围18~75
np.random.seed(42)
ages = np.random.randint(18, 76, size=100)
# 等距分箱:分为5个区间
k = 5
bins_labels = ['青年', '中青年', '中年', '中老年', '老年']
# 使用 cut 进行等距分箱
age_bins = pd.cut(ages, bins=k, labels=bins_labels, include_lowest=True)
# 查看分箱结果
df = pd.DataFrame({'年龄': ages, '年龄段': age_bins})
print(df.head(10))
# 查看各区间样本分布
print("\n各区间样本数:")
print(df['年龄段'].value_counts().sort_index())
输出示例:
年龄 年龄段
0 56 中老年
1 69 老年
2 46 中年
3 32 中青年
4 60 中老年
5 25 中青年
6 37 中青年
7 27 中青年
8 54 中老年
9 22 中青年
各区间样本数:
青年 8
中青年 24
中年 22
中老年 24
老年 22
Name: 年龄段, dtype: int64
实用技巧: 使用
pd.cut(..., retbins=True) 可返回区间边界值,便于后续复用或可视化。使用 pd.cut(..., right=False) 可控制区间左闭右开。
2.6 等距分箱 vs 等频分箱对比
| 对比维度 | 等距分箱 | 等频分箱 |
|---|---|---|
| 区间宽度 | 相等 | 不等 |
| 各区间样本数 | 可能差异很大 | 大致相等 |
| 对异常值敏感度 | 高 | 低 |
| 业务可解释性 | 好(数值跨度一致) | 较差(边界不规整) |
| 适用场景 | 数据分布均匀、有明确数值含义 | 数据分布偏斜、需要平衡样本 |