4.4 机器学习 - 集成学习

发布于:2025-09-08 ⋅ 阅读:(19) ⋅ 点赞:(0)

集成学习通过 “组合多个基础模型” 提升泛化能力,核心分为并行集成(Bagging)串行集成(Boosting)多层集成(Stacking) 三大范式,分别对应 “降方差”“降偏差”“兼顾偏差与方差” 三大优化目标,适用场景与实现逻辑差异显著。

一、Bagging:并行集成,专注降低方差(Bootstrap AGGregatING)

Bagging 的核心是 “用数据多样性抵消模型波动”,通过并行训练多个相同基础模型,最终平均 / 投票输出,主打 “提升模型稳定性”,对偏差影响极小。

1. 核心原理与流程

三步实现数据采样、并行训练与结果融合,关键在于 “有放回采样(Bootstrap)” 创造多样性:

  1. 数据采样:对含 m 个样本的原始训练集,有放回采样 m 次,生成 n 个不同的训练集(每个训练集样本有重复);
  2. 并行训练:用 n 个训练集,并行训练 n 个完全相同的基础模型(如决策树);
  3. 结果融合:
    • 回归任务:n 个模型预测结果取平均;
    • 分类任务:n 个模型预测结果投票(少数服从多数)。

(1−lim⁡m→∞(1−1/m)m=1−1/e≈63%)(1-\lim_{m \to \infty}(1-1/m)^m = 1-1/e \approx 63\%) (1mlim(11/m)m=11/e63%) 的样本会被采样到,未被采样的 “Out-of-Bag(OOB)样本” 可直接作为验证集,无需额外划分数据。

2. 代码实现(简化版)

from copy import deepcopy
import numpy as np
import pandas as pd  # 假设输入为DataFrame格式

class Bagging: 
    def __init__(self, base_learner, n_learners): 
        # 初始化n个相同基础模型(深拷贝避免参数共享)
        self.learners = [deepcopy(base_learner) for _ in range(n_learners)] 
        self.n_learners = n_learners
    
    def fit(self, X: pd.DataFrame, y: pd.Series): 
        # 循环模拟并行训练(实际工程中可多线程/多进程加速)
        for learner in self.learners: 
            # Bootstrap有放回采样:生成与原数据量相同的样本索引
            sample_indices = np.random.choice(
                np.arange(len(X)), size=len(X), replace=True
            )
            # 用采样数据训练单个基础模型
            learner.fit(X.iloc[sample_indices], y.iloc[sample_indices]) 
            
    def predict(self, X: pd.DataFrame) -> np.ndarray: 
        # 回归任务:多模型预测结果取平均
        preds = np.array([learner.predict(X) for learner in self.learners])  # 形状:(n_learners, 样本数)
        return preds.mean(axis=0)  # 按样本维度平均,输出形状:(样本数,)

3. 适用场景与典型案例

  • 核心作用:显著降低方差(多模型平均抵消单模型对数据的敏感波动),对偏差基本无影响;
  • 适配基础模型:仅对 “不稳定模型” 有效(如决策树、神经网络)—— 这类模型对训练数据细节敏感,数据微小变化会导致预测结果大幅波动;对 “稳定模型”(如线性回归)效果有限;
  • 典型案例:随机森林(Random Forest)—— 在 Bagging 基础上,对每个决策树的 “特征” 也进行随机采样(如每次分裂仅选 1/3 特征),进一步增加模型多样性,降低过拟合风险。

二、Boosting:串行集成,专注降低偏差

Boosting 的核心是 “逐步修正错误,强化弱模型”,通过串行训练多个弱模型(如浅层决策树),后一个模型聚焦前一个模型的错误样本,最终加权融合,主打 “提升模型准确性”。

1. 核心原理与流程

三步实现串行训练、错误聚焦与加权融合,关键在于 “样本权重调整”:

  1. 弱模型串行训练:按顺序训练 n 个弱模型(如深度≤3 的决策树),每个模型的训练依赖前一个模型的误差;
  2. 错误样本聚焦:通过调整样本权重(或重新采样),让后一个模型更关注前一个模型预测错误的样本(如错误样本权重升高,正确样本权重降低);
  3. 结果加权融合:根据每个弱模型的性能(误差率)分配权重(误差率越低,权重越高),最终预测结果为各模型预测值的加权和。

