内容概览
本文系统梳理了集成学习的核心方法脉络,涵盖以下关键内容:
- 随机森林(Random Forest):通过自举采样 + 随机特征选择构建解耦合的决策树,在保持偏差不变的同时显著降低方差,是 Bagging 的代表性改进;
- 广义加性模型(Additive Models) :以 F(x)=∑m=1Mfm(x)F(x) = \sum_{m=1}^{M} f_m(x)F(x)=∑m=1Mfm(x) 的形式逐步叠加基学习器,为 Boosting 提供了统一的加性框架;
- AdaBoost :通过最小化指数损失 J(F)=Ee−yF(x)J(F) = \mathbb{E}e\^{-yF(x)}J(F)=Ee−yF(x) 自适应调整样本权重,是 Boosting 的经典实现;
- GBDT 梯度提升决策树:以决策树为基学习器,通过泰勒展开逼近目标函数并引入结构复杂度惩罚,XGBoost 是其最成功的工程化实现;
- 深度森林(gcForest):以级联森林 + 多粒度扫描实现逐层特征变换,探索了不依赖反向传播的"深度"集成学习路径。
1. 引言
集成学习(Ensemble Learning)是机器学习中一类非常强大的方法,其核心思想是:通过构建并组合多个"不同的"学习器,达到比单个学习器更好的泛化效果。本讲内容来自上海交通大学张伟楠老师的《机器学习》第7节,系统介绍了从随机森林、广义加性模型、AdaBoost、GBDT梯度提升决策树,到深度森林(多粒度级联森林)的完整知识脉络。
2. 随机森林
2.1 偏差-方差分解(Bias-Variance Decomposition)
假设 Y=f(X)+ϵY = f(X) + \epsilonY=f(X)+ϵ,其中 Eϵ=0\mathbb{E}\\epsilon = 0Eϵ=0,Varϵ=σϵ2\mathrm{Var}\\epsilon = \sigma_\epsilon^2Varϵ=σϵ2。在输入点 x0x_0x0 的期望预测误差为:
Err(x0)=E(Y−f\^(x0))2∣X=x0=σϵ2+Bias2(f^(x0))+Var(f^(x0))\mathrm{Err}(x_0) = \mathbb{E}\left(Y - \\hat{f}(x_0))\^2 \\mid X = x_0\\right = \sigma_\epsilon^2 + \mathrm{Bias}^2(\hat{f}(x_0)) + \mathrm{Var}(\hat{f}(x_0))Err(x0)=E(Y−f\^(x0))2∣X=x0=σϵ2+Bias2(f^(x0))+Var(f^(x0))
2.2 为什么 Bagging 算法有效?
Bagging 有效的原因是与原始模型相比偏差相同但是降低了方差(在整个数据集上进行训练),对低偏差和高方差的预测模型尤其有效果。
如果有一系列服从同一分布的变量(方差为 σ2\sigma^2σ2),两两之间的关联性为 ρ\rhoρ,对变量值取平均之后的方差为:
var=ρσ2+1−ρBσ2\mathrm{var} = \rho\sigma^2 + \frac{1 - \rho}{B}\sigma^2var=ρσ2+B1−ρσ2
如果采样样本无限大,该公式的值会降为 ρσ2\rho\sigma^2ρσ2。用自举采样(Bootstrap)的数据进行训练得到的模型很可能是有一定相关性的,ρ\rhoρ 越小,最后集成的方差越小。
2.3 随机森林算法
随机森林与 Bagging 算法的主要区别在于构建了一个**解耦合(de-correlated)**的树,然后对结果取平均。其核心思想来自 Breiman 的经典论文 "Random forests." Machine learning 45.1 (2001)。
树解耦合的关键 :在每个树节点分裂前,随机选择 m≤pm \le pm≤p 个变量作为分裂的候选变量(一般 m=pm = \sqrt{p}m=p 甚至取值为 1)。
随机森林算法流程:
- 对 b=1b = 1b=1 到 BBB:
- 从训练数据中自举采样 nnn 个数据作为自举采样集;
- 根据采样数据生成一个随机树 TbT_bTb,对每个树的叶节点迭代重复接下来几步,直到到达最小的结点数量:
- 从 ppp 个变量中随机选择 mmm 个变量;
- 在 mmm 个变量中间选择最好的变量和最佳分裂点;
- 将结点分裂成两个子结点。
- 输出新的集成结果 {Tb}b=1B\{T_b\}_{b=1}^{B}{Tb}b=1B。
- 对新的点 xxx 做预测:
- 回归 :预测平均值 f^rfB(x)=1B∑b=1BTb(x)\hat{f}{\mathrm{rf}}^B(x) = \frac{1}{B}\sum{b=1}^{B} T_b(x)f^rfB(x)=B1∑b=1BTb(x);
- 分类 :多数投票 C^rfB(x)=majority vote{C^b(x)}1B\hat{C}_{\mathrm{rf}}^B(x) = \text{majority vote}\{\hat{C}_b(x)\}_1^BC^rfB(x)=majority vote{C^b(x)}1B。
下面是随机森林算法的完整流程图,直观展示从自举采样、生成随机树到集成预测的整个过程:
#mermaid-svg-hIG4hLoVLCqzBTp2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hIG4hLoVLCqzBTp2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hIG4hLoVLCqzBTp2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hIG4hLoVLCqzBTp2 .error-icon{fill:#552222;}#mermaid-svg-hIG4hLoVLCqzBTp2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hIG4hLoVLCqzBTp2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hIG4hLoVLCqzBTp2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hIG4hLoVLCqzBTp2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hIG4hLoVLCqzBTp2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hIG4hLoVLCqzBTp2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hIG4hLoVLCqzBTp2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hIG4hLoVLCqzBTp2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hIG4hLoVLCqzBTp2 .marker.cross{stroke:#333333;}#mermaid-svg-hIG4hLoVLCqzBTp2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hIG4hLoVLCqzBTp2 p{margin:0;}#mermaid-svg-hIG4hLoVLCqzBTp2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-hIG4hLoVLCqzBTp2 .cluster-label text{fill:#333;}#mermaid-svg-hIG4hLoVLCqzBTp2 .cluster-label span{color:#333;}#mermaid-svg-hIG4hLoVLCqzBTp2 .cluster-label span p{background-color:transparent;}#mermaid-svg-hIG4hLoVLCqzBTp2 .label text,#mermaid-svg-hIG4hLoVLCqzBTp2 span{fill:#333;color:#333;}#mermaid-svg-hIG4hLoVLCqzBTp2 .node rect,#mermaid-svg-hIG4hLoVLCqzBTp2 .node circle,#mermaid-svg-hIG4hLoVLCqzBTp2 .node ellipse,#mermaid-svg-hIG4hLoVLCqzBTp2 .node polygon,#mermaid-svg-hIG4hLoVLCqzBTp2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hIG4hLoVLCqzBTp2 .rough-node .label text,#mermaid-svg-hIG4hLoVLCqzBTp2 .node .label text,#mermaid-svg-hIG4hLoVLCqzBTp2 .image-shape .label,#mermaid-svg-hIG4hLoVLCqzBTp2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-hIG4hLoVLCqzBTp2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hIG4hLoVLCqzBTp2 .rough-node .label,#mermaid-svg-hIG4hLoVLCqzBTp2 .node .label,#mermaid-svg-hIG4hLoVLCqzBTp2 .image-shape .label,#mermaid-svg-hIG4hLoVLCqzBTp2 .icon-shape .label{text-align:center;}#mermaid-svg-hIG4hLoVLCqzBTp2 .node.clickable{cursor:pointer;}#mermaid-svg-hIG4hLoVLCqzBTp2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hIG4hLoVLCqzBTp2 .arrowheadPath{fill:#333333;}#mermaid-svg-hIG4hLoVLCqzBTp2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hIG4hLoVLCqzBTp2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hIG4hLoVLCqzBTp2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hIG4hLoVLCqzBTp2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hIG4hLoVLCqzBTp2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hIG4hLoVLCqzBTp2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hIG4hLoVLCqzBTp2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hIG4hLoVLCqzBTp2 .cluster text{fill:#333;}#mermaid-svg-hIG4hLoVLCqzBTp2 .cluster span{color:#333;}#mermaid-svg-hIG4hLoVLCqzBTp2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hIG4hLoVLCqzBTp2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hIG4hLoVLCqzBTp2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-hIG4hLoVLCqzBTp2 .icon-shape,#mermaid-svg-hIG4hLoVLCqzBTp2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hIG4hLoVLCqzBTp2 .icon-shape p,#mermaid-svg-hIG4hLoVLCqzBTp2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hIG4hLoVLCqzBTp2 .icon-shape .label rect,#mermaid-svg-hIG4hLoVLCqzBTp2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hIG4hLoVLCqzBTp2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hIG4hLoVLCqzBTp2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hIG4hLoVLCqzBTp2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否
是
是
否
回归
分类
开始:训练数据
对 b = 1 到 B 循环
自举采样:从训练数据中
随机抽取 n 个样本
生成随机树 T_b
从 p 个变量中
随机选择 m 个变量
在 m 个变量中
选择最佳变量与分裂点
是否达到
最小结点数量?
完成一棵随机树 T_b
b < B?
输出集成结果 {T_b}
对新点 x 做预测
任务类型
预测平均值
(1/B)ΣT_b(x)
多数投票
majority vote
输出最终预测结果
2.4 表现对比
在 10 维嵌套球数据上(Y=1Y = 1Y=1 若 ∑j=110Xj2>9.34\sum_{j=1}^{10} X_j^2 > 9.34∑j=110Xj2>9.34,否则 Y=−1Y = -1Y=−1),RF-m 表示每次分裂时随机选择的变量数量。实验表明:选 1 个特征、选 3 个特征、选 10 个特征的分裂效果各不相同,随机选择少量特征往往能带来更好的泛化性能。
3. 广义加性模型
3.1 Bagging vs. 随机森林 vs. Boosting
- Bagging:仅仅是在有相同权重的自举采样集上对每个预测模型进行训练;
- 随机森林:通过采样特征的方法尝试去解耦合自举训练预测模型(决策树);
- Boosting:基于之前的预测模型有策略性地学习和结合接下来的预测模型。
下表从核心思想、代表性算法、主要优点、缺点/挑战和典型应用场景五个维度,系统对比四类主流集成学习方法:
| 维度 | Bagging | 随机森林(Random Forest) | Boosting(AdaBoost / GBDT) | 深度森林(gcForest) |
|---|---|---|---|---|
| 核心思想 | 对训练数据做自举采样,并行训练多个基学习器后取平均/投票,偏差不变、降低方差 | 在 Bagging 基础上,分裂时随机选择候选特征子集,构建解耦合的决策树后集成 | 串行训练基学习器,每个新学习器聚焦前序模型的错误,逐步最小化损失函数 | 以级联森林 + 多粒度扫描实现逐层特征变换,探索不依赖反向传播的"深度"集成 |
| 代表性算法 | Bagging(Bootstrap Aggregating) | 随机森林(Breiman, 2001) | AdaBoost、GBDT、XGBoost、LightGBM | gcForest(多粒度级联森林,Zhou & Feng, 2017) |
| 主要优点 | 实现简单、可并行、能显著降低高方差模型的过拟合 | 泛化能力强、对噪声和过拟合鲁棒、可并行训练、能输出特征重要性 | 精度通常更高,能逼近复杂非线性关系,XGBoost 等工程实现高效且支持正则化 | 超参数少、默认设定即可用、自适应模型复杂度、可在小数据集上应用、无需反向传播 |
| 缺点/挑战 | 对低方差模型提升有限,模型间相关性较高时收益下降 | 在高维稀疏数据上表现一般,可解释性弱于单棵决策树 | 串行训练难以并行、对噪声/异常值敏感(AdaBoost 尤甚)、调参较复杂 | 训练开销较大、理论分析尚不完善、在超大图像任务上仍不及 DNNs |
| 典型应用场景 | 高方差模型(如深决策树)的方差削减、中小规模表格数据 | 表格数据分类/回归、特征重要性分析、Kaggle 竞赛基线 | 广告点击率预测、排序、信贷风控、各类结构化数据竞赛(XGBoost/LightGBM 为主流) | 图像/序列等需逐层特征变换的任务、小样本场景、希望避免繁琐调参的落地场景 |
3.2 加性模型(Additive Models)
加性模型的通用形式为:
F(x)=∑m=1Mfm(x)F(x) = \sum_{m=1}^{M} f_m(x)F(x)=m=1∑Mfm(x)
其中 fm(x)=βmb(x;γm)f_m(x) = \beta_m b(x; \gamma_m)fm(x)=βmb(x;γm),即:
FM(x)=∑m=1Mβmb(x;γm)F_M(x) = \sum_{m=1}^{M} \beta_m b(x; \gamma_m)FM(x)=m=1∑Mβmb(x;γm)
加性回归模型有两种学习策略:
- 其他预测模型参数固定,进行最小二乘学习 :本质上相当于把原始值修改为 ym←y−∑k≠mfk(x)y_m \leftarrow y - \sum_{k \ne m} f_k(x)ym←y−∑k=mfk(x);
- 之前学习好的预测模型参数固定,逐步进行最小二乘学习 :本质上相当于把原始值修改为 ym←y−Fm−1(x)=ym−1−fm−1(x)y_m \leftarrow y - F_{m-1}(x) = y_{m-1} - f_{m-1}(x)ym←y−Fm−1(x)=ym−1−fm−1(x)。
加性分类模型 :对二元分类 y={1,−1}y = \{1, -1\}y={1,−1},有:
P(y=1∣x)=exp(F(x))1+exp(F(x)),P(y=−1∣x)=11+exp(F(x))P(y = 1|x) = \frac{\exp(F(x))}{1 + \exp(F(x))}, \quad P(y = -1|x) = \frac{1}{1 + \exp(F(x))}P(y=1∣x)=1+exp(F(x))exp(F(x)),P(y=−1∣x)=1+exp(F(x))1
进行对数变换后得到 logP(y=1∣x)1−P(y=1∣x)=F(x)\log\frac{P(y=1|x)}{1-P(y=1|x)} = F(x)log1−P(y=1∣x)P(y=1∣x)=F(x)。
4. AdaBoost 简介
4.1 AdaBoost 学习准则
对二元分类,AdaBoost 最小化下式:
J(F)=Ee−yF(x)J(F) = \mathbb{E}e\^{-yF(x)}J(F)=Ee−yF(x)
该准则由 Schapire 和 Singer 在 1998 年作为误分类误差的上限提出,它(几乎)等价于逻辑交叉熵损失函数。可以证明,AdaBoost 的最优 F(x)F(x)F(x) 对应于 1/21/21/2 倍的逻辑斯谛回归 F(x)F(x)F(x) 值:
F(x)=12logP(y=1∣x)P(y=−1∣x)F(x) = \frac{1}{2}\log\frac{P(y=1|x)}{P(y=-1|x)}F(x)=21logP(y=−1∣x)P(y=1∣x)
指数准则和对数似然(交叉熵)在二阶泰勒级数上是等价的。
4.2 离散型 AdaBoost 算法
- 等权重初始化每一个样本权重 wi=1N,i=1,...,Nw_i = \frac{1}{N}, i = 1, \dots, Nwi=N1,i=1,...,N;
- 从 m=1m = 1m=1 到 MMM:
- I. 用权重 wiw_iwi 在训练数据上训练分类器 fm(x)∈{−1,1}f_m(x) \in \{-1, 1\}fm(x)∈{−1,1};
- II. 计算误差 err=Ew1y≠f(x)\mathrm{err} = \mathbb{E}_w1_{y \\ne f(x)}err=Ew1y=f(x),c=12log1−errerrc = \frac{1}{2}\log\frac{1-\mathrm{err}}{\mathrm{err}}c=21logerr1−err;
- III. 更新权重 wi←wiexp(cm⋅1yi≠fm(xi))w_i \leftarrow w_i \exp(c_m \cdot 1y_i \\ne f_m(x_i))wi←wiexp(cm⋅1yi=fm(xi)),并重新归一化使 ∑iwi=1\sum_i w_i = 1∑iwi=1;
- 输出分类结果 sign∑m=1Mcmfm(x)\text{sign}\\sum_{m=1}\^{M} c_m f_m(x)sign∑m=1Mcmfm(x)。
4.3 实数型 AdaBoost 算法
实数型 AdaBoost 使用类别概率估计 pm(x)p_m(x)pm(x) 来计算实数值贡献 fm(x)f_m(x)fm(x):
- 等权重初始化每一个样本权重 wi=1N,i=1,...,Nw_i = \frac{1}{N}, i = 1, \dots, Nwi=N1,i=1,...,N;
- 从 m=1m = 1m=1 到 MMM:
- I. 用权重 wiw_iwi 在训练数据上训练分类器得到一个类别概率估计 pm(x)=P^w(y=1∣x)∈0,1p_m(x) = \hat{P}_w(y=1|x) \in 0,1pm(x)=P^w(y=1∣x)∈0,1;
- II. 令 fm(x)←12logpm(x)1−pm(x)∈Rf_m(x) \leftarrow \frac{1}{2}\log\frac{p_m(x)}{1-p_m(x)} \in \mathbb{R}fm(x)←21log1−pm(x)pm(x)∈R;
- III. 令 wi←wiexp(−yifm(xi))w_i \leftarrow w_i \exp(-y_i f_m(x_i))wi←wiexp(−yifm(xi)),并重新归一化使 ∑iwi=1\sum_i w_i = 1∑iwi=1;
- 输出分类结果 sign∑m=1Mfm(x)\text{sign}\\sum_{m=1}\^{M} f_m(x)sign∑m=1Mfm(x)。
5. 提升算法简史
- 1990 年 :Schapire 证明,弱学习器总是可以通过在输入数据的过滤版本上训练另外两个分类器来提高其性能。具体地,在有 NNN 个样本的原始数据上训练分类器 h1h_1h1,然后在一组新的 NNN 个样本上训练分类器 h2h_2h2(其中有一半样本是被 h1h_1h1 错误分类的),然后在 h1h_1h1 和 h2h_2h2 分类结果不一致的 NNN 个样本上训练 h3h_3h3,提升分类器 hB=多数投票(h1,h2,h3)h_B = \text{多数投票}(h_1, h_2, h_3)hB=多数投票(h1,h2,h3),事实证明 hBh_BhB 比 h1h_1h1 性能更高;
- 1995 年:Freund 提出了一种"多数提升"的变种方法,将许多弱学习器同时结合起来并改善了 Schapire 简单提升算法的性能(这两种算法都要求弱学习器有固定的错误率);
- 1996 年:Freund 和 Schapire 提出了 AdaBoost,去除了固定错误率的要求;
- 1996~1998 年:Freund、Schapire 和 Singer 以泛化误差的上界形式提出了一些理论来支持他们的算法,但边界太松散而不具有实际意义,提升算法的实际表现远远超过了理论边界;
- 2003 年:Freund、Schapire 因 AdaBoost 获得哥德尔奖。
推荐阅读周志华教授文章:《Boosting 学习理论的探索 ------ 一个跨越 30 年的故事》。
6. GBDT 梯度提升决策树
6.1 增量树
GBDT 是决策树的提升算法,fm(x)f_m(x)fm(x) 是一个决策树模型,有许多变体(GBRT、boosted trees、GBM 等)。其核心思想是生成下一棵树 ftf_tft 来最小化包含惩罚项 Ω(ft)\Omega(f_t)Ω(ft) 的损失函数:
J(t)=∑i=1nl(yi,y^i(t))+Ω(ft)J^{(t)} = \sum_{i=1}^{n} l(y_i, \hat{y}_i^{(t)}) + \Omega(f_t)J(t)=i=1∑nl(yi,y^i(t))+Ω(ft)
其中 y^i(t)=∑m=1tfm(xi)=y^i(t−1)+ft(xi)\hat{y}i^{(t)} = \sum{m=1}^{t} f_m(x_i) = \hat{y}_i^{(t-1)} + f_t(x_i)y^i(t)=∑m=1tfm(xi)=y^i(t−1)+ft(xi)。
6.2 泰勒级数逼近
定义梯度 gi=∇y^(t−1)l(yi,y^i(t−1))g_i = \nabla_{\hat{y}^{(t-1)}} l(y_i, \hat{y}i^{(t-1)})gi=∇y^(t−1)l(yi,y^i(t−1)) 和二阶梯度 hi=∇y^(t−1)2l(yi,y^i(t−1))h_i = \nabla{\hat{y}^{(t-1)}}^2 l(y_i, \hat{y}_i^{(t-1)})hi=∇y^(t−1)2l(yi,y^i(t−1)),目标函数可近似为:
J(t)≃∑i=1nl(yi,y\^i(t−1))+gift(xi)+12hift2(xi)+Ω(ft)J^{(t)} \simeq \sum_{i=1}^{n} \leftl(y_i, \\hat{y}_i\^{(t-1)}) + g_i f_t(x_i) + \\frac{1}{2} h_i f_t\^2(x_i)\\right + \Omega(f_t)J(t)≃i=1∑nl(yi,y\^i(t−1))+gift(xi)+21hift2(xi)+Ω(ft)
6.3 树结构复杂度惩罚
定义树结构 ft(x)=wq(x)f_t(x) = w_{q(x)}ft(x)=wq(x),其中 w∈RTw \in \mathbb{R}^Tw∈RT,q:Rd↦{1,2,...,T}q: \mathbb{R}^d \mapsto \{1, 2, \dots, T\}q:Rd↦{1,2,...,T},TTT 为叶子节点的数目,wjw_jwj 为叶子节点的权重。树结构的复杂度惩罚为:
Ω(ft)=γT+12λ∑j=1Twj2\Omega(f_t) = \gamma T + \frac{1}{2}\lambda \sum_{j=1}^{T} w_j^2Ω(ft)=γT+21λj=1∑Twj2
6.4 重写目标函数
定义 Gj=∑i∈IjgiG_j = \sum_{i \in I_j} g_iGj=∑i∈Ijgi,Hj=∑i∈IjhiH_j = \sum_{i \in I_j} h_iHj=∑i∈Ijhi(IjI_jIj 是样例的集合 {i∣q(xi)=j}\{i \mid q(x_i) = j\}{i∣q(xi)=j}),目标函数可重写为:
J(t)=∑j=1TGjwj+12(Hj+λ)wj2+γTJ^{(t)} = \sum_{j=1}^{T} \leftG_j w_j + \\frac{1}{2}(H_j + \\lambda)w_j\^2\\right + \gamma TJ(t)=j=1∑TGjwj+21(Hj+λ)wj2+γT
对于固定树结构 qqq,其闭式解为:
wj∗=−GjHj+λ,J(t)=−12∑j=1TGj2Hj+λ+γTw_j^* = -\frac{G_j}{H_j + \lambda}, \quad J^{(t)} = -\frac{1}{2}\sum_{j=1}^{T}\frac{G_j^2}{H_j + \lambda} + \gamma Twj∗=−Hj+λGj,J(t)=−21j=1∑THj+λGj2+γT
该值用于衡量一个树结构的好坏,数值越小,树结构越好(注意:这里并没有着眼最大化基尼不纯度或者信息增益)。
6.5 寻找最优树结构
贪心地生长树结构:从树结构深度为 0 处开始,对于每一个叶子节点,尝试增加一次分裂之后,其目标函数的变化为:
Gain=12(GL2HL+λ+GR2HR+λ−(GL+GR)2HL+HR+λ)−γ\text{Gain} = \frac{1}{2}\left(\frac{G_L^2}{H_L + \lambda} + \frac{G_R^2}{H_R + \lambda} - \frac{(G_L + G_R)^2}{H_L + H_R + \lambda}\right) - \gammaGain=21(HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2)−γ
由于最后的惩罚项,引入分裂以后有可能获得非正数的增益。
高效寻找最优分裂 :对于被选特征 jjj,将数据进行升序排序,仅需要获得每一边的 ggg 和 hhh 即可计算 Gain。从左往右对于排序好的样例进行遍历,便能够决定此特征的最佳分裂点。
分裂点搜寻算法 :对于每一个节点,枚举所有可选特征;对于每一个特征,根据特征数值对样例进行排序,以线性时间进行样例遍历并且寻找该特征之下的最佳分裂点。生长一棵深度为 KKK 的树所需时间复杂度为 O(ndKlogn)O(ndK\log n)O(ndKlogn):对于每一层,需要 O(nlogn)O(n\log n)O(nlogn) 的时间复杂度进行排序,对于 ddd 个特征,需要在 KKK 层都进行排序操作。可以进行进一步优化(例如:近似方法或将排序好的特征进行缓存),从而扩展到大规模数据集。
6.6 XGBoost
XGBoost 是最有影响力以及最有效的 GBDT 工具包,参考论文:T Chen, C Guestrin. XGBoost: A Scalable Tree Boosting System. KDD 2016。官方文档见 https://xgboost.readthedocs.io。
6.7 XGBoost 实战:二分类任务
6.8 XGBoost 调参与交叉验证
上一节的示例使用了固定的超参数组合,实际项目中往往需要通过交叉验证 + 网格搜索(GridSearchCV) 或随机搜索(RandomizedSearchCV) 来自动寻找较优的超参数。下面以 GridSearchCV 为例,演示如何在乳腺癌数据集上对 XGBoost 进行调参:
python
import xgboost as xgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score, roc_auc_score
# 1. 数据加载与划分(与 6.7 节保持一致)
data = load_breast_cancer()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 2. 定义待搜索的超参数网格
param_grid = {
"n_estimators": [50, 100, 200], # 树的数量:过少欠拟合,过多则训练变慢且可能过拟合
"max_depth": [3, 5, 7], # 树的最大深度:越大模型越复杂,易过拟合
"learning_rate": [0.01, 0.1, 0.3], # 学习率:越小越稳健,但需要更多树来收敛
"subsample": [0.7, 0.8, 1.0], # 每轮训练的样本采样比例:小于 1 可增加随机性、降低过拟合
"colsample_bytree": [0.7, 0.8, 1.0], # 每棵树使用的特征比例:类似随机森林的特征采样
"reg_lambda": [0.1, 1.0, 10.0], # L2 正则化系数:越大惩罚越强,模型越简单
}
# 3. 构建基础模型(固定与调参无关的公共参数)
base_model = xgb.XGBClassifier(
random_state=42,
eval_metric="logloss",
use_label_encoder=False
)
# 4. 网格搜索 + 5 折交叉验证
grid_search = GridSearchCV(
estimator=base_model,
param_grid=param_grid,
scoring="roc_auc", # 用 AUC 作为评估指标,对类别不平衡更稳健
cv=5, # 5 折交叉验证
n_jobs=-1, # 使用所有 CPU 核心并行搜索
verbose=1
)
grid_search.fit(X_train, y_train)
# 5. 输出最优参数与交叉验证得分
print("最优参数:", grid_search.best_params_)
print("最优交叉验证 AUC: {:.4f}".format(grid_search.best_score_))
# 6. 用最优模型在测试集上评估
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
y_prob = best_model.predict_proba(X_test)[:, 1]
print("测试集准确率: {:.4f}".format(accuracy_score(y_test, y_pred)))
print("测试集 AUC: {:.4f}".format(roc_auc_score(y_test, y_prob)))
关键参数调参范围与策略:
n_estimators(树的数量) :常用范围[50, 100, 200, 500]。树太少容易欠拟合,太多则训练开销增大且可能过拟合;通常与learning_rate配合调节------学习率越小,需要的树越多;max_depth(树的最大深度) :常用范围[3, 5, 7, 9]。深度越大模型越复杂、拟合能力越强,但也越容易过拟合;表格数据上一般从3~7起步;learning_rate(学习率) :常用范围[0.01, 0.05, 0.1, 0.3]。值越小每一步的贡献越保守、泛化往往更好,但需要更多棵树,训练时间更长;subsample(样本采样比例) :常用范围[0.6, 0.8, 1.0]。小于 1 时每轮随机采样部分样本训练,增加随机性、降低过拟合,但过小会欠拟合;colsample_bytree(特征采样比例) :常用范围[0.6, 0.8, 1.0]。每棵树随机使用部分特征,类似随机森林的特征采样,能增强多样性、抑制过拟合;reg_lambda(L2 正则化) :常用范围[0.1, 1.0, 10.0]。对应目标函数中的 λ\lambdaλ,值越大对叶子权重的惩罚越强,模型越简单。
调参建议 :网格搜索会穷举所有组合,参数较多时计算量呈指数增长,此时可改用 RandomizedSearchCV(随机搜索)在参数空间中随机采样,用更少的尝试找到较优组合;更高效的做法是分阶段调参 ------先固定 learning_rate 与 n_estimators,粗调 max_depth、subsample、colsample_bytree,最后再微调正则化系数 reg_lambda、reg_alpha。
下面用一个简单的 Python 示例演示 XGBoost 在二分类任务上的基本流程,包括数据加载、模型训练、预测与评估。示例使用 sklearn 自带的乳腺癌数据集(569 个样本、30 个特征,标签为良性/恶性)。
python
import xgboost as xgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, roc_auc_score
# 1. 数据加载
data = load_breast_cancer()
X, y = data.data, data.target # X: 特征矩阵, y: 标签(0/1)
# 2. 划分训练集与测试集(80% 训练, 20% 测试)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 3. 构建 XGBoost 分类器
model = xgb.XGBClassifier(
n_estimators=100, # 树的数量(迭代轮数)
max_depth=3, # 每棵树的最大深度,控制模型复杂度,防止过拟合
learning_rate=0.1, # 学习率(步长),越小越稳健但需要更多树
subsample=0.8, # 每轮训练随机采样 80% 样本,增加随机性、降低过拟合
colsample_bytree=0.8, # 每棵树随机使用 80% 特征,类似随机森林的特征采样
reg_lambda=1.0, # L2 正则化系数,对应目标函数中的 lambda
reg_alpha=0.0, # L1 正则化系数
random_state=42, # 固定随机种子,保证结果可复现
eval_metric="logloss", # 训练过程中的评估指标
use_label_encoder=False # 关闭旧版标签编码器警告(XGBoost 1.6+ 可省略)
)
# 4. 模型训练
model.fit(X_train, y_train)
# 5. 预测与评估
y_pred = model.predict(X_test) # 预测类别(0/1)
y_prob = model.predict_proba(X_test)[:, 1] # 预测为正类的概率
acc = accuracy_score(y_test, y_pred) # 准确率
auc = roc_auc_score(y_test, y_prob) # AUC(对类别不平衡更稳健)
print(f"准确率: {acc:.4f}")
print(f"AUC: {auc:.4f}")
关键点说明:
n_estimators与learning_rate需要配合调节:学习率越小,通常需要越多的树才能收敛;max_depth、subsample、colsample_bytree、reg_lambda共同控制模型的复杂度与泛化能力,是 XGBoost 最常用的调参对象;- 二分类默认使用
binary:logistic目标函数,输出为类别概率,因此用predict_proba取正类概率计算 AUC 更合理。
6.8.1 常见问题与调参技巧
下面总结 XGBoost/GBDT 实战中几个高频问题,并给出对应的调参技巧与代码片段。
问题 1:过拟合迹象(训练集表现远好于验证集)
当训练集 AUC/准确率明显高于验证集,或验证集指标随迭代轮数先升后降时,说明模型过拟合。常见缓解手段:
- 降低模型复杂度:减小
max_depth、增大min_child_weight(叶子节点最小样本权重和); - 增强正则化:增大
reg_lambda(L2)或reg_alpha(L1); - 增加随机性:调小
subsample与colsample_bytree; - 配合早停(early stopping),在验证集不再提升时提前终止训练。
python
import xgboost as xgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
data = load_breast_cancer()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 用 DMatrix + 早停训练,观察训练/验证 logloss 是否出现"先降后升"的过拟合迹象
dtrain = xgb.DMatrix(X_train, label=y_train)
dvalid = xgb.DMatrix(X_test, label=y_test)
params = {
"objective": "binary:logistic",
"eval_metric": "logloss",
"max_depth": 3, # 减小深度,降低模型复杂度
"min_child_weight": 5, # 增大叶子最小样本权重和,抑制过拟合
"subsample": 0.8, # 每轮随机采样 80% 样本
"colsample_bytree": 0.8, # 每棵树随机使用 80% 特征
"reg_lambda": 2.0, # 增大 L2 正则化
"eta": 0.05, # 调小学习率,配合更多轮数
}
bst = xgb.train(
params,
dtrain,
num_boost_round=500,
evals=[(dtrain, "train"), (dvalid, "valid")],
early_stopping_rounds=50, # 验证集 50 轮无提升即停止
verbose_eval=False,
)
print("最佳迭代轮数:", bst.best_iteration)
print("最佳验证 logloss: {:.4f}".format(bst.best_score))
问题 2:特征重要性解读与特征筛选
XGBoost 内置多种特征重要性指标,最常用的是 gain(该特征被用于分裂时带来的平均增益,对应目标函数中的 Gain)。解读时注意:重要性高只代表该特征在分裂中贡献大,不代表因果性;高度相关的特征会分摊重要性,导致排序失真。
python
import xgboost as xgb
import pandas as pd
# 训练完成后查看特征重要性(基于 gain)
importance = bst.get_score(importance_type="gain")
imp_df = pd.DataFrame(
{"feature": list(importance.keys()), "gain": list(importance.values())}
).sort_values("gain", ascending=False)
print(imp_df.head(10)) # 输出贡献最大的前 10 个特征
# 用 sklearn 接口同样可以获取
# model.feature_importances_ # 默认基于 weight(分裂次数)
问题 3:类别不平衡处理
当正负样本比例悬殊时,准确率会失真,模型容易偏向多数类。常用策略:
- 评估指标改用 AUC、PR-AUC 或 F1,而不是准确率;
- 设置
scale_pos_weight,近似为负样本数 / 正样本数,让模型更关注少数类; - 配合
max_delta_step稳定训练,或使用采样方法(欠采样/过采样)。
python
import xgboost as xgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score, f1_score
data = load_breast_cancer()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# 计算正负样本比例,用于 scale_pos_weight
neg_count = (y_train == 0).sum()
pos_count = (y_train == 1).sum()
scale = neg_count / pos_count # 近似为负样本数 / 正样本数
model = xgb.XGBClassifier(
n_estimators=200,
max_depth=3,
learning_rate=0.1,
scale_pos_weight=scale, # 让模型更关注少数类(正类)
eval_metric="logloss",
use_label_encoder=False,
random_state=42,
)
model.fit(X_train, y_train)
y_prob = model.predict_proba(X_test)[:, 1]
y_pred = (y_prob > 0.5).astype(int) # 也可根据业务调整阈值
print("AUC: {:.4f}".format(roc_auc_score(y_test, y_prob)))
print("F1: {:.4f}".format(f1_score(y_test, y_pred)))
问题 4:训练速度慢 / 内存占用高
数据量大或参数组合多时,训练可能非常耗时。常用优化手段:
- 使用
hist树构造方法(直方图近似)替代默认的exact,大幅加速; - 调小
max_depth、subsample、colsample_bytree,减少单棵树计算量; - 用
RandomizedSearchCV替代GridSearchCV,在参数空间中随机采样,用更少尝试找到较优组合; - 开启
n_jobs并行,或使用 GPU 加速(tree_method="gpu_hist")。
python
import xgboost as xgb
# 使用直方图近似 + 并行,显著提升训练速度
model = xgb.XGBClassifier(
n_estimators=200,
max_depth=6,
learning_rate=0.1,
tree_method="hist", # 直方图近似,比默认 exact 快很多
n_jobs=-1, # 使用所有 CPU 核心
eval_metric="logloss",
use_label_encoder=False,
random_state=42,
)
问题 5:缺失值处理
XGBoost 原生支持缺失值:训练时自动学习缺失值的最优分裂方向,无需手动填充。但要注意:缺失值占比过高或缺失模式本身携带信息时,可考虑构造"是否缺失"的指示特征,帮助模型捕捉缺失模式。
python
import numpy as np
import xgboost as xgb
# XGBoost 原生支持 NaN,直接传入即可,无需填充
X_with_nan = X_train.copy()
X_with_nan[0, 0] = np.nan # 人为制造一个缺失值示例
model = xgb.XGBClassifier(
n_estimators=100,
max_depth=3,
learning_rate=0.1,
eval_metric="logloss",
use_label_encoder=False,
random_state=42,
)
model.fit(X_with_nan, y_train) # 训练时自动学习缺失值分裂方向
# 可选:构造缺失指示特征,捕捉缺失模式
# X_missing_flag = np.isnan(X_with_nan).astype(int)
7. 深度森林
7.1 探寻深度学习的本质
近年来,深度学习取得了巨大成功。然而,"深度学习"到底是什么?现在而言,深度学习 = 深度神经网络(DNNs)。
增加模型复杂度可以增强学习能力(增加隐层单元数即模型宽度,增加隐层的层数即模型深度),但也会加大过拟合风险以及训练难度。当经过多层的反向传播,误差的梯度将会发散,收敛到稳定状态将会非常困难,传统的反向传播算法将会失效,需要使用许多技巧进行训练。
DNNs 成功的关键:
- 庞大的训练数据(减小过拟合风险最为简单有效的方式);
- 高效的算力机器(没有 GPU 的加速,DNNs 无法如此成功);
- 训练技巧(启发式,甚至是无法解释的)。
DNNs 的本质是表示学习,逐层学习很关键。对于何种类型的任务有效?当数据的"原始表示"(例如,图像的像素点)距离对任务而言"足够好的表示"很远时。
深度模型的关键:逐层处理、特征变换、足够的模型复杂度。
使用神经网络的困难:过多的超参数(调参需要许多小技巧,特别是跨任务训练时,很难复现他人的结果)、当结构固定以后模型复杂度往往超过了需求、需要大量训练数据、理论分析十分困难、黑盒问题等。
除此以外,在许多任务中 DNNs 并没有优越性,有时甚至带来不足:数据不同维度的连续/离散性质、不同的规模、有缺失。在许多 Kaggle 竞赛任务中,随机森林或者 XGBoost 往往是参赛者的最终选择。
巨大的挑战:深度模型 = DNNs?不可微模块可以做深度学习吗(不使用反向传播)?可以让深度模型在更多任务上胜出吗?是否可以使用不可微的模块来实现深度学习?
灵感启发:设计的模型需要具有逐层处理、特征变换、足够的模型复杂度。深度森林是一种可能的方案。
7.2 深度森林简介
深度森林(Deep Forest)来自南京大学周志华教授团队的工作:Zhi-hua Zhou, Ji Feng. Deep Forest: Towards an Alternative to Deep Neural Networks. IJCAI 2017。
gcForest(多粒度级联森林,multi-Grained Cascade Forest) 是一种决策树森林(集成学习)方法,与 DNNs 相比在多个任务上表现都具有很强竞争力,且超参数减少明显、更加容易设定参数(默认设定在多个任务上都可以很有效)、自适应的模型复杂度(根据数据集自动决定)、可以在小数据集上应用。
7.3 好的集成方式
直觉而言:个体必须存在差异,个体必须不能太差,集成的确会有帮助。
根据误差-分歧分解(Error-ambiguity decomposition,Krogh & Vedelsby, NIPS'95):集成误差 = 平均个体误差 - 平均个体分歧。单个学习模型越准确越具有差异,集成模型表现越佳。需要注意"分歧"并没有一个形式化定义,且误差-分歧分解是在使用平方损失的回归问题中推导得到的。
差异性是关键,基本思想是加入更多的随机性,主要策略包括:
- 数据采样的处理:Bagging 中的自举采样、Boosting 中的重要性采样;
- 输入特征的处理:在随机子空间中进行特征采样;
- 可学习参数的处理:NN 的随机初始化、负相关学习;
- 输出表示的处理:ECOC、输出翻转。
这些策略并非一直有效(数据采样的处理对于"静态学习器"如线性分类器、SVMs 并不生效),因此需要采用多种策略结合,例如随机森林、FASBIR 等。
7.4 级联森林结构
将多片森林的输出作为新的输入,传入另一层的多片森林,类似于 Stacking(著名集成学习方法)。但 Stacking 一般只对一到两层进行,多了容易过拟合,其并不能应用于深度模型中。
假设预测三个类别,每片森林输出一个三维的类别向量,层数 NNN 可以由交叉验证决定。
集成模型的集成:采用不同种类的森林来鼓励多样性,例如:
- 随机森林:分裂时随机选取 ddd 个特征,然后选择最佳特征;
- 完全随机森林:随机选择一个特征进行分裂。
类别向量的生成 :对于 kkk 分类任务,每片森林输出 kkk 维向量,对应每个类别的分类概率。
滑动窗口扫描:受到 CNNs 以及 RNNs 的启发,挖掘空间及序列的关联。所有 301 个样例都具有与原来样例相同的标签。针对高维数据,过多的样例以及过大的向量长度如何处理?可以采用特征采样(例如,对于样例进行降采样)。完全随机树不依赖于分裂特征选取,而随机森林对于分裂特征的扰动十分敏感。
7.5 总体架构与超参数
多粒度扫描 :每片森林 500 棵树;树的生长直到纯的叶子或者深度 = 100;滑动窗口大小 d/16,d/8,d/4d/16, d/8, d/4d/16,d/8,d/4。
级联:每片森林 500 棵树;树的生长直到纯的叶子。
超参数:在实验中,gcForest 对于所有数据都使用相同的超参数,而 DNNs 对于每个数据集都进行了精细的调参。
7.6 实验结果
gcForest 在以下任务上表现优异:
- 人脸识别(ORL);
- 图像识别(MNIST);
- 手掌运动识别(sEMG);
- 音乐分类(GTZAN);
- 情感分类(IMDB);
- 低维数据(特征:16,14,8)。
在图像分类(CIFAR-10,彩色 32×32 的图片,训练 50000 张 10 类的图片,测试 10000 张图片)上,gcForest 已经是非 DNN 方法中效果最好的方法。DNNs 方法在图像相关的任务中效果极好,但深度森林在许多其他任务中会更有帮助。
7.7 gcForest 和深度森林
gcForest 作为集成模型的成功应用,差异性是集成模型的关键,gcForest 几乎使用了所有策略来增加模型的差异性。gcForest 只是深度森林方法的开始,深度森林有许多可能性去探索,在许多其他任务中可以尝试。
8. 术语与关键概念索引
下表汇总了本文出现的核心术语,标注其在正文中首次出现的章节编号,并给出简洁解释,方便读者快速回顾与定位:
| 术语 | 首次出现章节 | 一句话解释 |
|---|---|---|
| 集成学习(Ensemble Learning) | 1. 引言 | 通过构建并组合多个"不同的"学习器,达到比单个学习器更好的泛化效果。 |
| 偏差-方差分解(Bias-Variance Decomposition) | 2.1 | 将期望预测误差分解为噪声、偏差平方与方差三项,用于分析模型误差来源。 |
| Bagging(Bootstrap Aggregating) | 2.2 | 对训练数据做自举采样,并行训练多个基学习器后取平均/投票,偏差不变、降低方差。 |
| 自举采样(Bootstrap) | 2.2 | 从原始数据集中有放回地随机抽取样本,构成多个训练子集以增加模型多样性。 |
| 解耦合(de-correlated) | 2.3 | 通过随机选择分裂候选特征,降低树与树之间的相关性,从而减小集成方差。 |
| 随机森林(Random Forest) | 2.3 | 在 Bagging 基础上,分裂时随机选择特征子集构建解耦合决策树后集成。 |
| 广义加性模型(Additive Models) | 3.2 | 以 F(x)=∑m=1Mfm(x)F(x) = \sum_{m=1}^{M} f_m(x)F(x)=∑m=1Mfm(x) 的形式逐步叠加基学习器的统一加性框架。 |
| Boosting | 3.1 | 串行训练基学习器,每个新学习器聚焦前序模型的错误,逐步最小化损失函数。 |
| AdaBoost | 4.1 | 通过最小化指数损失 J(F)=Ee−yF(x)J(F) = \mathbb{E}e\^{-yF(x)}J(F)=Ee−yF(x) 自适应调整样本权重,是 Boosting 的经典实现。 |
| 指数损失(Exponential Loss) | 4.1 | AdaBoost 最小化的目标函数,与逻辑交叉熵损失在二阶泰勒级数上等价。 |
| GBDT 梯度提升决策树 | 6.1 | 以决策树为基学习器的提升算法,通过生成下一棵树来最小化当前损失。 |
| 泰勒级数逼近(Taylor Expansion) | 6.2 | 利用一阶梯度 gig_igi 与二阶梯度 hih_ihi 对目标函数做近似,是 XGBoost 推导的核心技巧。 |
| 树结构复杂度惩罚 | 6.3 | 以 Ω(ft)=γT+12λ∑j=1Twj2\Omega(f_t) = \gamma T + \frac{1}{2}\lambda \sum_{j=1}^{T} w_j^2Ω(ft)=γT+21λ∑j=1Twj2 惩罚叶子数与叶子权重,控制模型复杂度。 |
| XGBoost | 6.6 | 最有影响力且最有效的 GBDT 工程化工具包,支持正则化、并行与高效分裂点搜寻。 |
| 深度森林(Deep Forest) | 7.2 | 来自周志华教授团队的集成方法,探索不依赖反向传播的"深度"集成学习路径。 |
| gcForest(多粒度级联森林) | 7.2 | 以级联森林 + 多粒度扫描实现逐层特征变换的深度森林具体实现。 |
| 误差-分歧分解(Error-ambiguity decomposition) | 7.3 | 集成误差 = 平均个体误差 - 平均个体分歧,说明个体越准确越有差异,集成越佳。 |
| 级联森林结构(Cascade Forest) | 7.4 | 将多片森林的输出作为下一层输入,逐层堆叠,类似 Stacking 但可扩展到更深结构。 |
| 多粒度扫描(Multi-Grained Scanning) | 7.5 | 通过多种滑动窗口大小扫描原始特征,挖掘空间与序列关联,增强特征变换能力。 |
| 表示学习(Representation Learning) | 7.1 | DNNs 的本质,通过逐层特征变换学习对任务"足够好的表示"。 |
8. 总结
- Bagging 有效的原因是与原始模型相比偏差相同但是降低了方差;
- 集成学习通过构建和组合多个"不同的"学习器,达到更好的效果;
- 随机森林通过随机化节点分裂时的候选特征集合,从而增大集成学习的单模型多样性;
- Boosting 算法则直接通过最小化损失函数作为目标来构建下一个学习器,GBDT 则是通过构建下一棵树来最小化当前的损失;
- 深度森林则从深度这个维度进一步探索森林在堆叠的构架下树模型能否取得深度学习的卓越效果。