集成学习(Ensemble Learning)¶
集成学习的核心思想:三个臭皮匠,顶个诸葛亮。 将多个"弱"模型组合起来,形成一个"强"模型。集成方法几乎是机器学习竞赛(如 Kaggle)中的制胜法宝。
为什么集成有效?¶
直觉理解
假设你有 5 个互相独立的分类器,每个的准确率是 70%。让它们投票决定最终结果。
至少 3 个正确(多数投票正确)的概率:
5 个 70% 的模型组合后达到了 83.7%!关键条件是模型之间要足够不同(多样性)。
集成学习主要有两大流派:Bagging 和 Boosting。
graph TD
A[集成学习] --> B[Bagging]
A --> C[Boosting]
B --> B1[随机森林]
C --> C1[AdaBoost]
C --> C2[GBDT]
C --> C3[XGBoost]
C --> C4[LightGBM]
一、Bagging(Bootstrap Aggregating)¶
核心思想¶
并行训练多个模型,每个模型用不同的数据子集,最后投票/取平均。
算法步骤¶
有放回采样(Bootstrap)
每次采样时,已抽到的样本会放回去,所以同一个样本可能被多次抽到,也可能一次都没被抽到。
数学上,每个样本不被抽到的概率为 \((1 - \frac{1}{n})^n \approx \frac{1}{e} \approx 36.8\%\)
也就是说,大约 63.2% 的数据会出现在每个子集中,剩余 36.8% 可作为袋外数据(OOB) 用于评估。
为什么 Bagging 有效?¶
Bagging 主要用来降低方差。单个决策树方差很大(数据稍有变化,树的结构可能完全不同),通过平均多棵树的预测,方差大幅降低。
二、随机森林(Random Forest)¶
在 Bagging 基础上加了什么?¶
随机森林 = Bagging + 特征随机。在每次分裂节点时,不是从所有特征中选最优的,而是从随机选取的一部分特征中选最优的。
两层随机性¶
| 层次 | 做法 | 效果 |
|---|---|---|
| 数据随机 | Bootstrap 采样,每棵树用不同数据 | 增加模型多样性 |
| 特征随机 | 每次分裂只考虑 \(\sqrt{d}\) 个特征(分类)或 \(d/3\) 个特征(回归) | 进一步增加多样性,降低树之间的相关性 |
特征重要性¶
随机森林天然可以给出特征重要性排名,这是它的一大优势:
- 基于不纯度(Gini Importance):特征在所有树中减少不纯度的总量
- 基于排列(Permutation Importance):随机打乱某个特征的值,看模型性能下降了多少
优缺点¶
| 优点 | 缺点 |
|---|---|
| 效果好,几乎不需要调参 | 模型较大,预测速度比单棵树慢 |
| 不容易过拟合 | 对高维稀疏数据效果一般 |
| 可以处理缺失值 | 不如 Boosting 系列精度高(通常) |
| 给出特征重要性 | 不能很好地处理线性关系 |
| 可并行训练,速度快 | — |
三、Boosting(提升法)¶
核心思想¶
与 Bagging 的并行策略不同,Boosting 是串行的:每个新模型都专注于修正前面模型犯过的错误。
类比
就像一个学生做完练习题后,老师不会让他重做全部题目,而是让他只重做做错的题。每轮学习都集中精力攻克薄弱环节。
Bagging vs Boosting¶
| 特性 | Bagging | Boosting |
|---|---|---|
| 训练方式 | 并行、独立 | 串行、依赖前一个 |
| 数据采样 | 随机采样(均等权重) | 加权采样(错误样本权重更高) |
| 降低什么 | 方差 | 偏差(也降方差) |
| 过拟合风险 | 低 | 较高(需要早停) |
| 代表算法 | 随机森林 | AdaBoost、GBDT、XGBoost |
四、AdaBoost(自适应提升)¶
核心机制¶
- 初始时,所有训练样本权重相等
- 训练一个弱分类器(如一层决策树 / 决策桩)
- 增大被误分类样本的权重,减小被正确分类样本的权重
- 在新的权重分布下训练下一个弱分类器
- 最终将所有弱分类器加权投票(准确率高的分类器权重大)
权重更新公式¶
分类器 \(t\) 的误差率:
分类器的权重(话语权):
样本权重更新:
- 分对的样本:权重减小(下次少关注)
- 分错的样本:权重增大(下次重点关注)
最终预测¶
五、GBDT(梯度提升决策树)¶
核心思想¶
GBDT 的每棵新树不是去拟合原始目标,而是去拟合前面所有树的残差(预测误差)。
直觉理解
你猜一个人的年龄:
- 第1棵树预测:30 岁(实际 25 岁,残差 = -5)
- 第2棵树学习残差,预测修正:-4(累计预测 30 + (-4) = 26,残差 = -1)
- 第3棵树继续修正:-0.8(累计预测 26 + (-0.8) = 25.2,更接近了!)
每棵树都在弥补之前的不足,逐步逼近真实值。
算法流程¶
初始化:F₀(x) = 常数(如目标均值)
对 t = 1, 2, ..., T:
1. 计算负梯度(残差):rᵢ = yᵢ - Fₜ₋₁(xᵢ)
2. 用决策树拟合残差:hₜ(x) ≈ rᵢ
3. 更新模型:Fₜ(x) = Fₜ₋₁(x) + η · hₜ(x)
最终预测:F_T(x) = F₀(x) + η·h₁(x) + η·h₂(x) + ... + η·h_T(x)
其中 \(\eta\) 是学习率(shrinkage),通常设为 0.01-0.3。较小的学习率需要更多的树,但通常泛化更好。
为什么叫"梯度"提升?¶
因为残差就是损失函数对模型预测值的负梯度:
对于 MSE 损失,负梯度 = \(y_i - F(x_i)\),正好就是残差。
六、XGBoost(极端梯度提升)¶
比 GBDT 强在哪?¶
XGBoost 是 GBDT 的工程优化版,在效果和速度上都有提升:
| 改进 | 说明 |
|---|---|
| 正则化 | 目标函数中加入了树复杂度的惩罚项,防止过拟合 |
| 二阶梯度 | 使用泰勒展开的二阶导数信息,收敛更快 |
| 列采样 | 类似随机森林,每棵树只用部分特征 |
| 缺失值处理 | 自动学习缺失值应该往左还是往右分 |
| 并行化 | 特征分裂时并行计算,大幅加速 |
| 剪枝策略 | 先生长再剪枝(后剪枝),比预剪枝更优 |
目标函数¶
其中正则化项:
- \(T\):叶子节点数(控制树的复杂度)
- \(w_j\):叶子权重
- \(\gamma\):控制分裂的最小增益
- \(\lambda\):L2 正则化系数
关键超参数¶
| 参数 | 含义 | 调参建议 |
|---|---|---|
n_estimators |
树的数量 | 100-1000,配合早停 |
max_depth |
树的最大深度 | 3-10,通常 6 |
learning_rate |
学习率 | 0.01-0.3 |
subsample |
每棵树用多少比例的数据 | 0.6-1.0 |
colsample_bytree |
每棵树用多少比例的特征 | 0.6-1.0 |
min_child_weight |
叶子节点最小权重和 | 防止过拟合 |
gamma |
分裂的最小增益 | 防止过拟合 |
七、LightGBM(补充)¶
LightGBM 是微软开发的 GBDT 框架,比 XGBoost 更快:
| 特性 | XGBoost | LightGBM |
|---|---|---|
| 树的生长策略 | 按层生长(Level-wise) | 按叶子生长(Leaf-wise) |
| 特征分裂 | 预排序 | 直方图加速 |
| 训练速度 | 快 | 更快(通常 2-10x) |
| 内存占用 | 较大 | 较小 |
| 大数据集 | 适用 | 更适用 |
八、Stacking(模型堆叠)¶
核心思想¶
用多个不同的模型作为第一层,将它们的预测结果作为新特征,再训练一个第二层模型(元学习器)来做最终预测。
训练数据
/ | \
模型A 模型B 模型C ← 第一层(基学习器)
| | |
预测A 预测B 预测C
\ | /
[预测A, 预测B, 预测C] ← 作为新特征
|
元模型 ← 第二层(元学习器)
|
最终预测
实践建议
- 第一层用差异性大的模型(如 随机森林 + SVM + KNN)
- 第二层通常用简单模型(如逻辑回归),避免过拟合
- 第一层的预测必须用交叉验证产生,否则会数据泄露
集成方法速查表¶
| 方法 | 核心策略 | 适合基模型 | 主要降低 | 过拟合风险 |
|---|---|---|---|---|
| Bagging | 并行 + 投票 | 高方差模型(决策树) | 方差 | 低 |
| 随机森林 | Bagging + 特征随机 | 决策树 | 方差 | 低 |
| AdaBoost | 串行 + 加权 | 弱分类器(决策桩) | 偏差 | 中 |
| GBDT | 串行 + 拟合残差 | 决策树 | 偏差 | 中高 |
| XGBoost | GBDT + 正则化 + 优化 | 决策树 | 偏差+方差 | 中 |
| Stacking | 分层组合 | 多种不同模型 | 偏差+方差 | 中高 |