梯度提升决策树(GBDT)算法的原理与构建过程
题目描述
梯度提升决策树(Gradient Boosting Decision Tree, GBDT)是一种强大的集成学习算法,它通过迭代地构建多棵决策树(通常为CART回归树)来组合成一个强学习器。每一棵新树都致力于修正之前所有树组合的预测残差(即负梯度方向),最终将所有树的预测结果进行加权求和,得到最终预测。GBDT在回归和分类任务中都表现出色,是许多机器学习竞赛中的常用模型。
解题过程
1. 算法核心思想
GBDT属于Boosting家族,其核心思想是“加法模型”与“前向分步算法”。它通过多轮迭代,每一轮产生一个弱学习器(一棵决策树),并让当前弱学习器去学习之前所有弱学习器组合的“残差”(在GBDT中,这个“残差”被定义为损失函数的负梯度),从而逐步降低整体模型的偏差。
2. 问题设定与初始化
我们以回归问题为例进行说明。假设训练数据集为 \(D = \{ (x_1, y_1), (x_2, y_2), ..., (x_n, y_n) \}\),我们的目标是学习一个模型 \(F(x)\),使得损失函数 \(L(y, F(x))\) 的期望值最小。常用的损失函数是平方误差损失:\(L(y, F(x)) = \frac{1}{2}(y - F(x))^2\)。
首先,我们需要初始化一个弱模型 \(F_0(x)\),它通常是一个常数。对于平方误差损失,最优的初始值就是所有训练样本标签的均值:
\[F_0(x) = \underset{\gamma}{\arg\min} \sum_{i=1}^n L(y_i, \gamma) = \frac{1}{n} \sum_{i=1}^n y_i \]
这个初始模型 \(F_0(x)\) 是所有样本的一个粗略估计。
3. 迭代构建过程(M轮迭代)
接下来,我们进行 M 轮迭代(即构建 M 棵树)。对于第 \(m\) 轮(\(m = 1, 2, ..., M\)):
- a. 计算伪残差(负梯度)
对于每一个训练样本 \(i\)(\(i = 1, 2, ..., n\)),计算损失函数在当前模型 \(F_{m-1}(x_i)\) 下的负梯度,这个值被称为“伪残差” \(r_{im}\)。
\[ r_{im} = -\left[\frac{\partial L(y_i, F(x_i))}{\partial F(x_i)}\right]_{F(x)=F_{m-1}(x)} \]
对于平方误差损失函数 $ L(y, F) = \frac{1}{2}(y - F)^2 $,其负梯度计算非常简单:
\[ r_{im} = -\left[ \frac{\partial (\frac{1}{2}(y_i - F)^2)}{\partial F} \right]_{F=F_{m-1}} = -\left[ -(y_i - F) \right]_{F=F_{m-1}} = y_i - F_{m-1}(x_i) \]
所以,对于平方损失,伪残差就是真实值 $ y_i $ 与当前模型预测值 $ F_{m-1}(x_i) $ 之间的普通残差。
-
b. 拟合一棵新的决策树
我们用上一步计算出的伪残差 \(r_{im}\) 作为新的“目标值”,来训练一棵新的决策树 \(h_m(x)\)。这棵树的输入是原始特征 \(x_i\),输出目标是伪残差 \(r_{im}\)。这棵树的目标是学习如何从 \(x\) 预测出当前模型的“错误”或“不足”的部分。
这棵树通常是一棵有 \(J\) 个叶子节点的CART回归树。训练完成后,这棵树会将输入空间划分成 \(J\) 个互不相交的区域 \(R_{1m}, R_{2m}, ..., R_{Jm}\)。 -
c. 为树的每个叶子节点计算最优输出值
对于第 \(m\) 棵树划分出的每一个叶子节点区域 \(R_{jm}\)(\(j = 1, 2, ..., J\)),我们需要计算一个最佳的输出值 \(\gamma_{jm}\)。这个值是通过最小化该叶子节点内所有样本的损失来确定的:
\[ \gamma_{jm} = \underset{\gamma}{\arg\min} \sum_{x_i \in R_{jm}} L(y_i, F_{m-1}(x_i) + \gamma) \]
这个公式的含义是:找到一个值 $ \gamma $,使得将 $ \gamma $ 加到该叶子节点内所有样本的当前预测值 $ F_{m-1}(x_i) $ 上之后,这些样本的总损失最小。
对于平方误差损失,这个最优值就是落入该叶子节点的所有样本的伪残差 $ r_{im} $ 的均值:
\[ \gamma_{jm} = \frac{\sum_{x_i \in R_{jm}} r_{im}}{\sum_{x_i \in R_{jm}} 1} = \text{平均}(r_{im} \mid x_i \in R_{jm}) \]
- d. 更新模型
我们将新训练的树 \(h_m(x)\) 及其叶子节点的输出值 \(\gamma_{jm}\) 加入到现有模型中,从而更新模型。为了控制每棵树的贡献,防止过拟合,我们引入一个学习率 \(\nu\)(也叫步长或收缩系数,通常 \(0 < \nu \leq 1\))。
\[ F_m(x) = F_{m-1}(x) + \nu \cdot h_m(x) \]
其中,$ h_m(x) $ 对于样本 $ x $ 的输出,就是 $ x $ 所属的叶子节点 $ R_{jm} $ 对应的 $ \gamma_{jm} $ 值。
学习率 $ \nu $ 越小,模型收敛越慢,但通常泛化能力更好。
4. 得到最终模型
经过 M 轮迭代后,我们得到了最终的强学习器 \(F_M(x)\),它是由初始模型和 M 棵树的加权和构成的:
\[F(x) = F_M(x) = F_0(x) + \nu \sum_{m=1}^M h_m(x) \]
5. 扩展到分类问题
对于分类问题(例如二分类),GBDT的核心思想不变,但损失函数和初始化方式会改变。
- 损失函数:通常使用对数似然损失(Log Loss)。对于二分类,模型 \(F(x)\) 输出的是对数几率(Log-Odds),通过Sigmoid函数可以转化为概率 \(p(x) = \sigma(F(x)) = 1/(1+e^{-F(x)})\)。
- 初始化:\(F_0(x)\) 初始化为一个常数,使得初始预测概率为整个数据集的正例比例的对数几率。
- 伪残差计算:负梯度不再是简单的 \(y - p\),而是 \(y_i - p(x_i)\)(对于对数似然损失)。
- 叶子节点输出值:计算方式更为复杂,需要通过牛顿法等方法近似求解,但思想同样是最小化该叶子节点内样本的损失。
总结
GBDT的构建过程是一个循序渐进、不断修正错误的过程。每一棵新树都像一个“补丁”,专门用于修复之前所有模型组合在一起时产生的“漏洞”(即残差)。通过控制迭代轮数(树的数量)、学习率、每棵树的最大深度等超参数,我们可以在偏差和方差之间取得平衡,构建出强大且鲁棒的预测模型。后续的XGBoost、LightGBM和CatBoost等算法都是在GBDT这一思想基础上的优化和改进。