第 28 章 · 番外
经典机器学习:决策树与随机森林
这本书一路都在讲神经网络,但它并不是机器学习的全部。第 26 章那张“模型家族表”里, 有一支叫树模型——到 2026 年,它在表格数据(银行风控、广告排序、销量预测、工业质检)上依然常常比神经网络更好用。 这一章就把这支讲清楚:一棵决策树是怎么学出来的,为什么单棵容易过拟合,以及随机森林和梯度提升树怎么用“很多棵树”把它救回来。
前面 27 章的神经网络和这一章的树模型,是机器学习里两条并行的路线,不是谁进化成谁。 这一章不依赖前面的反向传播、梯度下降——树模型压根不用求导。它更像给你补上“另一半地图”: 知道除了神经网络,业界还常年在用什么、为什么用。本章仍以原理和直觉为主,暂无配套 C++ 代码。
读完这一章,你会明白
- 一棵决策树到底在学什么——其实就是把一串 if-else 从数据里自动长出来;
- 它凭什么决定“先问哪个问题”:基尼不纯度 / 信息增益是怎么打分的;
- 整棵树是怎么训练出来的——贪心 + 递归地反复问“下一刀切哪最划算”,全程不求导;
- 为什么单棵树特别容易过拟合,以及“剪枝”在干嘛;
- 随机森林怎么用“很多棵各自有偏见的树投票”把误差压下去(Bagging);
- 梯度提升树(GBDT)又是另一种思路:一棵接一棵地专门纠错(Boosting);
- kNN 这个“不训练”的惰性模型怎么靠邻居投票判类;SVM / 逻辑回归 / 朴素贝叶斯速览,以及它们分别适合什么场景、承担什么作用。
1. 先从一个问题说起:20 个问题
你小时候大概玩过“猜东西”游戏:我心里想一个动物,你只能问“是/否”问题来猜。聪明的玩法是—— 每次都问那个最能把可能性劈成两半的问题:“它是哺乳动物吗?”“它比猫大吗?”“它会飞吗?”…… 问不了几轮,答案就锁定了。
决策树就是这个游戏的自动版。给它一堆带标签的数据(比如很多条贷款申请,每条标了“最后有没有还上”), 它会自己找出“该按哪些特征、按什么顺序去问”,最后长成一棵能对新样本做判断的树。它和神经网络最大的不同是: 你能一眼读懂它的每一步决策——这也是它在金融、医疗这类“必须解释为什么”的场景里长盛不衰的原因。
2. 决策树:把 if-else 学出来
假设我们要判断“要不要给一个人批贷款”,手上每条历史数据有几个特征:收入、是否有房、信用历史长度, 以及标签最终是否违约。一棵学出来的决策树可能长这样:
一棵决策树:每个内部节点就是一个“问一个特征”的判断,每条边是答案,每个叶子给出最终结论。预测时,新样本从根节点开始按特征一路往下走,落到哪片叶子就输出哪个答案。
注意:树的形状、先问哪个特征、在哪个数值上切,都不是人写死的,而是从数据里“学”出来的。 那么问题来了——它凭什么决定“根节点先问收入,而不是先问有没有房”?
2.1 怎么选“该问哪个问题”:基尼与信息增益
核心思想一句话:选那个能把数据分得“最干净”的问题。“干净”指的是——分完之后,每一堆里尽量都是同一类 (要么几乎全是“会还款”,要么几乎全是“会违约”)。衡量“不干净”程度的常用指标是基尼不纯度(Gini impurity):
举个数字:一个节点里有 10 条样本,如果 10 条全是“会还款”,那 Gini = 1 − 1² = 0,纯净到不用再问了; 如果 5 条还款、5 条违约,Gini = 1 − (0.5² + 0.5²) = 0.5,乱成一团。 决策树会逐个特征、逐个切分点试一遍,算出“切完之后左右两堆的加权平均 Gini 下降了多少”, 下降最多的那个切法就是这一步的最优提问。然后对切出来的每一堆递归重复,直到足够干净——树就这样一层层长出来了。
另一套经典指标(ID3 / C4.5 算法用)是信息增益,把“不纯度”换成信息论里的熵(entropy) H = −Σ pk log pk,再看“分裂后熵减少了多少”。尺子不同,目标完全一致:让每一刀都尽量把混在一起的类别分开。
2.2 怎么把整棵树种出来:贪心 + 递归
上一节解决的是“某一个节点该按哪个特征、哪个切分点分”。那整棵树呢?答案是一句话: 在每个节点都用上面的打分选一个当下最优的切法,切完之后对切出来的每一小堆重复同样的动作。 这种“每一步都只挑眼前最好、不回头”的策略叫贪心(greedy),配合“对子问题重复自己”的递归(recursion),树就长出来了。写成步骤:
训练一个节点(落在这个节点的样本集合 D):
1. 若 D 已经足够纯(几乎全一类)或满足停止条件: 1
把这个节点设成叶子,输出 D 里最多的那一类,返回
2. 否则,遍历每个特征 × 每个可能的切分点: 2
算“按它切开后,左右两堆的加权平均不纯度”
3. 选出让不纯度下降最多的那个 (特征, 切分点) 3
4. 用它把 D 分成左、右两堆 4
5. 对左堆、右堆各自递归调用“训练一个节点” 5
- 递归的出口:纯了就不用再问,直接当叶子。停止条件还包括“深度到顶”“样本太少”等(下一节剪枝会展开)。
- 穷举打分:这是树“学习”的核心动作——它不靠求导,而是把所有候选切法都试一遍,用 §2.1 的基尼/信息增益给每种切法打分。
- 贪心选择:只挑当前这一步分得最干净的,不考虑“将来会不会更好”。这让训练很快,但也是单棵树容易长歪的原因之一。
- 一分为二:比如“收入 > 1 万”成立的样本进右堆,不成立的进左堆。
- 对子问题重复自己:左右两堆各自又是一个更小的训练问题,套用同一套流程,直到触发出口。
所以决策树的“训练”和神经网络完全是两码事:它没有权重可调、不做反向传播、也没有学习率, 整个过程就是“不停地问:下一刀切在哪最划算?”。下面用一个最小的例子,把“打分”这一步真正算一遍。
设一个节点有 10 条样本:6 条会还款、4 条会违约,当前不纯度 Gini = 1 − (0.6² + 0.4²) = 0.48。现在试一个切法“月收入 > 1 万?”,把样本分成两堆:
- 右堆(收入>1万):5 条,4 还款 / 1 违约 → Gini = 1 − (0.8² + 0.2²) = 0.32
- 左堆(收入≤1万):5 条,2 还款 / 3 违约 → Gini = 1 − (0.4² + 0.6²) = 0.48
切完的加权平均不纯度 = (5/10)×0.32 + (5/10)×0.48 = 0.40,比切之前的 0.48 下降了 0.08。决策树会对每个特征的每个切分点都算一遍这个“下降了多少”, 最后挑下降最多的那一刀落下去。这就是它每一步在“学”的全部内容。
2.3 什么时候停:过拟合与剪枝
如果让树无限往下长,它最终能给训练集里每一条样本都单独切一片叶子——训练准确率 100%。 但这恰恰是灾难:它把训练数据里的噪声和巧合也当成规律背了下来,一遇到新样本就露馅。 这就是第 10 章讲过的过拟合,在树模型里尤其严重。
常用的两类刹车:
- 预剪枝(提前停):长树时就设限——比如“最深不超过 5 层”“一个节点少于 20 条样本就不再分”“不纯度下降太小就停”。
- 后剪枝(先长再砍):先让树长满,再用验证集从底往上评估,把“砍掉后泛化反而更好”的枝叶剪掉。
但即便剪枝,单棵决策树依然有个顽疾:不稳定。训练数据只要变动一点点(去掉几条样本), 它可能就从根节点开始选了完全不同的特征,长成另一棵样子完全不同的树。正是这个“不稳定”,催生了随机森林。
3. 随机森林:三个臭皮匠,顶个诸葛亮
既然一棵树又不稳、又爱过拟合,那就种一大片树,让它们投票。这就是随机森林(Random Forest), 它用的通用套路叫 Bagging(Bootstrap Aggregating)。关键是要让每棵树都不一样、犯各自独立的错,靠两重随机做到:
- 样本随机:每棵树不是拿全部数据,而是从训练集里有放回地随机抽一批样本来训(有的样本被抽中多次,有的没被抽到)。
- 特征随机:每次分裂时,不是从所有特征里挑最优,而是先随机抽一个特征子集,只在子集里挑最优。这样避免所有树都被同一个“强特征”主导,长得千篇一律。
预测时:分类问题让所有树投票取多数,回归问题取所有树输出的平均。
随机森林:从同一份数据反复抽样训出许多各不相同的树,预测时让它们投票 / 取平均。单棵树各有各的偏见和错误,但把大量独立的错平均掉后,整体反而又准又稳。
想象一群人估西瓜重量:每个人都会估偏,有人偏高有人偏低。但只要大家的错误方向各异、互相独立, 把所有人的估计一平均,正负就抵消了,群体结果往往比任何一个专家都准。随机森林靠“样本随机+特征随机”刻意制造这种独立性, 所以它几乎不用怎么调参就很能打,是表格数据上最好用的“开箱即用”模型之一。
4. 梯度提升树:一棵接一棵地纠错
随机森林是并行种一堆树再平均(Bagging);还有另一条思路正好相反——串行地一棵接一棵种, 每棵新树都专门去修正前面所有树加起来还没做对的部分。这就是 Boosting, 它的代表是梯度提升树(GBDT):
- 先种一棵很浅的树,做个粗略预测;
- 算出它还差多少(残差 / 梯度方向);
- 再种一棵新树,专门去拟合这个“差多少”;
- 把新树加进来,预测更准一点;如此反复几百上千棵,每棵都只补一小步。
你可能已经嗅到熟悉的味道了——“看还差多少,朝减小误差的方向挪一小步”,这正是第 5 章梯度下降的思路, 只不过这里每一步挪的不是数字参数,而是加进来一棵新树。XGBoost、LightGBM 就是 GBDT 的高效工业实现, 在 Kaggle 竞赛和真实表格业务里常年是夺冠常客。
| 随机森林(Bagging) | 梯度提升树(Boosting) | |
|---|---|---|
| 树之间 | 并行、独立,互不知道 | 串行、接力,后一棵补前面的错 |
| 每棵树 | 长得比较深、比较强 | 通常很浅(弱学习器),靠数量取胜 |
| 主要降低 | 方差(让结果更稳、不过拟合) | 偏差(让结果更准、拟合更细) |
| 脾气 | 不太挑参数,稳健好用 | 更准,但要小心调参、否则会过拟合 |
同样是“很多棵树”,Bagging 靠“平均独立的错”求稳,Boosting 靠“接力纠错”求准。两者是表格数据上的两大主力。
5. kNN:一个“不训练”的模型
讲完树,再看一个思路截然相反、却同样经典的模型——k 近邻(k-Nearest Neighbors,kNN)。 它的想法朴素到有点“耍赖”:要判断一个新样本是哪一类,就看它周围离得最近的 k 个老样本大多是什么类,少数服从多数。 “物以类聚,人以群分”,说的就是它。
kNN 判类:找出离待判样本(?)最近的 k 个邻居,让它们投票。k=3 时这里 2 橙 1 蓝,于是判成橙类。
kNN 最有意思的一点是——它几乎没有“训练”这回事:
- “训练”只是把数据存起来。它不像决策树要递归分裂,也不像神经网络要反向传播,训练阶段什么都不算,所以被叫作惰性学习(lazy learning)。
- 所有计算都堆在预测时。来一个新样本,才现算它到每一个老样本的距离(常用欧氏距离),排序取最近的 k 个投票。
- k 是关键旋钮:k 太小(如 k=1)容易被个别噪声点带偏、过拟合;k 太大又会把很远的、不相干的点也拉进来投票,变得模糊。
kNN 思想极简、也不需要训练,但代价是预测慢:每判一个新样本都要和全部训练数据比一遍距离,数据一大就吃不消。 而且它高度依赖“距离有意义”——当特征维度很高时,所有点的距离会变得差不多(维度灾难), 近邻也就失去了意义。所以 kNN 更适合维度不高、数据量不大的场景,以及作为快速验证想法的基线。
6. 其他常见的经典模型(速览)
树和 kNN 之外,还有几位“深度学习之前的主力”,至今在合适场景里依然好用。这里各给一句话直觉,建立个印象即可:
| 模型 | 一句话直觉 | 擅长 |
|---|---|---|
| 逻辑回归 | 加权求和再过一个 Sigmoid,输出“属于某类的概率” | 快、稳、极好解释;是很多系统的基线 |
| SVM 支持向量机 | 找一条“间隔最大”的分界线;必要时用核函数映到高维再切 | 中小规模、高维数据,理论漂亮 |
| 朴素贝叶斯 | 用贝叶斯公式算概率,假设各特征“互相独立”(所以叫朴素) | 文本分类、垃圾邮件过滤,又快又意外地好用 |
| K-means 聚类 | 没有标签,自动把数据聚成 K 堆 | 见 第 27 章,属于无监督 |
逻辑回归 = “加权求和 Σ w·x + b → 过 Sigmoid → 输出概率”。对照第 2 章的一个神经元你会发现: 一个带 Sigmoid 的神经元,本质上就是一个逻辑回归。所以神经网络并不是凭空冒出来的新物种——它更像是把这些经典的“小砖块”大规模堆叠、再让它们端到端一起学。
7. 一张速查表:它们分别用在哪
经典模型不是“老古董”,更像一套工具箱。它们的差别不只是准不准,还包括训练成本、预测速度、可解释性、对数据形态的要求。 下面这张表可以当成第一版选型地图:
| 模型 | 典型场景 | 主要作用 | 不太适合 |
|---|---|---|---|
| 决策树 | 小中型表格数据;规则审核;需要解释每一步的风控/运营策略 | 把数据里的判断规则变成一串可读的 if-else,方便人检查、改规则、做合规说明 | 数据噪声大、特征很多且关系复杂时,单棵树容易过拟合、不稳定 |
| 随机森林 | 表格分类/回归;想先拿一个稳健基线;不想花太多时间调参 | 用很多棵树投票/平均,把单棵树的偶然错误平均掉;常用于快速判断“这个问题能不能从特征里学出来” | 追求极致精度、模型要很小、或需要每条预测都有非常短的解释链路时 |
| GBDT / XGBoost / LightGBM | 银行风控、广告点击率、推荐排序、销量/价格预测等表格业务 | 一棵接一棵纠错,通常是表格数据上的高精度主力;还能输出特征重要性,帮人发现哪些字段最有用 | 原始图片、语音、长文本这类需要自动学表示的非结构化数据 |
| kNN | 数据量不大、维度不高、距离有意义的分类/检索;快速做 demo 或基线 | 不训练,直接靠“最近的老样本”投票;也常用于相似案例查找、简单推荐、异常点初筛 | 大数据量预测会慢;高维特征里距离容易失真;线上低延迟服务通常不直接裸用 |
| 逻辑回归 | 二分类风控、广告点击率、转化率预估、医疗风险评分;需要概率和可解释系数 | 给出“属于某类的概率”,训练快、上线便宜、系数可解释;非常适合作为生产基线和可解释评分卡 | 强非线性关系很多、特征交叉复杂且不想手工做特征工程时 |
| SVM | 中小规模、高维稀疏特征;文本分类、传统图像特征分类、生物信息等 | 找最大间隔分界面,小数据上常很稳;核函数能处理一部分非线性边界 | 百万级以上大数据、需要频繁增量训练、或需要自然输出概率的场景 |
| 朴素贝叶斯 | 垃圾邮件过滤、新闻分类、舆情标签、关键词很有信号的文本任务 | 用词/特征出现的概率快速判类;训练和预测都极快,小数据也能跑出可用结果 | 特征之间强相关、需要理解上下文语义、或类别边界很复杂的任务 |
| K-means | 没有标签时做用户分群、商品分组、图片颜色聚类、数据探索 | 先把样本粗分成几群,帮助人看结构、做分层运营,或给后续模型造特征 | 不知道该分几群、簇形状弯弯绕绕、离群点很多的场景 |
选模型时先问三件事:数据是表格还是图文语音?数据量是小中大?业务要不要解释?答案通常已经能排除一大半模型。
真做项目时,别一上来就拿大模型压。表格任务可以先用逻辑回归做可解释基线, 再用随机森林看非线性信号是否存在,最后用GBDT冲精度; 图像、语音、长文本这类原始感知数据,再优先考虑 CNN / Transformer / 大模型。
8. 到底什么时候用树、什么时候用神经网络?
这是最实用的问题。别被“深度学习最先进”带偏了——选模型要看数据长什么样:
| 你的数据 / 场景 | 更推荐 | 为什么 |
|---|---|---|
| 表格数据(Excel 那种:一行样本、多列特征) | 树模型 / GBDT | 特征各有含义、量纲不同、还常有缺失,树天然能吃;通常又快又准 |
| 图像、语音、视频 | 神经网络(CNN 等) | 原始像素/波形需要自动学层次化特征,树很难处理 |
| 长文本、对话、翻译 | 神经网络(Transformer) | 需要理解顺序和长距离依赖 |
| 数据量很小(几百上千条) | 经典模型 / 树 | 神经网络容易过拟合、也不划算 |
| 必须能解释每一步(风控、医疗合规) | 决策树 / 逻辑回归 | 决策路径人能读懂,神经网络更像黑盒 |
| 数据海量、且是原始感知信号 | 深度学习 / 大模型 | 数据越多、结构越原始,端到端表示学习优势越大 |
一个常被验证的经验:在中小规模表格数据上,调好的 GBDT 往往打平甚至超过深度网络,而且训练快得多。所以“用不用神经网络”,先看数据,而不是先看潮流。
小结
- 决策树 = 从数据里自动长出来的一串 if-else;预测就是从根节点按特征一路走到叶子。
- 选“先问哪个特征”靠基尼不纯度 / 信息增益:哪一刀把类别分得最干净,就选哪一刀。
- 整棵树靠贪心 + 递归训练:每个节点穷举所有切法挑最优,再对左右两堆重复;不求导、无学习率。
- 单棵树容易过拟合、不稳定,靠剪枝缓解,但根治要靠“很多棵树”。
- 随机森林(Bagging):样本随机 + 特征随机种一堆独立的树,投票/平均求稳。
- 梯度提升树(Boosting/GBDT):串行接力,每棵新树专补前面的错,求准;XGBoost/LightGBM 是工业主力。
- kNN 不训练,把计算全留到预测时靠最近邻投票;逻辑回归、SVM、朴素贝叶斯各有擅长,一个带 Sigmoid 的神经元就是逻辑回归。
- 经典模型各有位置:逻辑回归做可解释概率基线,随机森林做稳健基线,GBDT 冲表格精度,kNN 做近邻检索/小数据验证,SVM 适合中小高维数据,朴素贝叶斯适合快速文本分类。
- 选型看数据:表格数据优先树模型,图像/语音/长文本优先神经网络,不是越“深”越好。
动手与思考
问题 1:一个节点里 8 条样本全是“会还款”,它的基尼不纯度是多少?说明什么?
Gini = 1 − 1² = 0。说明这堆已经完全纯净(全一类),不需要再分裂,可以直接作为叶子给出结论。
问题 2:随机森林为什么要“特征随机”?只做“样本随机”不行吗?
如果只做样本随机,一旦存在某个特别强的特征,几乎每棵树都会先拿它来分裂,结果所有树长得很像、错误高度相关,平均起来降不了多少方差。加上“每次分裂只在随机特征子集里挑”,才能强制让树彼此不同、错误更独立,投票才真正有效。
问题 3:随机森林和梯度提升树,最本质的区别是什么?
随机森林是并行、独立地种很多树再平均,主要降低方差(求稳);梯度提升树是串行接力,每棵新树专门拟合前面所有树的残差,主要降低偏差(求准)。一个靠“平均独立的错”,一个靠“接力纠错”。
问题 4:手上是一份 5000 行、30 列的银行客户表格,要预测会不会违约,你先试哪个模型?
先试树模型 / GBDT(如 XGBoost、LightGBM)。这是典型的中小规模表格数据,特征有含义、量纲不一、可能有缺失,树模型天然适配、训练快、还相对好解释;神经网络在这种场景通常没有优势,还更容易过拟合。
番外读完 · 另一半地图补上了
现在你手里有了完整的两张地图:一边是这本书主讲的神经网络 / 深度学习, 另一边是树模型和经典机器学习。真实世界里它们常常并肩作战—— 大模型负责理解图文语音,树模型负责稳稳地啃表格。知道什么时候用哪个,比只会一种更值钱。