本笔记介绍机器学习中常见的集成学习:Bagging和Boosting。
@[toc]
集成学习(Ensemble Learning)概述
集成学习是一种通过组合多个模型(通常是弱模型)来提升整体预测性能的技术 ,主要分为 Bagging 和 Boosting 两类方法。Bagging 和 Boosting 是构建强大的集成模型的基础,并衍生出了多种经典的算法,如随机森林、AdaBoost、Gradient Boosting、XGBoost 和 GBDT。
Bagging 和 Boosting 的对比
属性 | Bagging | Boosting |
---|---|---|
模型训练方式 | 并行训练多个模型 | 串行训练多个模型 |
每次训练的数据集 | 每次从原始数据集进行有放回随机采样 生成不同的子集 | 每次使用相同的数据集,但样本的权重会随错误分类情况调整 |
关注样本方式 | 每个模型使用相同的样本权重 | 不同的权重,后续模型重点关注前一模型的错误 |
结果集成方式 | 平均(回归)或投票(分类) | 加权组合模型 |
主要优点 | 降低方差,减少过拟合 | 降低偏差,提高模型精度,减少欠拟合 |
主要缺点 | 对偏差问题无明显改善 | 对噪声敏感,训练时间长 |
代表算法 | 随机森林 | AdaBoost、Gradient Boosting |
- Bagging :通过并行训练多个模型,降低模型的方差,更适合高方差模型(减轻过拟合),如随机森林是其经典应用。
- Boosting :通过串行训练多个模型,逐步提升模型性能,更适合提升高偏差模型(减轻欠拟合),经典算法包括 AdaBoost 和 Gradient Boosting。
高方差是过拟合,高偏差是欠拟合
Bagging 算法
什么是 Bagging?
Bagging(Bootstrap Aggregating)是一种并行集成学习方法 ,它通过在训练集中多次随机采样(有放回的抽样)生成多个不同的子集,并在每个子集上训练模型,最终通过平均(回归)或投票(分类)得到集成模型的预测结果。
Bagging 的主要特点
- 并行训练:每个模型是独立训练的,因此可以并行计算。
- 有放回的随机采样。
- 减小方差,降低过拟合:通过组合多个模型,可以有效降低模型的方差,提高稳定性。
- 不易过拟合,容易欠拟合:对于不稳定的模型(如决策树),Bagging 能有效减少过拟合的风险。
常用的 Bagging 算法
随机森林(Random Forest)
- 随机森林是在 Bagging 的基础上,对每个子模型(决策树)进一步随机选择特征 进行训练。它通过引入特征选择的随机性,进一步减少了模型的方差,提高了模型的泛化能力。
- 工作原理 :
- 从训练集中随机有放回地抽样,生成多个子集。
- 对每个子集训练一个决策树模型。
- 在每棵树的节点划分时,随机选择部分特征进行划分。
- 对于分类任务 ,通过所有树的投票结果 决定最终的类别;对于回归任务 ,通过所有树的平均值决定最终的预测值。
Boosting 算法
什么是 Boosting?
Boosting 是一种串行集成 学习方法,它通过逐步训练一系列弱模型,每个模型都试图纠正前一个模型的错误预测 。最终的集成模型是所有弱模型的加权和。
Boosting 的主要特点
- 串行训练:模型是依次训练的,后一个模型依赖于前一个模型的结果。
- 减小偏差,减轻欠拟合:通过加权训练,Boosting 能够逐步减小模型的偏差。
- 易于过拟合:由于模型不断地优化错误样本,容易在训练数据上表现过好,需要使用正则化等技术来防止过拟合。
常用的 Boosting 算法
算法 | 原理 | 优点 | 缺点 | 使用场景 |
---|---|---|---|---|
AdaBoost | 通过调整样本权重 ,训练多个弱分类器,并加权组合。 | 简单易实现,适合分类任务。 | 对噪声敏感,容易过拟合,需控制弱分类器数量。 | 分类任务,如垃圾邮件分类等。 |
GB | 泛指梯度提升框架 ,通过梯度下降拟合残差优化模型。 | 提升模型精度,减少偏差,适合分类和回归任务。 | 训练时间较长,容易过拟合。 | 分类和回归,非线性数据场景。 |
GBDT | 基于决策树的梯度提升方法,通过拟合残差优化模型。 | 强大回归能力,处理复杂非线性关系。 | 训练时间长,需调参(树的数量、学习率等)。 | 分类和回归,复杂特征场景。 |
XGBoost | GBDT 的增强版 ,引入正则化、并行化和缺失值处理等优化。 | 训练速度快,性能好,适用于大规模数据集。 | 模型复杂,超参数调优困难。 | 大规模数据下的分类和回归任务。 |
LightGBM | GBDT 的优化版 ,基于直方图算法 和叶子节点生长策略。 | 训练速度极快,内存占用少,适合大数据集和高维数据 | 对小数据集不适合,Leaf-wise 策略可能导致过拟合,需调参。 | 大规模数据下的分类、回归和排序任务。 |
- AdaBoost :适合分类任务 ,通过加权样本聚焦错分类,但容易过拟合。
- GB :梯度下降框架,适合分类和回归,但训练慢。
- GBDT :是 GB 框架的一个具体实现 ,专用决策树做弱学习器,处理复杂关系,训练时间长。
- XGBoost:GBDT 的增强版,速度快,适合大规模数据,但需复杂调参。
- LightGBM:基于 GBDT 的改进算法,通过直方图方法加速训练,适合大规模数据和高维特征场景,具有极快的训练速度,但容易过拟合,需调参。
AdaBoost(Adaptive Boosting)
-
原理 : AdaBoost 是最早的 Boosting 算法之一,最常用于二分类问题 。AdaBoost 通过迭代训练弱分类器 (通常是决策树桩 ),每一轮迭代中,AdaBoost 会调整样本的权重 ,增加错误分类样本的权重,使得下一轮的弱分类器能够更关注那些难以分类的样本。
-
决策树桩是一种极其简单的决策树,它只有一个划分节点和两个叶节点。也就是说,决策树桩仅能基于单一特征进行一次划分,将数据集分为两个部分。
-
主要特点 : 权重调整 :每轮训练后,增加误分类样本的权重 ,使下一轮分类器更注重这些难分类的样本。 组合方式 :将每个弱分类器的预测结果以加权方式组合 起来,得到最终的预测结果。 优点 :容易实现,能够有效提高分类精度。 缺点:对噪声数据比较敏感,因为噪声数据会反复加重权重,容易过拟合,需要控制弱分类器的数量。
-
算法步骤:
- 初始化 样本权重,使每个样本的权重相等。
- 训练一个弱分类器,计算该分类器的错误率。
- 更新样本权重 ,使错误分类 的样本权重增加,正确分类的样本权重减少。
- 计算该分类器的权重 (与错误率相关),并将其加入到最终模型中。
- 重复上述步骤,直到达到预定的弱分类器数量或错误率阈值。
GB(Gradient Boosting)
- 原理 : Gradient Boosting 是一种通过优化损失函数 的 Boosting 方法。与 AdaBoost 直接调整样本权重不同 ,Gradient Boosting 是通过拟合当前模型的残差(即模型预测与真实值的差异)来训练下一个弱分类器的。
- 主要特点 :
- 残差拟合 :每一步都会训练 一个新的弱分类器 ,拟合之前模型的残差,逐步减少模型的预测误差。
- 损失函数最小化 :Gradient Boosting 的目标是最小化损失函数 (如平方误差、交叉熵),每一步的优化都是沿着梯度下降的方向。
- 优点:在回归和分类问题中效果非常好,能灵活选择损失函数。
- 缺点:训练时间较长,对超参数比较敏感,容易过拟合。
- 算法步骤 :
- 初始化模型: 一开始我们建立一个简单的模型,比如使用训练数据集的均值作为初始预测值。
- 计算残差 : 在每一轮迭代中,我们先计算现有模型的残差,也就是模型当前预测和实际值之间的差距。
- 拟合新树 : 然后,我们训练一棵新的决策树 来拟合这些残差,这棵树的目标是减少这些残差。
- 更新模型 : 新的树被加入到模型中,模型更新 为现有模型加上新树的预测结果。
- 重复训练: 上述步骤重复多次,直到达到预设的迭代次数或预设的停止条件,比如残差减少到某个水平。
目标是将模型的预测值 <math xmlns="http://www.w3.org/1998/Math/MathML"> F m ( x ) F_m(x) </math>Fm(x) 尽可能接近真实值 <math xmlns="http://www.w3.org/1998/Math/MathML"> y y </math>y 。假设初始模型 <math xmlns="http://www.w3.org/1998/Math/MathML"> F 0 ( x ) F_0(x) </math>F0(x)是所有样本的均值 。后续每一轮迭代中:
- 计算残差或负梯度 :在第 <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m 轮,我们计算残差 <math xmlns="http://www.w3.org/1998/Math/MathML"> r m = y − F m − 1 ( x ) r_m = y - F_{m-1}(x) </math>rm=y−Fm−1(x)。
- 拟合残差 :训练一个弱学习器(例如决策树) <math xmlns="http://www.w3.org/1998/Math/MathML"> h m ( x ) h_m(x) </math>hm(x) 来拟合残差,使得 <math xmlns="http://www.w3.org/1998/Math/MathML"> h m ( x ) h_m(x) </math>hm(x) 尽量接近 <math xmlns="http://www.w3.org/1998/Math/MathML"> r m r_m </math>rm。
- 更新模型 :更新当前模型 <math xmlns="http://www.w3.org/1998/Math/MathML"> F m ( x ) F_m(x) </math>Fm(x) 的预测为:
<math xmlns="http://www.w3.org/1998/Math/MathML"> F m ( x ) = F m − 1 ( x ) + η ⋅ h m ( x ) F_m(x) = F_{m-1}(x) + \eta \cdot h_m(x) </math>Fm(x)=Fm−1(x)+η⋅hm(x) 这样一来,新的预测结果 <math xmlns="http://www.w3.org/1998/Math/MathML"> F m ( x ) F_m(x) </math>Fm(x) 就更接近真实值 <math xmlns="http://www.w3.org/1998/Math/MathML"> y y </math>y。 <math xmlns="http://www.w3.org/1998/Math/MathML"> η \eta </math>η:步长或学习率(learning rate)。它是一个超参数,用来控制每一轮的调整幅度。较小的学习率可以让模型更加稳定,但需要更多的迭代次数。
GBDT(Gradient Boosting Decision Tree)
-
原理 :GBDT (梯度提升决策树,Gradient Boosting Decision Tree)是一种基于 Gradient Boosting(梯度提升) 的集成学习方法,它使用 决策树 作为基本的弱学习器。在每一轮迭代中,GBDT 通过拟合当前模型的残差,逐步减少模型的误差,使得最终模型能够实现更好的预测效果。
-
主要特点:
- 弱学习器 :GBDT 中的弱学习器是决策树,通常是深度较小的 CART 决策树(即二叉决策树)。
- 损失函数最小化:GBDT 通过最小化损失函数(如均方误差、交叉熵等)来逐步提高模型性能。在每一轮迭代中,GBDT 训练新的决策树来拟合前一轮模型的残差。
- 灵活性:GBDT 可以使用不同的损失函数(如回归任务中的平方误差、分类任务中的对数损失),具有很强的适应性。
- 迭代过程:每一轮训练一个新的决策树来拟合当前模型的残差,通过逐步减小残差来优化整体模型。
- 加权组合:GBDT 最终的预测结果是多个决策树加权输出的组合。
-
算法步骤:
- 初始化模型为一个常数模型,通常为所有训练样本目标值的均值。
- 计算当前模型的残差(即预测值与真实值的差)。
- 训练一棵新的决策树来拟合这些残差。
- 将新的树加入到模型中,并更新模型的预测值。
- 重复上述步骤,直到达到预定的树的数量或模型收敛。
GB和GBDT的关系
Gradient Boosting(梯度提升) 是一种框架,泛指一种通过拟合残差来逐步提升模型性能的技术 。它可以使用不同的弱学习器(如线性回归、决策树等),而 GBDT 是一种特定的 Gradient Boosting 实现,GBDT 选择的是决策树作为弱学习器。
- Gradient Boosting 是一个广义上的提升框架 ,核心思想是利用梯度下降法最小化损失函数。它可以结合任何基学习器(如线性回归、支持向量机等),但最常用的基学习器是决策树。
- GBDT 是 Gradient Boosting 框架下的一种具体实现,特指基于 决策树 的梯度提升模型。
损失函数
GBDT可以处理回归和分类问题,基于不同的损失函数:
回归问题
对于回归问题 ,常用的损失函数是均方误差(MSE):
分类问题
对于分类问题 (二分类),常用的损失函数是对数损失(Log Loss):
XGBoost(Extreme Gradient Boosting)
-
原理 :XGBoost 是 GBDT 的改进版本 ,采用了正则化、并行化 、自动处理缺失值 等优化技术。它引入了二阶导数的损失函数优化,可以加速收敛和提高模型精度。
-
主要特点:
- 正则化:XGBoost 引入了 L1 和 L2 正则化项,以防止过拟合。
- 二阶导数优化 :对损失函数进行了二阶泰勒展开,使用损失的一阶导数(负梯度)和二阶导数(Hessian)来更新模型,使得 XGBoost 能更精确地更新模型,收敛速度更快。
- 分裂增益计算 :在每个节点的分裂过程中,XGBoost 通过计算分裂增益来选择最优分裂点。XGBoost 能有效选择最优分裂点,避免过度分裂。
- 并行化:XGBoost 的并行化通过将特征分块后在不同线程上独立计算各特征的分裂增益,最终汇总以加速最佳分裂点的选择。
- 剪枝:XGBoost 使用预剪枝策略来控制树的深度和复杂度。在训练过程中,如果增益低于设定阈值,则不进行分裂,从而避免生成多余的节点,进一步防止过拟合。
-
算法步骤:
-
- 与 Gradient Boosting 类似,XGBoost 通过拟合残差进行迭代。
-
- 每一轮生成的新树通过拟合上一次模型的残差,减少整体的损失。
-
- 增加了正则化项,进一步优化了树结构的选择,避免模型复杂化导致过拟合。
-
1. 目标函数及正则化项
XGBoost 的优化目标函数由两部分组成:损失函数(测量模型预测误差)和正则化项(控制模型复杂度)。XGBoost 的目标函数公式如下:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> Obj = ∑ i = 1 N L ( y i , y ^ i ) + ∑ m = 1 M Ω ( f m ) \text{Obj} = \sum_{i=1}^N L(y_i, \hat{y}i) + \sum{m=1}^M \Omega(f_m) </math>Obj=i=1∑NL(yi,y^i)+m=1∑MΩ(fm)
损失函数 <math xmlns="http://www.w3.org/1998/Math/MathML"> L ( y i , y ^ i ) L(y_i, \hat{y}_i) </math>L(yi,y^i)
损失函数 <math xmlns="http://www.w3.org/1998/Math/MathML"> L ( y i , y ^ i ) L(y_i, \hat{y}_i) </math>L(yi,y^i) 测量每个样本的预测误差。例如,常用的损失函数有:
- 均方误差 (MSE) :用于回归问题,定义为 <math xmlns="http://www.w3.org/1998/Math/MathML"> L ( y i , y ^ i ) = 1 2 ( y i − y ^ i ) 2 L(y_i, \hat{y}_i) = \frac{1}{2}(y_i - \hat{y}_i)^2 </math>L(yi,y^i)=21(yi−y^i)2。
- 对数损失 (Log Loss) :用于二分类问题。 <math xmlns="http://www.w3.org/1998/Math/MathML"> L ( y , y ^ ) = − ( y ⋅ log ( y ^ ) + ( 1 − y ) ⋅ log ( 1 − y ^ ) ) L(y, \hat{y}) = - \left( y \cdot \log(\hat{y}) + (1 - y) \cdot \log(1 - \hat{y}) \right) </math>L(y,y^)=−(y⋅log(y^)+(1−y)⋅log(1−y^))
正则化项 <math xmlns="http://www.w3.org/1998/Math/MathML"> Ω ( f m ) \Omega(f_m) </math>Ω(fm)
正则化项 <math xmlns="http://www.w3.org/1998/Math/MathML"> Ω ( f m ) \Omega(f_m) </math>Ω(fm) 用于控制模型复杂度,包含 L1 和 L2 正则化:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> Ω ( f m ) = γ T + 1 2 λ ∑ j = 1 T w j 2 + α ∑ j = 1 T ∣ w j ∣ \Omega(f_m) = \gamma T + \frac{1}{2} \lambda \sum_{j=1}^T w_j^2 + \alpha \sum_{j=1}^T |w_j| </math>Ω(fm)=γT+21λj=1∑Twj2+αj=1∑T∣wj∣
其中:
- <math xmlns="http://www.w3.org/1998/Math/MathML"> T T </math>T 是树的叶节点数目。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> w j w_j </math>wj 是第 <math xmlns="http://www.w3.org/1998/Math/MathML"> j j </math>j 个叶节点的权重。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> γ \gamma </math>γ 控制叶节点的数量,较大的 <math xmlns="http://www.w3.org/1998/Math/MathML"> γ \gamma </math>γ 倾向于减少叶节点数量,使模型更简单。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> λ \lambda </math>λ 是 L2 正则化系数,控制叶节点权重的平方和,有助于平滑叶节点的权重。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> α \alpha </math>α 是 L1 正则化系数,控制叶节点权重的绝对值之和,促使部分权重趋向于零,从而构建更稀疏的模型。
以下是图片中的内容转换为文字:
2. 二阶导数优化
为了提高训练效率,在实际优化中,XGBoost 对损失函数 进行了二阶泰勒展开,使用损失的一阶导数(负梯度)和二阶导数(Hessian)来更新模型:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> Obj ( m ) ≈ ∑ i = 1 N [ g i f m ( x i ) + 1 2 h i f m ( x i ) 2 ] + Ω ( f m ) \text{Obj}^{(m)} \approx \sum_{i=1}^N \left[ g_i f_m(x_i) + \frac{1}{2} h_i f_m(x_i)^2 \right] + \Omega(f_m) </math>Obj(m)≈i=1∑N[gifm(xi)+21hifm(xi)2]+Ω(fm)
其中:
- <math xmlns="http://www.w3.org/1998/Math/MathML"> g i = ∂ L ( y i , y ^ i ) ∂ y ^ i g_i = \frac{\partial L(y_i, \hat{y}_i)}{\partial \hat{y}_i} </math>gi=∂y^i∂L(yi,y^i) 是损失函数的一阶导数(梯度)。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> h i = ∂ 2 L ( y i , y ^ i ) ∂ y ^ i 2 h_i = \frac{\partial^2 L(y_i, \hat{y}_i)}{\partial \hat{y}_i^2} </math>hi=∂y^i2∂2L(yi,y^i) 是损失函数的二阶导数(Hessian)。
二阶导数使得 XGBoost 能更精确地更新模型,收敛速度更快。
3. 分裂增益计算
在每个节点的分裂过程中,XGBoost 通过计算分裂增益来选择最优分裂点。增益公式如下:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> Gain = 1 2 ( G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ ) − γ \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) - \gamma </math>Gain=21(HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2)−γ
其中:
- <math xmlns="http://www.w3.org/1998/Math/MathML"> G L G_L </math>GL 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> H L H_L </math>HL 是左子节点的梯度和和二阶导数和。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> G R G_R </math>GR 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> H R H_R </math>HR 是右子节点的梯度和和二阶导数和。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> λ \lambda </math>λ 是 L2 正则化系数。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> γ \gamma </math>γ 是控制叶节点数量的正则化超参数。
通过增益公式,XGBoost 能有效选择最优分裂点,避免过度分裂。
分裂增益和ID3的信息增益的区别
- ID3:使用信息增益,基于信息论的熵来衡量节点纯度,通过最大化信息增益来选额分裂特征,适合分类问题中的树生成。
- XGBoost:使用基于梯度和二阶导数的分裂增益,直接通过梯度提升的方法最小化预测误差,适合用于梯度提升方法中。
信息增益(Information Gain) 表示某一特征 <math xmlns="http://www.w3.org/1998/Math/MathML"> A A </math>A 将数据集 <math xmlns="http://www.w3.org/1998/Math/MathML"> D D </math>D 划分后的纯度提升程度 。ID3 选择信息增益最大的特征进行划分。信息增益的公式为:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> 信息增益 = H ( D ) − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ H ( D v ) \text{信息增益} = H(D) - \sum_{v=1}^V \frac{|D_v|}{|D|} H(D_v) </math>信息增益=H(D)−v=1∑V∣D∣∣Dv∣H(Dv)
其中:
- <math xmlns="http://www.w3.org/1998/Math/MathML"> H ( D ) H(D) </math>H(D) 是数据集 <math xmlns="http://www.w3.org/1998/Math/MathML"> D D </math>D 的信息熵。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> V V </math>V 是特征 <math xmlns="http://www.w3.org/1998/Math/MathML"> A A </math>A 的可能取值数。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> D v D_v </math>Dv 是根据特征 <math xmlns="http://www.w3.org/1998/Math/MathML"> A A </math>A 的取值 <math xmlns="http://www.w3.org/1998/Math/MathML"> v v </math>v 分割得到的子集。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> ∣ D v ∣ / ∣ D ∣ |D_v| / |D| </math>∣Dv∣/∣D∣ 表示取值 <math xmlns="http://www.w3.org/1998/Math/MathML"> v v </math>v 的样本在数据集 <math xmlns="http://www.w3.org/1998/Math/MathML"> D D </math>D 中的比例。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> H ( D v ) H(D_v) </math>H(Dv) 是子集 <math xmlns="http://www.w3.org/1998/Math/MathML"> D v D_v </math>Dv 的熵。
详细信息增益参考:万字长文解读机器学习------决策树
4. 并行化
XGBoost 的并行不是 Tree 粒度的并行,XGBoost 也是一次迭代完才能进行下一次迭代的(第 t 次迭代的代价函数里包含了前面 t-1 次迭代的预测值)。XGBoost 的并行是在特征粒度上的。
- 决策树的学习最耗时 的一个步骤就是对特征的值进行排序 (因为要确定最佳分割点),XGBoost在训练之前,预先对数据进行了排序,然后保存为 block 结构。 后面的迭代中重复地使用这个结构,大大减小计算量。
- 这个block 结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。
LightGBM(Light Gradient Boosting Machine)
-
原理 :LightGBM 是另一种基于 GBDT(Gradient Boosting Decision Trees) 的改进算法,采用了多种优化技术,如基于直方图的分裂方法 、叶子节点生长策略,旨在提升效率并降低内存使用。LightGBM 特别擅长处理大规模数据集和高维度特征。
-
主要特点:
- 基于直方图的分裂方法 :LightGBM 通过直方图算法 ,将连续特征分箱,从而大幅减少内存消耗和计算量。
- 基于叶子生长策略的决策树 :LightGBM 使用叶子生长策略,而不是深度优先策略 ,每次选择增益最大的叶子进行扩展 。这相比于传统的按深度生长方式能更快地降低误差。
- 支持类别特征 :LightGBM 能够直接处理类别特征 ,而不需要对其进行独热编码(one-hot encoding),从而提高了效率。
- 预剪枝:LightGBM 使用了预剪枝策略来防止树的过度生长,降低过拟合的风险。
- 分布式学习:支持分布式训练,适合在多台机器上并行处理超大规模数据集。
- 处理缺失值:自动处理缺失数据,无需额外的预处理步骤。
-
优点:
- 训练速度非常快,适合大规模数据集和高维数据。
- 内存使用效率高,尤其在大规模数据集上的表现优秀。
- 提供强大的分布式学习能力。
- 针对类别特征的处理更高效。
-
缺点:
- Leaf-wise 增长策略有时可能会导致过拟合,需要通过调优控制模型复杂度。
- 超参数较多,调优过程复杂。
直方分裂算法(Histogram-based Splitting)
直方分裂算法是 LightGBM的核心优化之一 ,它通过将连续特征离散化成直方图,显著减少了寻找最佳分裂点时的计算量,从而提升了训练速度。
原理 : 在传统的决策树构建中,选择最佳分裂点需要遍历每个样本的特征值,计算各个分裂点的增益,计算量较大,尤其是在数据集和特征数较多时。
在 LightGBM中 ,直方分裂算法将连续特征值离散化为固定数量的桶 (bins),将特征值映射到这些离散桶中,以降低计算复杂度。
操作流程【详细待补充】:
- 特征离散化 :将每个连续特征 的取值范围划分成 K 个桶。假设将特征的值域划分为K=256 个桶,那么每个特征值会被映射到其中的某一个桶中。
- 构建直方图 :根据桶中的数据 生成直方图。具体步骤为: 对每个分桶,累积样本数及其目标值的和(或梯度和)。 这样,每个桶会存储当前桶中所有样本的梯度和、样本数量,从而构成直方图。
选择最佳分裂点:在直方图上遍历所有分桶 (而不是逐个样本),计算每个分桶的增益,找到最佳分裂点。
直方分裂公式假设我们当前节点包含 N个样本,目标是找到一个最优分裂点 ,以使分裂后的左右子节点增益最大化 。在计算增益时,使用直方图中的累积梯度和二阶梯度【同上面的XGboost中的分裂增益】:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> Gain = 1 2 ( G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ ) − γ \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) - \gamma </math>Gain=21(HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2)−γ
其中:
- <math xmlns="http://www.w3.org/1998/Math/MathML"> G L G_L </math>GL 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> H L H_L </math>HL 是左子节点的梯度和和二阶导数和。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> G R G_R </math>GR 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> H R H_R </math>HR 是右子节点的梯度和和二阶导数和。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> λ \lambda </math>λ 是 L2 正则化系数。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> γ \gamma </math>γ 是控制叶节点数量的正则化超参数。
通过增益公式,LightGBM的直方分裂算法能有效选择最优分裂点,避免过度分裂。
基于叶子生长的策略(Leaf-wise Growth Strategy)
原理 :
传统的 GBDT 和 XGBoost 使用的是层级生长策略(Level-wise GrowthStrategy),即在每一层同时分裂所有节点,形成一棵尽可能平衡的树。然而,这种策略在大数据集上计算开销较大。
LightGBM,不是同时分裂整层节点。而是采用叶子生长策略 (Leaf-wise Growth Strategy),优先分裂增益最高的叶节点,这样可以在树的相同深度下 更大限度地减少损失**,使得模型具有更强的拟合能力。然而,叶子生长策略可能会导致树结构不平衡 ,尤其是在数据较为复杂时,可能会出现某些分支比其他分支深得多的情况,这可能导致过拟合。
操作流程
- 初始化根节点:在树的根节点计算损失,记录该节点的梯度和二阶梯度和。
- 选择叶节点分裂 :对于每一轮分裂,遍历所有当前叶节点,计算其分裂增益 。选择增益最大 的叶节点进行分裂,而不是层级生长策略中对一层的所有节点进行分裂。 计算分裂增益:对于每个叶节点,分裂增益的计算公式同样为XGboost中的分裂增益:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> Gain = 1 2 ( G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ ) − γ \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) - \gamma </math>Gain=21(HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2)−γ
其中:
- <math xmlns="http://www.w3.org/1998/Math/MathML"> G L G_L </math>GL 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> H L H_L </math>HL 是左子节点的梯度和和二阶导数和。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> G R G_R </math>GR 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> H R H_R </math>HR 是右子节点的梯度和和二阶导数和。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> λ \lambda </math>λ 是 L2 正则化系数。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> γ \gamma </math>γ 是控制叶节点数量的正则化超参数。
更新叶节点和分裂:分裂后,更新叶节点列表,将新生成的叶节点加入列表,并继续寻找增益最大的节点进行分裂。
注意
: LightGBM 和 XGBoost 的增益公式是一样的,都是用梯度和二阶导数来计算每个分裂点的增益。但是由于树的生长策略不同,增益在两者中的作用方式有所区别。LightGBM 使用叶子生长策略,增益决定哪个叶节点优先分裂;XGBoost 使用层级生长策略,增益用于确定每层节点的分裂点。
GBDT、XGBoost、LightGBM迭代路径
更多的Boosting优化参考: GBDT、XGBoost、LightGBM迭代路径
Stacking 算法
Stacking(堆叠集成)是一种集成学习方法,利用多个 不同模型(基学习器 )生成预测结果,再用一个 更高层次的模型(元学习器 )来综合这些预测,从而提升整体预测性能。它灵活且有效,尤其在不同模型的预测结果存在互补性时表现尤佳。【其实类似模型蒸馏的教师模型和学生模型】
参考:万字长文解读深度学习------训练(DeepSpeed、Accelerate)、优化(蒸馏、剪枝、量化)、部署细节
基本思想和流程
Stacking 的基本思想是将多个模型(基学习器)的预测结果作为新特征 ,再通过一个 模型(通常称为元学习器 )来对这些特征进行综合,生成最终预测。整体流程分为两层结构:
- 第一层(基学习器层) :由多个基学习器组成。每个基学习器独立对训练数据进行训练,并生成预测结果。这些基学习器可以是同类型的不同参数模型,也可以是完全不同的模型。
- 第二层(元学习器层) :基于第一层的预测结果,生成新的特征,再使用一个元学习器 来学习这些新特征,从而做出最终预测。
实现步骤
步骤 1:选择基学习器和元学习器
- 基学习器 :选择多个不同的基学习器,通常选用表现良好 的但互补的模型,比如决策树、支持向量机、逻辑回归、KNN、神经网络等。基学习器的多样性对于最终性能至关重要。
- 元学习器 :通常选择简单而具有强泛化能力的模型,例如线性回归或逻辑回归,也可以使用更复杂的模型,如梯度提升决策树(GBDT)等。
步骤 2:准备第一层输入数据(K 折交叉验证)
为了避免数据泄露(即避免让元学习器在训练时看到测试数据),我们通常对训练数据进行 K 折交叉验证来生成第一层的输出。
- 训练过程 :
- 将训练集划分为 K 折。
- 针对每个基学习器,进行 K 次训练。每次在 K-1 个子集上训练,在剩余的 1 个子集上进行预测。
- 将 K 次预测的结果合并,作为该基学习器在训练集上的输出。
- 这样对每个基学习器得到一个与训练集相同大小的预测结果,作为新的特征(即第一层输出)。
- 测试过程 :
- 针对每个基学习器,使用全部训练数据进行训练,然后在测试集上进行预测。
- 得到每个基学习器在测试集上的预测结果,将这些预测结果作为测试集的新特征。
步骤 3:训练元学习器
- 使用基学习器的输出(即第一层的预测结果)作为新的特征,在训练集上训练元学习器。
- 元学习器可以是简单的线性模型,也可以是更复杂的模型,例如树模型。
步骤 4:生成最终预测
- 在测试集上,基学习器生成的预测结果作为元学习器的输入,通过元学习器生成最终预测。
优点和缺点
优点
- 灵活性强:可以组合不同类型的基学习器,充分利用它们的优势。
- 性能提升明显:基学习器的多样性带来的互补效果,可以显著提升预测性能。
- 适应性强:适合回归、分类任务,且能够处理高维特征。
缺点
- 计算成本高:需要训练多个基学习器和元学习器,计算开销大,尤其在数据量较大时。
- 调参复杂:每个基学习器和元学习器都有独立的超参数,调优过程复杂。
- 易过拟合:如果基学习器和元学习器过于复杂,可能导致过拟合问题。
变体
-
Blending:
- 与 Stacking 类似,但 Blending 不使用交叉验证。
- 将训练数据分为训练集和验证集。基学习器在训练集上训练,在验证集上生成预测结果,作为新的特征。
- 优点是实现简单,缺点是验证集小,可能导致过拟合。
-
多层 Stacking:
- 可以扩展 Stacking 的层次结构,增加更多的层级(即多层元学习器)。
- 例如:将第一层的输出作为第二层基学习器的输入,第二层的输出再输入到第三层元学习器,依此类推。
- 多层 Stacking 可能会带来更好的性能,但调优难度和计算成本也会大幅增加。
实际实现中的注意事项
- 数据泄露问题:确保元学习器的训练数据来自交叉验证的输出,以避免数据泄露问题。
- 基学习器的多样性:选择具有互补性的基学习器,避免不同模型之间的高相关性。
- 正则化:在元学习器上使用正则化(如 L2 正则化)可以防止过拟合。
- 特征缩放:根据不同模型的需求,可以对输入数据进行特征缩放,以提升模型性能。
- 计算资源:Stacking 需要多次训练模型,计算成本较高,因此在实际应用中要考虑资源情况。
总结
Stacking 是一种强大的集成学习方法,通过组合多个基学习器的预测结果,利用元学习器进一步学习这些结果,从而提升整体模型的性能。尽管 Stacking 计算复杂度高,但在实际应用中表现出色,尤其适合需要高精度预测的场景。
历史文章
本系列其他相关笔记参考如下:
机器学习笔记------感知机、多层感知机(MLP)、支持向量机(SVM)