梯度提升机由于其高度的灵活性,容易对训练数据过拟合。缓解此问题的一个有效且常用方法是通过数据抽样在树构建过程中引入随机性,这种方法常被称为随机梯度提升 (SGB)。这种思路借鉴了Bagging(自助聚合)和随机梯度下降(SGD),其中通过数据抽样引入随机性可以提升模型的泛化能力和稳定性。随机梯度提升在每次提升迭代 $m$ 中,不是使用整个训练数据集来计算伪残差并拟合新的基学习器(树),而是仅使用一部分随机抽取(不放回)的训练样本。同样,它也可以抽样一部分特征。数据抽样为何有效:降低方差数据抽样的主要作用是降低方差。通过在数据和/或特征的略微不同子集上训练每棵树,我们降低了集成中树之间的关联性。每棵树对数据分布和前面树留下的误差模式(伪残差)都有一个略微不同的“视角”。这可以防止集成模型过度适应完整训练集中的噪声或特定模式。虽然每棵单独的树由于训练数据较少可能略显不足(偏差较高),但作为一个整体,集成模型具有更好的泛化能力,并在未见数据上表现更好。数据抽样的种类梯度提升中实现数据抽样主要有两种方式:行抽样 (抽样比例):这包括在拟合每棵新树之前,不放回地随机选择一部分训练数据实例(行)。在Scikit-learn、XGBoost和LightGBM等库中,这通常由名为subsample或bagging_fraction的超参数控制。典型值通常在0.5到0.8之间,意味着每棵树的拟合使用50%到80%的数据。将subsample设置为1.0将恢复为使用所有数据点训练每棵树的标准梯度提升。将其设置为低于1.0会引入随机性,有助于防止过拟合,并能显著加快训练速度,尤其是在大型数据集上,因为每次迭代处理的数据量减少了。但设置过低可能导致欠拟合或收敛速度变慢。列抽样 (特征比例):这包括在构建每棵树时,甚至在每个节点寻找最佳分裂时,选择随机一部分特征(列)来考虑。常见超参数包括:colsample_bytree:每棵树构建时一次性抽样特征的比例。colsample_bylevel:树中每个新层级抽样特征的比例。colsample_bynode (XGBoost) 或 feature_fraction_bynode (LightGBM):每个节点分裂时抽样特征的比例。列抽样在高维数据集中特别有效,因为这些数据集中许多特征可能不相关或冗余。它防止模型过度依赖少数高预测性的特征。与行抽样类似,它降低方差,并通过减少需要评估的特征分裂数量来加快训练过程。典型值也通常在0.5到1.0的范围。下图展示了行抽样和列抽样如何融入提升过程。digraph SGB { rankdir=TB; node [shape=box, style=rounded, fontname="helvetica", fontsize=10]; edge [fontsize=10, fontname="helvetica"]; Start [label="从初始模型 F₀(x) 开始", shape=ellipse, style=filled, fillcolor="#e9ecef"]; Data [label="完整训练数据\n(X, y)", shape=cylinder, style=filled, fillcolor="#a5d8ff"]; LoopStart [label="对于 m = 1 到 M:", shape=plaintext]; ComputeRes [label="计算伪残差\nrᵢ = -[∂L(yᵢ, F(xᵢ))/∂F(xᵢ)]", style=filled, fillcolor="#fff3bf"]; SampleRows [label="抽样行比例\n(subsample < 1.0)", style=filled, fillcolor="#b2f2bb"]; SampleCols [label="抽样列比例\n(colsample_by* < 1.0)", style=filled, fillcolor="#ffd8a8"]; SampledData [label="抽样数据与特征\n(X', r')", shape=cylinder, style=filled, fillcolor="#fcc2d7"]; FitTree [label="拟合基学习器(树)hₘ(x)\n到抽样数据 (X', r')", style=filled, fillcolor="#bac8ff"]; UpdateModel [label="更新集成模型\nFₘ(x) = Fₘ₋₁(x) + η * hₘ(x)", style=filled, fillcolor="#d0bfff"]; LoopEnd [label="循环结束", shape=plaintext]; FinalModel [label="最终模型 F_M(x)", shape=ellipse, style=filled, fillcolor="#e9ecef"]; Start -> Data; Data -> LoopStart [style=invis]; LoopStart -> ComputeRes [style=invis]; Data -> ComputeRes [label=" 使用 Fₘ₋₁(x)"]; ComputeRes -> SampleRows; SampleRows -> SampleCols; SampleCols -> SampledData; SampledData -> FitTree; FitTree -> UpdateModel; UpdateModel -> LoopEnd [style=invis]; LoopEnd -> ComputeRes [label=" 下次迭代", style=dashed]; UpdateModel -> FinalModel [label=" 经过 M 次迭代后"]; }随机梯度提升算法的流程图,展示了在每次提升迭代中如何融入行抽样和列抽样。与其他集成方法的关系SGB中使用的数据抽样方法与随机森林中的方法有相似之处。随机森林对行使用自助抽样(有放回抽样),并在每次分裂时随机选择特征。SGB通常对行使用不放回抽样,并为特征抽样提供了更灵活的选项(按树、按层级、按节点)。核心区别在于,提升算法是顺序构建树来纠正之前的错误,而随机森林是并行独立构建树。实际考量与调优行抽样和列抽样是有效的正则化工具,通常与收缩(学习率)和树复杂度限制(如max_depth、min_child_weight)结合使用。相互作用: 较低的学习率通常需要更多的提升轮次(n_estimators),并可能与较低的数据抽样率配合良好。反之,较高的数据抽样率可能允许略高的学习率或更少的树。调优: subsample、colsample_bytree等的最佳值高度依赖于数据。它们通常与学习率(eta或learning_rate)、树深度(max_depth)和提升轮次数量(n_estimators)等其他重要超参数一起通过交叉验证进行调优,并常通过提前停止来确定。网格搜索、随机搜索或贝叶斯优化(第8章介绍)等方法对于找到好的组合至关重要。计算成本: 数据抽样通常会减少每次迭代的训练时间,特别是处理大量特征时的列抽样。总训练时间取决于抽样率与收敛所需的提升轮次数量之间的关系。总之,随机梯度提升通过行抽样和列抽样引入随机性,有效降低了最终集成模型的方差。这使得模型对特定的训练数据不那么敏感,提升了其对新的、未见示例的泛化能力。此外,它通常还带来了加快训练过程的好处。熟练运用和调优这些数据抽样参数是构建高精度梯度提升模型的重要一步。