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 算法步骤

  1. 确定分箱数量K(通常为5~10)。
  2. 计算区间宽度 width = (max - min) / K。
  3. 生成边界点:min + width, min + 2*width, ...
  4. 将每个样本分配到对应的区间。

4.2.2 优缺点对比

维度 优点 缺点
实现难度 非常简单,计算量小 对异常值敏感,极端值会拉宽区间
分布适应性 均匀分布时效果较好 长尾分布下中间箱样本稀疏,两端箱样本集中
单调性 不保证单调性 需手动调整或合并
避坑指南:等距分箱在风控中通常仅作为初始分箱或快速探索使用。若特征存在极端值(如收入特征中个别超高收入),建议先做截尾处理(Winsorize)再进行等距分箱。

4.3 等频分箱(Equal Frequency Binning)

等频分箱确保每个箱中包含大致相同数量的样本。其核心逻辑是:按特征值排序后,以分位数作为边界。

4.3.1 算法步骤

  1. 确定分箱数量K。
  2. 计算每个箱的样本数 n_per_bin = N / K。
  3. 按特征值升序排列,取第 n_per_bin, 2*n_per_bin, ... 个样本的特征值作为边界。
  4. 处理重复值:若边界点存在大量重复值,需合并相同值的箱。

4.3.2 优缺点对比

维度 优点 缺点
样本分布 各箱样本均衡,统计量稳定 相同特征值可能被分到不同箱,造成逻辑混乱
异常值处理 对异常值不敏感 边界可能落在密集值域内,导致相邻箱差异小
单调性 不保证单调性 需后续合并调整
应用场景:等频分箱常用于评分卡建模的初始分箱步骤,尤其适用于分布未知或偏态严重的特征。后续通常结合卡方分箱或决策树分箱进行合并优化。

4.4 卡方分箱(Chi-Merge Binning)

卡方分箱是一种自底向上的监督分箱方法。它通过卡方检验评估相邻两个箱的类别分布是否独立,若独立则合并,否则保留。其核心思想是:合并后应保持箱内样本的坏账率尽可能一致,而箱间差异尽可能大。

4.4.1 算法步骤

  1. 初始化:将每个不同特征值作为一个单独的箱(或先做等频预分箱)。
  2. 计算卡方值:对每对相邻箱,计算卡方统计量:
    χ² = Σᵢ Σⱼ (Oᵢⱼ - Eᵢⱼ)² / Eᵢⱼ
    其中:
    - i = 1,2 表示两个相邻箱
    - j = 1,2 表示好/坏标签
    - Oᵢⱼ = 第i箱中第j类的实际频数
    - Eᵢⱼ = 第i箱中第j类的期望频数 = (行合计 × 列合计) / 总样本
  3. 合并:合并卡方值最小(即最不显著)的相邻箱对。
  4. 迭代:重复步骤2~3,直到所有相邻箱对的卡方值均大于显著性阈值(如0.05),或达到预设箱数。

4.4.2 卡方分箱流程

卡方分箱(Chi-Merge)流程图 初始分箱(等频预分箱) 计算相邻箱对的卡方统计量 最小卡方值 < 阈值? 是 合并卡方值最小的相邻箱 否 输出最终分箱
参数建议:卡方显著性阈值通常设为0.05~0.10。阈值越小,合并越保守,最终箱数越多;阈值越大,合并越激进,箱数越少。建议结合IV值变化曲线选择最优阈值。

4.5 决策树分箱(Decision Tree Binning)

决策树分箱利用单变量决策树(CART)的递归二分思想,以目标变量(好坏标签)作为监督信息,自动寻找最优切分点。其核心优势是天然保证分箱后的坏账率单调性(若树结构允许)。

4.5.1 算法步骤

  1. 训练单变量决策树:以当前特征为唯一输入,好坏标签为目标,设置最大深度(如3~5层)和最小叶子节点样本数(如总样本的5%)。
  2. 提取切分点:从树结构中提取所有内部节点的切分值,作为分箱边界。
  3. 生成分箱:按切分点将特征值域划分为多个区间。
  4. 后处理合并:若相邻箱的坏账率差异不显著(如卡方检验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单调性检查与调整流程 计算各箱WOE值 检查WOE是否单调 是 分箱方案通过 否 合并相邻箱 / 调整边界
常见问题:若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值则量化特征预测能力。一个优秀的分箱方案应同时满足单调性、区分度、稳定性和业务可解释性四个标准。