ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

决策树核心原理与工程实践:从信息增益到剪枝及缺失值处理

决策树核心原理与工程实践:从信息增益到剪枝及缺失值处理 开学那会儿翻开这本书的目录第四章“决策树”三个字平平无奇我甚至一度觉得它是最没技术含量的一章——不就是if-else嵌套吗直到用Python里的库跑完几个模型的对比又回头啃了两遍这章内容才发现自己错得离谱。纯啃公式的读书笔记太多了这一篇我尽量换个讲法不按原书章节顺序走而是先把“一棵树到底是怎么长出来的”讲明白再回到那些容易被跳过的难点上比如剪枝、连续值、缺失值、多变量树。如果你也是正在啃这本书的初学者或者用了一段时间树模型想看下底层逻辑这篇笔记应该能帮你省不少力气。1. 决策树的核心逻辑一套“先问哪个问题”的分层筛选机制这一节在原书里属于基础铺垫但很多人恰恰是在这里就开始吃夹生饭。决策树的推理逻辑说白了就是一句大白话遇到一个新样本我不知道它属于哪一类就反复问它“你的某个特征是什么”每问一次缩小一圈候选范围最后剩下来的类别就是预测结果。这个过程放到数据结构里就是一棵树。顶部叫根节点中间每个判断点叫内部节点最底部不再继续分叉的叫叶节点每个叶节点对应一个决策结果。整棵树的生成过程是从根节点开始递归地“选属性、分数据、建子树”直到数据被分隔得足够纯或者可用特征用完为止。书中给的基本流程里有两个细节值得圈出来每一个非叶节点只挑一个最优属性划分这个“最优”是局部意义上的最优决策树整体并不保证全局最优。递归终止有三个条件当前节点样本全属于同一类别当前属性集为空或所有样本在剩余属性上取值相同样本集合为空。第三个条件容易被漏掉它对应一种特殊处理——把父节点中样本最多的类别作为叶节点的标记。这种“分而治之”的策略之所以几十年不过时在于它和人类的分类认知高度吻合。我拿生活中最常见的场景举例你妈给你介绍对象对方资料摆在桌上你第一眼看的既不是学历也不是收入而是“在不在一个城市”。见了面看“聊不聊得来”再往下看“有没有存款”。每问一个问题都砍掉一批选项这就是一棵活脱脱的决策树。树模型的强项不是像线性回归那样给出一个光滑的连续打分而是把规则摊开每一步都讲得出理由——所以它在风控、医疗诊断这类需要解释性的场景里依然是主力。这里的原书内容我建议反复读三遍核心不是背流程而是理解“递归”“划分”“纯度”这几个词背后到底对应了什么操作。2. 属性选择到底在优化什么信息熵、信息增益、增益率、基尼系数的来龙去脉如果决策树生成过程是一台机器那“选哪个属性作为当前节点”就是这台机器的发动机。书里真正难啃的第一块硬骨头就在这里——明明叫决策树为什么非要扯上信息论里的“熵”。信息熵这个概念当初也绕了我一阵。你把它理解成不确定性程度就对了。一箱球如果全是红的闭着眼睛猜都能猜对熵为0如果五种颜色各占五分之一猜错概率高熵就大。公式是Ent(D) -Σ p(k) × log2(p(k))其中k是类别下标p(k)是第k类样本占比。这个公式不要求你会推导但要求你能说出一个直觉含义熵越小数据越纯。信息增益说白了就是“划分之前的不确定性”减去“划分之后的不确定性”。Gain(D, a) Ent(D) - Σ(|Dv| / |D| × Ent(Dv))其中v是属性a的各个取值。这个差值越大说明用了这个属性之后类别变得更确定了那它就应该被优先拿来划分。ID3决策树就是按信息增益选属性的。信息增益有个明显毛病——它天然偏好取值数目多的属性。比如你拿样本编号当属性每个编号一个值信息增益直接拉满但这显然毫无泛化能力。为了掰回这种倾向C4.5改成用增益率公式是Gain_ratio(D, a) Gain(D, a) / IV(a)其中IV(a)是属性a的固有值等于 -Σ(|Dv| / |D| × log2(|Dv| / |D|))。取值多的属性IV值通常更大等于给信息增益做了个除法惩罚。但惩罚也不能太狠否则又会偏向取值少的属性所以C4.5的做法是先挑信息增益高于平均水平的属性再从里面选增益率最高的。基尼系数又是另一套思路它不用熵的log运算公式是Gini(D) 1 - Σ p(k)²。直观含义是从数据集里随便抽两个样本它们类别不一致的概率。概率越小数据集越纯。CART决策树就是基于基尼指数来选划分属性的。我曾经在项目里只盯着准确率看对Node上的impurity不纯度指标毫不在意。后来遇到一棵深度夸张的树打印出的结构完全不符合业务直觉回头排查才发现是不同节点用了不同的分裂标准模型库默认的配置和书上写的算法根本对不上。所以我建议你把这些数学指标动手算一遍——取一个20条样本的小表分别用三种指标算同一个属性的得分你就知道它们的结果差在哪了。不亲手算只看公式你永远记不牢。为了更直观这里放一个我当年手工推演的对照小表虚构数据集“天气、温度、是否出门”划分属性信息增益增益率基尼指数按划分后加权均值天气0.2470.2860.350温度0.1070.1390.408选择结论选“天气”若增益率比较仍可能偏向“天气”选“天气”不同指标在大部分简单数据上结论一致但在特征取值数差异很大的数据集上ID3和C4.5会有明显分歧。这也是为什么工程上更常用CART因为它计算快而且后面能直接对接梯度提升框架。3. 剪枝处理为什么树不能任它长到完美在我第一次用默认参数训练决策树时训练集的准确率直逼100%一到测试集立刻掉到刚及格的水平。当时的我把锅甩给数据集太小后来读了剪枝一节才恍然大悟——树长过头了把训练集里的细枝末节全记下来了这种状态叫过拟合。剪枝是决策树对抗噪声和过拟合的主要手段。书里讲了两种思路预剪枝和后剪枝。预剪枝的策略是边构建边剪每次尝试划分一个节点时先用验证集估算一下如果这个划分不做的精度再估算一下做了的精度只有后者更高才允许生成。它可以防止树长得太大减少训练时间但风险在于“只看一步”——当前收益不高不代表后续几步不会带来更大收益。这种贪心式的近视眼可能会导致某些有潜力的分支还没展开就夭折了精度提升有限。后剪枝的策略是先让你把那棵树完整长出来然后自底向上对每个非叶节点做手脚如果把以它为首的分支整个换成一个叶节点验证集精度不降反升那就果断砍掉。这个方案保留了更多分支空间通常比预剪枝更能降低过拟合风险但代价是训练时间明显增加。我曾拿一个中等规模的数据集做过对比用预剪枝生成的树小了一半训练时间少了一大截但测试集精度比后剪枝低了三个多点。可见“懒得多花时间”这种心态在机器学习里经常要付出精度代价。书里还暗示了一个在实际建模时很重要、但写得比较含蓄的点剪枝用的验证集数据会参与“训练”吗严格说验证集参与了模型超参数的选择也就是结构的选择这部分信息依然可能造成一定程度的间接过拟合。很多人在做交叉验证时会忽略这层耦合关系。我的习惯是如果数据量充足预留30%作为最终测试集剪枝只在内部做交叉验证数据量紧张时宁可少剪几刀也要保证测试集是“干净”的。4. 连续值与缺失值处理容易被漏掉的工程细节如果说剪枝是这章最容易丢分的主观题那连续值和缺失值就是最容易被跳过的客观题。很多人学完ID3、C4.5就觉得自己会决策树了一上手遇到“年龄27.5岁”这种连续特征就愣住因为信息增益那套理论默认属性是离散的。书里给的标准解法叫二分法思路极简属性有N个不同取值就排序把相邻取值的中间点作为候选划分点把连续值变成“大于等于这个点”和“小于这个点”两个离散块然后按离散属性去算信息增益。注意连续值特征可以被多次使用不同层次的节点可以在不同切分点上重复利用它这一点和离散属性“用一次就不能再用”完全不同。这一节还有一处对小白尤其不友好就是缺失值的处理。训练集里如果某条样本缺少了当前划分属性上的取值既不能直接扔掉样本太少会浪费信息也不能随便填个均值会引入噪声。书里给出的方案是找划分属性时用无缺失值样本作为子集计算信息增益再按缺失样本比例折算。某个样本在划分属性上缺失时把它按不同权重划分到所有子节点权重和样本落入子节点的比例相关。权重机制贯穿始终每个样本初始权重为1缺失值样本每次划分都按比例更新权重最后被用于叶节点的类别统计。这个机制读起来很容易被绕晕我建议你在纸上画一个只有10条数据的小例子手动走一遍“1号样本缺失颜色特征”时的权重流动过程比看十遍公式都管用。真要在具体库中处理时实现略有差异但思路相同处理好缺失值后模型对比才有意义。5. 从单棵树到一片森林这本书埋下的进阶线索CART树在实践中的使用是深度学习中也会用到的构件。因为任何基于决策树的集成方法除了极少数情况外都需要在每一轮迭代中拟合一棵树这棵树的分裂质量直接决定了集成的上限。所以看第四章的时候多留一个心眼底层逻辑扎实了后面学梯度提升时会顺利得多。在此之前你手头的工具配置就可以先跑通了。装好环境后随便找一个公开的表格数据比如鸢尾花、泰坦尼克用默认参数拟合一棵CART树再打印出树结构图你会对“划分”“纯度”“叶节点样本数”这些词有非常直观的认知。不用急着调参主要为了建立体感让博士式的符号变成看得见的图形。剪枝在库中通常由成本复杂度参数控制数值越大、树被砍得越狠可以简单地把这个参数理解成后剪枝力度的一种实现。这部分再往后就是调参艺术了。6. 多变量决策树线性的根逻辑的叶这一节在初读时很容易被当成“选读内容”掠过但它其实回答了一个关键问题——决策树的分类边界为什么总是横平竖直的普通决策树在每个节点只做单属性判断学到的分类边界是轴平行的也就是和坐标轴垂直的线。如果真实数据的最优边界是斜的普通决策树就尴尬了——它必须用一堆阶梯状的折线去反复逼近那条斜线树深直接翻倍泛化能力自然受影响。多变量决策树的想法是一个节点的划分不用单个属性而用多个属性的线性组合。每个非叶节点维护一组系数相当于在以这些属性为坐标的空间中画一条任意方向的斜线作为边界。这样针对斜向分布的类别树不用长很高就能分开。书的第四章在这里点到为止但对读后续章节很重要因为很多集成模型中的随机特征子空间、线性树等概念都能从这里找到思想源头。我在工作中用到的调参和模型融合方案也是基于这种思路做一些组合特征。比如给决策树喂一些手工构造的“组合后特征”而非原始单特征往往能显著压缩树深度。这也算是多变量树思想在工程里的“穷人手写版”吧。7. 动手实现一版迷你决策树从零开始不长篇大论这章的笔记如果看完就散那确实太可惜了。建议用最精简的方式在十几分钟内把核心跑通我写过一版简化实现核心伪代码如下函数 生成节点(样本集D, 属性集A): 如果 D 全部属于同一类: 返回叶节点 如果 A 为空 或 D 在A上取值相同: 返回叶节点标记为 D 中最多的类 对每个属性 a in A: 计算按 a 划分后的纯度指标 选出最优属性 best_a 创建节点 node标记为 best_a 对 best_a 的每个取值 v: 子集 Dv D 中 best_a v 的样本 如果 Dv 为空: 创建叶节点标记为 D 中最多的类 否则: 递归调用 生成节点(Dv, A \ {best_a})这里最有价值的是条件“D在A上取值相同”。很多人实现时会漏掉它导致递归无限循环——所有样本在剩余属性上完全一样了再往下分已经不可能但代码意识不到还在硬选属性。等你写代码亲自踩一次这个坑就知道书中为什么特意加这个终止条件了。写完这个骨架后再跑一下剪枝对比课堂味和工程味就都有了。8. 笔记之外结合实战的三个提醒很多人在读书笔记阶段非常认真但一到自己的数据集上就陷入“默认参数流”。决策树模型的有效性并不取决于那个“魔力参数”被调得有多准而取决于数据和模型的匹配度。针对树的调优我个人的经验有以下几点树的深度和叶子节点最小样本数比分裂标准对结果影响大得多。设置叶子节点最小样本数可以连续抑制过拟合比每次调裁剪复杂度参数更易解释。特征数值范围敏感度低但特征重要性会被取值多的特征带偏。决策树的信息增益偏好会在真实数据中导致偏差用C4.5思路先算增益均值再选增益率最大往往比直接调默认参数更稳。树模型天然适合处理混合类型特征但前提是把缺失值编码成显式状态而不是全部填成-1或者0。缺失本身可能是重要的信号。书里不会告诉你的是同样的超参数在数据量变化超过一个数量级之后需要完全重调。树的复杂度本质上由样本密度决定样本越多树越有空间长深。我在多个项目中的保守做法是先固定一个合理的叶子最小样本数再通过交叉验证选择深度和特征数量并把这种配置写入项目记录中。没有记录不清的调参经验跟过拟合有什么区别9. 回头看这一章到底教会了什么第四章看上去信息量巨大把原始树的诞生过程拆开来看不过几年时间沉淀下来的几个经验找最有区分度的特征、控制生成规模、容忍真实数据的脏乱、必要时允许边界倾斜。如果把这本书当作一本“手艺集”第四章就是最核心的入门工具章。读完笔记之后别忘了回原书看每个小节最后的小结和习题。习题虽少但每道题都值得认真推理尤其是那些要求你“用公式计算”的题——不亲手算一遍你真的会以为自己懂了。这一章读完之后再往后看神经网络、支持向量机这些黑箱模型时你会多一个对比参照黑箱模型牺牲了可解释性换来了表达复杂边界的能力而决策树一直坚持把决策摊在台面上代价是边界表达受限。没有十全十美的模型只有适不适合你当前场景的选择。就我个人而言很多模型上线后最煎熬的环节就是向业务方解释预测逻辑每到这种时候我都会怀念决策树的直白。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表