典型算法:

  • AdaBoost:通过 “样本权重更新” 聚焦错误 错误样本权重×(1/误差率),正确样本权重×误差率错误样本权重 \times(1 / 误差率), \quad 正确样本权重 \times 误差率错误样本权重×(1/误差率),正确样本权重×误差率
  • Gradient Boosting:通过 “拟合前一轮模型的残差” 聚焦错误 残差=真实值−前一轮预测值残差 = 真实值 - 前一轮预测值残差=真实值前一轮预测值,适用性更广。

2. Gradient Boosting:基于残差的经典实现

Gradient Boosting(梯度提升)是工业界最常用的 Boosting 算法,通过 “拟合残差” 优化偏差,引入 “学习率(η)” 控制修正幅度,避免过拟合。

(1)核心公式
  • 模型迭代公式:

    Ht+1(x)=Ht(x)+η⋅ft(x)\Large H_{t+1}(x) = H_t(x) + \eta \cdot f_t(x)Ht+1(x)=Ht(x)+ηft(x)

    • Ht(x)H_t(x)Ht(x):第 t 轮集成模型的预测值;
    • ft(x)f_t(x)ft(x):第 t 个弱模型(拟合Ht(x)H_t(x)Ht(x)的残差,即y−Ht(x)y - H_t(x)yHt(x));
    • η\etaη(学习率):控制ft(x)f_t(x)ft(x)的贡献度(通常取 0.01~0.1),避免单模型影响过大导致过拟合。
  • 残差意义:当使用 MSE(均方误差)作为损失函数时,残差 y−Ht(x)y - H_t(x)yHt(x) 等于损失函数对 Ht(x)H_t(x)Ht(x) 的负梯度 −∂L/∂Ht(x)-\partial L / \partial H_t(x)L/Ht(x),即梯度下降的方向 —— 本质是用 “残差” 替代 “梯度”,简化计算。

(2)代码实现(简化版)
from copy import deepcopy
import numpy as np
import pandas as pd

class GradientBoosting: 
    def __init__(self, base_learner, n_learners, learning_rate=0.1): 
        self.learners = [deepcopy(base_learner) for _ in range(n_learners)] 
        self.lr = learning_rate  # 学习率,控制每轮残差修正幅度
        self.n_learners = n_learners
    
    def fit(self, X: pd.DataFrame, y: pd.Series): 
        residual = y.copy().values  # 初始残差=真实值(第0轮模型预测为0)
        for learner in self.learners: 
            # 弱模型拟合当前残差(将残差视为“新的真实值”)
            learner.fit(X, residual) 
            # 更新残差:减去当前模型的修正量(修正量=模型预测值×学习率)
            residual -= self.lr * learner.predict(X) 
            
    def predict(self, X: pd.DataFrame) -> np.ndarray: 
        # 所有弱模型预测值加权求和(权重=学习率)
        preds = np.array([learner.predict(X) for learner in self.learners])  # 形状:(n_learners, 样本数)
        return preds.sum(axis=0) * self.lr  # 按样本维度求和,输出形状:(样本数,)

3. GBDT 与工程优化

  • GBDT(Gradient Boosting Decision Trees):以 “浅层 CART 树” 为弱模型的 Gradient Boosting,兼顾精度与可解释性,广泛用于推荐系统(CTR 预测)、金融风控(违约预测)等场景;
  • 工程优化算法:
    • XGBoost:引入 “树复杂度正则化”(L1/L2 正则)、“缺失值自动处理”,支持并行计算(特征分裂候选值并行),训练速度比传统 GBDT 快 5~10 倍;
    • LightGBM:采用 “直方图优化”(将连续特征离散为直方图)、“Leaf-wise 树生长”(优先分裂增益大的叶子节点),进一步提升训练效率,适合亿级样本场景。

三、Stacking:多层集成,兼顾偏差与方差

Stacking 的核心是 “用不同模型多样性 + 多层学习”,通过并行训练多个不同基础模型,将其输出作为新特征输入 “元模型”,兼顾 “稳定性” 与 “准确性”,灵活性高于 Bagging 和 Boosting。

1. 单层 Stacking:基础结构

(1)核心流程

