4、特征分箱技术:等距分箱、等频分箱、卡方分箱、决策树分箱、分箱后的WOE与IV计算
特征分箱(Binning)是将连续变量离散化或将多状态离散变量合并为少数几个区间(箱)的过程。在风控模型中,分箱不仅是数据预处理步骤,更是提升模型稳定性、处理非线性关系、增强可解释性的核心手段。本章系统讲解四种主流分箱方法及其后续的WOE与IV计算。
4.1 分箱的核心价值与评估标准
一个好的分箱方案应同时满足以下标准:
- 单调性:坏账率(Bad Rate)随分箱顺序单调递增或递减,符合业务逻辑。
- 区分度:各箱之间的坏账率差异显著,IV值贡献高。
- 稳定性:分箱边界在时间序列上保持稳定,不易受极端值影响。
- 业务可解释:分箱边界为整数或常见阈值,便于风控策略落地。
实践提示:分箱并非越细越好。过细的分箱会导致过拟合,且WOE值波动剧烈;过粗的分箱则会损失信息量。通常建议每箱至少包含5%的样本,且箱数控制在5~10箱之间。
4.2 等距分箱(Equal Width Binning)
等距分箱将特征值域划分为宽度相等的K个区间。其核心逻辑是:区间宽度 = (最大值 - 最小值) / K。
4.2.1 算法步骤
- 确定分箱数量K(通常为5~10)。
- 计算区间宽度
width = (max - min) / K。 - 生成边界点:
min + width,min + 2*width, ... - 将每个样本分配到对应的区间。
4.2.2 优缺点对比
| 维度 | 优点 | 缺点 |
|---|---|---|
| 实现难度 | 非常简单,计算量小 | 对异常值敏感,极端值会拉宽区间 |
| 分布适应性 | 均匀分布时效果较好 | 长尾分布下中间箱样本稀疏,两端箱样本集中 |
| 单调性 | 不保证单调性 | 需手动调整或合并 |
避坑指南:等距分箱在风控中通常仅作为初始分箱或快速探索使用。若特征存在极端值(如收入特征中个别超高收入),建议先做截尾处理(Winsorize)再进行等距分箱。
4.3 等频分箱(Equal Frequency Binning)
等频分箱确保每个箱中包含大致相同数量的样本。其核心逻辑是:按特征值排序后,以分位数作为边界。
4.3.1 算法步骤
- 确定分箱数量K。
- 计算每个箱的样本数
n_per_bin = N / K。 - 按特征值升序排列,取第
n_per_bin,2*n_per_bin, ... 个样本的特征值作为边界。 - 处理重复值:若边界点存在大量重复值,需合并相同值的箱。
4.3.2 优缺点对比
| 维度 | 优点 | 缺点 |
|---|---|---|
| 样本分布 | 各箱样本均衡,统计量稳定 | 相同特征值可能被分到不同箱,造成逻辑混乱 |
| 异常值处理 | 对异常值不敏感 | 边界可能落在密集值域内,导致相邻箱差异小 |
| 单调性 | 不保证单调性 | 需后续合并调整 |
应用场景:等频分箱常用于评分卡建模的初始分箱步骤,尤其适用于分布未知或偏态严重的特征。后续通常结合卡方分箱或决策树分箱进行合并优化。
4.4 卡方分箱(Chi-Merge Binning)
卡方分箱是一种自底向上的监督分箱方法。它通过卡方检验评估相邻两个箱的类别分布是否独立,若独立则合并,否则保留。其核心思想是:合并后应保持箱内样本的坏账率尽可能一致,而箱间差异尽可能大。
4.4.1 算法步骤
- 初始化:将每个不同特征值作为一个单独的箱(或先做等频预分箱)。
- 计算卡方值:对每对相邻箱,计算卡方统计量:
χ² = Σᵢ Σⱼ (Oᵢⱼ - Eᵢⱼ)² / Eᵢⱼ 其中: - i = 1,2 表示两个相邻箱 - j = 1,2 表示好/坏标签 - Oᵢⱼ = 第i箱中第j类的实际频数 - Eᵢⱼ = 第i箱中第j类的期望频数 = (行合计 × 列合计) / 总样本 - 合并:合并卡方值最小(即最不显著)的相邻箱对。
- 迭代:重复步骤2~3,直到所有相邻箱对的卡方值均大于显著性阈值(如0.05),或达到预设箱数。
4.4.2 卡方分箱流程
参数建议:卡方显著性阈值通常设为0.05~0.10。阈值越小,合并越保守,最终箱数越多;阈值越大,合并越激进,箱数越少。建议结合IV值变化曲线选择最优阈值。
4.5 决策树分箱(Decision Tree Binning)
决策树分箱利用单变量决策树(CART)的递归二分思想,以目标变量(好坏标签)作为监督信息,自动寻找最优切分点。其核心优势是天然保证分箱后的坏账率单调性(若树结构允许)。
4.5.1 算法步骤
- 训练单变量决策树:以当前特征为唯一输入,好坏标签为目标,设置最大深度(如3~5层)和最小叶子节点样本数(如总样本的5%)。
- 提取切分点:从树结构中提取所有内部节点的切分值,作为分箱边界。
- 生成分箱:按切分点将特征值域划分为多个区间。
- 后处理合并:若相邻箱的坏账率差异不显著(如卡方检验p值>0.05),则合并。
4.5.2 决策树分箱与卡方分箱对比
| 对比维度 | 决策树分箱 | 卡方分箱 |
|---|---|---|
| 分箱方向 | 自顶向下(分裂) | 自底向上(合并) |
| 切分准则 | 基尼系数 / 信息增益 | 卡方统计量 |
| 单调性保证 | 通过限制树结构可保证 | 不保证,需后处理 |
| 计算效率 | 较高(O(n log n)) | 较低(需多次迭代合并) |
| 过拟合风险 | 较高(需控制树深度) | 较低(合并过程天然正则化) |
实践建议:在风控评分卡建模中,通常采用“等频预分箱 → 卡方合并 → 决策树精调”的混合策略。先用等频分箱将特征粗分为20~50箱,再用卡方分箱合并至10~15箱,最后用决策树分箱验证并微调边界。
4.6 分箱后的WOE与IV计算
分箱完成后,需要计算每个箱的WOE(Weight of Evidence,证据权重)和整体特征的IV(Information Value,信息量),以评估分箱效果和特征预测能力。
4.6.1 WOE计算公式
WOEᵢ = ln( (Goodᵢ / Good_total) / (Badᵢ / Bad_total) )
= ln( 好样本占比 / 坏样本占比 )
其中:
- Goodᵢ = 第i箱中的好样本数
- Badᵢ = 第i箱中的坏样本数
- Good_total = 总好样本数
- Bad_total = 总坏样本数
4.6.2 IV计算公式
IV = Σᵢ ( (Goodᵢ / Good_total) - (Badᵢ / Bad_total) ) × WOEᵢ
即:IV = Σᵢ (好样本占比 - 坏样本占比) × WOEᵢ
4.6.3 WOE与IV的典型分箱结果示例
| 分箱区间 | 样本数 | 好样本数 | 坏样本数 | 坏账率 | WOE | IV贡献 |
|---|---|---|---|---|---|---|
| [0, 30) | 2000 | 1800 | 200 | 10.0% | 0.2877 | 0.0288 |
| [30, 45) | 3000 | 2550 | 450 | 15.0% | 0.0000 | 0.0000 |
| [45, 60) | 2500 | 2000 | 500 | 20.0% | -0.2877 | 0.0288 |
| [60, +∞) | 1500 | 1050 | 450 | 30.0% | -0.6931 | 0.0693 |
| 合计 | 9000 | 7400 | 1600 | 17.8% | — | 0.1269 |
4.6.4 IV值评估标准
| IV值范围 | 预测能力 | 风控建议 |
|---|---|---|
| < 0.02 | 无预测能力 | 建议剔除 |
| 0.02 ~ 0.10 | 弱预测能力 | 可保留,但需结合业务判断 |
| 0.10 ~ 0.30 | 中等预测能力 | 推荐入模 |
| 0.30 ~ 0.50 | 强预测能力 | 优先入模 |
| > 0.50 | 可疑(可能过强) | 需检查是否与目标变量存在直接逻辑关系 |
4.7 分箱后WOE的单调性检查
WOE的单调性是评分卡模型可解释性的基石。若WOE值随分箱顺序呈现“先升后降”或“波动”形态,说明分箱方案可能存在问题。
4.7.1 单调性检查流程
常见问题:若WOE出现“倒U型”或“U型”分布,通常意味着特征与目标变量存在非线性关系。此时可考虑:① 将特征拆分为两个子特征分别建模;② 使用多项式特征变换;③ 接受非线性关系但改用树模型。
4.8 分箱后的代码实现示例
以下Python代码展示了使用scipy和pandas实现等频分箱、卡方分箱及WOE/IV计算的完整流程:
import pandas as pd
import numpy as np
from scipy.stats import chi2_contingency
def equal_freq_binning(x, n_bins=10):
"""等频分箱"""
quantiles = np.linspace(0, 1, n_bins + 1)
bins = x.quantile(quantiles).values
# 处理重复边界
bins = np.unique(bins)
return pd.cut(x, bins=bins, include_lowest=True)
def chi_merge_binning(x, y, max_bins=10, significance=0.05):
"""卡方分箱(简化版)"""
# 初始分箱:每个唯一值作为一箱
df = pd.DataFrame({'x': x, 'y': y})
df['bin'] = x
bins = sorted(df['bin'].unique())
while len(bins) > max_bins:
chi_values = []
for i in range(len(bins) - 1):
# 取相邻两箱
mask1 = df['bin'] == bins[i]
mask2 = df['bin'] == bins[i+1]
group1 = df[mask1]['y'].value_counts()
group2 = df[mask2]['y'].value_counts()
# 构建列联表
contingency = pd.DataFrame({
'bin1': group1,
'bin2': group2
}).fillna(0).T
# 卡方检验
chi2, p, _, _ = chi2_contingency(contingency)
chi_values.append((chi2, p, i))
# 找到p值最大的相邻箱对(最不显著)
chi_values.sort(key=lambda x: x[1], reverse=True)
_, max_p, merge_idx = chi_values[0]
if max_p > significance:
# 合并
merged_val = f"{bins[merge_idx]}_{bins[merge_idx+1]}"
df.loc[df['bin'].isin([bins[merge_idx], bins[merge_idx+1]]), 'bin'] = merged_val
bins = sorted(df['bin'].unique())
else:
break
return df['bin']
def calc_woe_iv(df, feature, target):
"""计算WOE和IV"""
total_good = df[target].sum()
total_bad = len(df) - total_good
result = df.groupby(feature).agg(
total=(target, 'count'),
bad=(target, 'sum')
).reset_index()
result['good'] = result['total'] - result['bad']
result['good_pct'] = result['good'] / total_good
result['bad_pct'] = result['bad'] / total_bad
result['bad_rate'] = result['bad'] / result['total']
result['WOE'] = np.log(result['good_pct'] / result['bad_pct'])
result['IV_contrib'] = (result['good_pct'] - result['bad_pct']) * result['WOE']
iv = result['IV_contrib'].sum()
return result, iv
# 使用示例
# df['bin'] = chi_merge_binning(df['feature'], df['target'], max_bins=8)
# bin_result, iv_value = calc_woe_iv(df, 'bin', 'target')
# print(f"特征IV值: {iv_value:.4f}")
关键总结:特征分箱是风控建模中连接数据预处理与模型可解释性的桥梁。等距分箱和等频分箱提供初始划分,卡方分箱和决策树分箱利用监督信息优化边界。分箱后的WOE计算将原始特征转换为线性尺度,IV值则量化特征预测能力。一个优秀的分箱方案应同时满足单调性、区分度、稳定性和业务可解释性四个标准。