4. 决策树分箱:用单变量决策树找最优切分点

等频分箱简单,但容易把密集区域的边界切在数据稀疏处。等距分箱更粗暴,碰到长尾分布直接废掉。那有没有一种方法,能自动从数据本身挖出最合理的切分点?

有。决策树分箱。

说白了,就是用一棵单变量决策树,只拿一个特征去拟合目标变量。树在分裂过程中选出的每个分裂阈值,就是天然的最优分箱边界。我刚开始做信用评分建模时,就靠这招解决了连续变量与坏账率之间的非线性映射问题——效果比手工调箱好太多了。

4.1 核心思路:树怎么帮你切箱子

想象你有一列年龄:18, 25, 30, 35, 45, 60。目标变量是“是否逾期”。你手动切个区间[18,30)、(30,50)、(50,60],凭什么?凭直觉。但决策树不凭直觉,它遍历每个候选切点,计算分裂后的纯度增益(比如信息增益或基尼系数),挑出增益最大的那个点。

单变量决策树只用一个特征(比如年龄)去拟合目标。树在每个节点尝试所有可能的切分阈值,选最优的那个。最终,树的所有内部节点的分裂阈值,就是我们需要的分箱边界。

关键点:决策树分箱本质是监督式离散化。它直接利用目标变量的信息来做切分,比无监督的等频/等距更“聪明”。

不过,树一旦不控制深度,就会疯狂分裂,把每个样本点都切成一个箱子——那就彻底过拟合了。所以下文讲的技巧才是核心。

4.2 实战步骤:从训练到取箱子

我一般按下面四步走,每一步都有要注意的坑。

  1. 准备数据:只拿一个特征(比如“余额”)和标签(是否流失)。缺失值提前处理,我用中位数填充。
  2. 训练单变量决策树:用DecisionTreeClassifier或DecisionTreeRegressor,限制最大深度(我常用3~5),设置最小样本分裂数(比如50)。
  3. 提取分裂阈值:遍历树的tree_.threshold属性,拿到所有内部节点的分裂值。
  4. 去重并排序:阈值可能重复,去重后排序,作为分箱边界。

举个例子,下面是我项目里用过的代码片段:

from sklearn.tree import DecisionTreeClassifier
import numpy as np

def decision_tree_bins(feature, target, max_depth=3, min_samples_leaf=50):
    clf = DecisionTreeClassifier(
        max_depth=max_depth,
        min_samples_leaf=min_samples_leaf
    )
    # 特征需要2D
    clf.fit(feature.reshape(-1, 1), target)
    thresholds = np.sort(np.unique(clf.tree_.threshold))
    # 去掉无效值(-2代表叶节点)
    thresholds = thresholds[thresholds != -2]
    return thresholds

# 使用示例
age_bins = decision_tree_bins(df['age'].values, df['bad_flag'].values)
print(age_bins)  # 输出类似 [25. 35. 50.]

这里返回的阈值就是最佳切分点。比如年龄的切分点是25、35、50,那分箱就是[ -inf, 25)、[25,35)、[35,50)、[50, +inf)。

4.3 过拟合:树切得太细怎么办

决策树分箱最大的敌人就是过拟合。树深度一上去,箱子会切得非常碎,甚至每个箱子只包含几个样本。测试集上一验证,效果直线下降。

我踩过一个坑:有一次做信用卡逾期预测,用决策树分箱对“近6月消费金额”做离散化,没限制深度,树自动切了30多个箱子。结果训练集AUC 0.87,验证集只有0.71——惨不忍睹。后来加了深度限制和最小样本数,箱子降到6个,验证集AUC反而升到0.80。

避坑指南:我曾经用min_samples_leaf=1默认参数跑分箱,结果箱子数和样本数一样多。那种分箱没有任何泛化能力。记住:分箱的目的是压缩信息,不是记忆样本。

下面四个技巧是我常用的防过拟合手段:

技巧 做法 推荐值
限制最大深度 max_depth设为3~6 4
提高最小叶节点样本数 min_samples_leaf设为总样本的1%~5% 50~200
限制最小分裂样本数 min_samples_split设为总样本的2%~10% 100
后剪枝(手动合并小箱子) 观察每个箱子的样本量,合并少于阈值的小箱 合并样本数<30的箱

提示:如果业务方要求箱子数固定(比如5个),你可以先调max_depth让树自动生成接近这个数量的箱子,再手动合并极小的边角箱。

4.4 决策树分箱完整流程图

下面的SVG图展示了一个单变量决策树分箱的完整流程,从输入特征到输出分箱列表:

决策树分箱流程图(单变量) 特征 X + 标签 Y 训练单变量决策树 提取 tree_.threshold 去重 + 排序 生成分箱边界列表 防过拟合技巧 • max_depth=3~5 • min_samples_leaf≥50 • min_samples_split≥100 • 手动合并小箱子

4.5 和等频/等距分箱对比

选哪种分箱方法,取决于你的数据特点和项目阶段。我这里列个对比表,方便你快速判断:

对比维度 等频分箱 等距分箱 决策树分箱
是否使用目标变量 否 否 是
对长尾分布适应性 较好 很差 好
过拟合风险 低 低 较高(需限制参数)
箱子数量控制 固定(需提前设定) 固定 自动,可调参数约束
单调性保障 不保证 不保证 不保证(但可结合单调性约束)
计算耗时 快 快 稍慢(需树训练)
最佳使用场景 探索分析和基线模型 均匀分布特征 强非线性关系,追求最优分箱

4.6 我的个人经验补充

再分享两个小经验:

  • 别一次对太多特征做决策树分箱。我在一个50特征的项目里,每个特征都单独训练一棵树,结果数据预处理时间比模型训练还长。后来我只对top-10重要特征用决策树分箱,其余用等频——平衡了效果和效率。
  • 分完箱后一定要检查woe或bin的单调性。决策树分箱不保证单调,如果业务方要求“余额越高,流失率越低”,你得手动合并那些违反单调方向的箱子,或者改用带单调约束的决策树分箱(可以用LightGBM的单调约束做替代方案,那是后面章节的内容)。

一句话总结:决策树分箱是监督分箱的利器,但必须用深度和样本数这两根缰绳勒住它。缰绳松了,它就变成记忆大师;缰绳紧了,它才能成为你的好帮手。