三层结构实现 “基础模型特征提取 + 元模型融合”,关键在于 “不同基础模型” 与 “特征拼接”:

  1. 第一层(基础模型层):并行训练 n 个不同类型的基础模型(如 Random Forest、GBDT、MLP),每个模型输出预测结果(如分类任务输出类别概率,回归任务输出连续值);
  2. 特征拼接(Concat):将 n 个基础模型的预测结果拼接成 “新特征矩阵”(如 3 个基础模型 → 新特征维度 = 3);
  3. 第二层(元模型层):用 “新特征矩阵” 训练元模型(如逻辑回归、Dense 层),输出最终预测结果。
(2)结构示意图
# 单层Stacking结构(核心:不同基础模型+元模型融合)

                  元模型(如逻辑回归、Dense层)
                          👆
                  -------------------
                  |     Concat      |  # 拼接各基础模型的预测结果(新特征)
                  -------------------
                          👆
    ----------------  👆  ----------------  👆  ----------------
    | Random Forest |  |    GBDT     |  |    ...    |  |    MLP    |  # 不同类型基础模型
    ----------------  👆  ----------------  👆  ----------------
                          👆
                  -------------------
                  |     Inputs      |  # 原始输入特征(如用户特征、物品特征)
                  -------------------
(3)核心作用
  • 主要降低方差:通过 “不同类型基础模型” 的多样性(如树模型 + 神经网络),抵消单一模型的波动;
  • 对比 Bagging:Bagging 靠 “相同模型 + 数据采样” 创造多样性,Stacking 靠 “不同模型” 创造多样性,灵活性更高,可适配更多场景。

2. 多层 Stacking:进阶结构

(1)核心流程

在单层基础上增加层级,实现 “逐层修正偏差”:

  1. 多层级联:每一层的输出作为下一层的输入(如 L1 层输出 → L2 层输入,L2 层输出 → L3 层输入);
  2. 每层多样性:每一层可使用不同基础模型(如 L1 用树模型,L2 用线性模型),高层元模型聚焦修正低层的偏差。
(2)结构示意图
# 多层Stacking结构(核心:层级联+逐层修正偏差)

                  L3:元模型(如Dense层)
                          👆
                  -------------------
                  |     Concat      |  # L2层各模型预测结果拼接
                  -------------------
                          👆
    ----------------  👆  ----------------  👆  ----------------
    | Random Forest |  |    GBDT     |  |    ...    |  |    MLP    |  # L2层基础模型
    ----------------  👆  ----------------  👆  ----------------
                          👆
                  -------------------
                  |     Concat      |  # L1层各模型预测结果拼接
                  -------------------
                          👆
    ----------------  👆  ----------------  👆  ----------------
    | Random Forest |  |    GBDT     |  |    ...    |  |    MLP    |  # L1层基础模型
    ----------------  👆  ----------------  👆  ----------------
                          👆
                  -------------------
                  |     Inputs      |  # 原始输入特征
                  -------------------
(3)过拟合解决策略

多层 Stacking 的高层(如 L2、L3)因 “新特征维度低、数据量少” 易过拟合,需针对性优化:

  1. 分层数据划分:将数据集分为 A、B 两组,A 训练 L1 层,B 训练 L2 层(避免 L2 层看到 L1 层的训练数据,导致数据泄露);
  2. K 折 Bagging 重复:
    • 对每一层,用 K 折交叉验证训练 K 个模型,取 “Out-of-Fold(OOF)预测结果” 作为下一层输入(如 K=5,每个样本仅用 “未参与训练的 1 折模型” 预测,避免过拟合);
    • 重复 n 次 K 折过程,对同一样本的 n 次预测取平均,进一步降低波动。

四、三大集成范式对比

集成范式 核心目标(降低偏差 / 方差) 计算成本 并行性 关键特点 适用场景
Bagging 方差(主要) n(n = 基础模型数) 高(n 个模型并行) 相同基础模型 + Bootstrap 采样,稳定优先 模型波动大、需提升稳定性(如决策树)
Boosting 偏差(主要) n 低(串行训练) 弱模型串行 + 错误聚焦,精度优先 模型欠拟合、需提升准确性(如浅层模型)
单层 Stacking 方差(主要) n 高(基础模型并行) 不同基础模型 + 元模型融合,灵活优先 需平衡稳定与灵活(如多模态数据)
多层 Stacking 偏差 + 方差(兼顾) n×l×k(n = 模型数,l = 层数,k=K 折) 中(每层内并行) 层级联 + 逐层修正,需防过拟合 高精度场景(如竞赛、核心业务预测)

网站公告

今日签到

点亮在社区的每一天
去签到