万字总结GBDT原理、核心参数以及调优思路

万字总结GBDT原理、核心参数以及调优思路

在机器学习领域,梯度提升决策树(Gradient Boosting Decision Tree, GBDT)以其卓越的预测性能和强大的模型解释能力而广受推崇。GBDT通过迭代地构建决策树,每一步都在前一步的残差上进行优化,从而实现对复杂数据模式的捕捉。本文将万字总结GBDT的工作原理、核心参数,以及如何高效地进行模型调优。从损失函数到树的构建,从正则化项到特征选择,我们将深入探讨GBDT的每一个细节,为读者提供全面的调优思路和实用技巧。


一、GBDT的基本思想

梯度提升树(Gradient Boosting Decision Tree,GBDT)是提升法中的代表性算法,它即是当代强力的XGBoost、LGBM等算法的基石,也是工业界应用最多、在实际场景中表现最稳定的机器学习算法之一。在最初被提出来时,并没有规定他的弱评估器一定是树模型,GBDT被写作梯度提升机器(Gradient Boosting Machine,GBM),它融合了Bagging与Boosting的思想、扬长避短,可以接受各类弱评估器作为输入,在后来弱评估器基本被定义为决策树后,才慢慢改名叫做梯度提升树。受Boosting算法首个发扬光大之作AdaBoost的启发,GBDT中自然也包含Boosting三要素:
在这里插入图片描述
同时GBDT也遵循boosting算法的基本流程进行建模:
依据上一个弱评估器 的结果,计算损失函 ,并使用𝐿 自适应地影响下一个弱评估器 构建。集成模型输出的结果,受到整体所有弱评估器 ~ 的影响。
但与RandomForest和AdaBoost不同,GBDT在整体建树过程中做出了几个关键的改变:

  • 弱评估器:GBDT的弱评估器输出类型不再与整体集成算法输出类型一致。 对于AdaBoost或随机森林算法来说,当集成算法执行的是回归任务时,弱评估器也是回归器,当集成算法执行分类任务时,弱评估器也是分类器。但对于GBDT而言,无论GBDT整体在执行回归/分类/排序任务,弱评估器一定是回归器。GBDT通过sigmoid或softmax函数输出具体的分类结果,但实际弱评估器一定是回归器。(借助softmax或Sigmoid函数将输出的连续型结果转换成类别)

  • 损失函数:在GBDT当中,损失函数范围不再局限于固定或单一的某个损失函数(且不要求损失函数的值域,GBDT对损失函数几乎没有任何要求,唯一要求是可微)(在AdaBoost中损失函数是指数损失,值域必在[0,1]之间否则会出问题),而从数学原理上推广到了任意可微的函数。因此GBDT算法中可选的损失函数非常多,GBDT实际计算的数学过程也与损失函数的表达式无关。

  • 拟合残差(面试最爱问):GBDT依然自适应调整弱评估器的构建,但却不像AdaBoost(奠定的比较根源的点是:后面建立的弱评估器需要依赖于前面建立的弱评估器的结果来进行自适应的调整,Boosting算法之间的不同就在于自适应调整的方法不太一样)一样通过调整数据分布来间接影响后续弱评估器。相对的,GBDT通过修改后续弱评估器的拟合目标来直接影响后续弱评估器的结构。

  • 抽样思想:GBDT加入了随机森林中随机抽样的思想,在每次建树之前,允许对样本和特征进行抽样来增大弱评估器之间的独立性(也因此可以有袋外数据集)。虽然Boosting算法不会大规模地依赖于类似于Bagging的方式来降低方差,但由于Boosting算法的输出结果是弱评估器结果的加权求和,因此Boosting原则上也可以获得由“平均”带来的小方差红利。当弱评估器表现不太稳定时,采用与随机森林相似的方式可以进一步增加Boosting算法的稳定性。

二、GBDT实现以及参数

from sklearn.ensemble import GradientBoostingRegressor as GBR
from sklearn.ensemble import GradientBoostingClassifier as GBC
from sklearn.model_selection import cross_validate, KFold
gbr = GBR(random_state=1412) #实例化
result_gbdt = cross_validate(gbr,X,y,cv=cv
                             ,scoring="neg_root_mean_squared_error" #负根均方误差
                             ,return_train_score=True
                             ,verbose=True
                             ,n_jobs=-1)

注意:由于GBDT的弱评估器只能是回归树,所以并没有分类树相关的属性如class_weight等。

1.迭代过程

GBDT迭代过程

1.1 初始预测结果的设置

参数init:输入计算初始预测结果H0的估计器对象。

在该参数中,可以输入任意评估器(最理想的状况)、字符串"zero"(上述两者结果都不好的时候才会选择zero)、或者None对象(第二选择),默认为None对象。
初始预测结果的设置

1.2 GBDT是如何使用回归器完成分类任务的

由于GBDT中所有的弱评估器都是回归树,因此在实际调用梯度提升树完成分类任务时,需要softmax函数或sigmoid函数对回归树输出的结果进行处理
GBDT是如何使用回归器完成分类任务的

1.3 GBDT的损失函数

对于GBDT而言,损失函数可以是任意可微的函数。

  • 分类器中的loss:字符串型,可输入"deviance", “exponential”,默认值=“deviance”
    其中"deviance"直译为偏差,特指逻辑回归的损失函数——交叉熵损失,而"exponential"则特指AdaBoost中使用的指数损失函数。

GBDT的损失函数

2.弱评估器结构

2.1 GBDT中弱评估器的复杂度

  • max_depth

对GBDT来说,无论是分类器还是回归器,默认的弱评估器最大深度都为3,因此GBDT默认就对弱评估器有强力的剪枝机制,因此在控制过拟合方面,max_depth的调参空间并不大。

  • max_features

当GBDT等Boosting算法处于过拟合状态时,一般从数据上下手控制过拟合(例如,使用参数max_features,在GBDT中其默认值为None),毕竟当max_depth已经非常小时,其他精剪枝的参数如min_impurity_decrease一般发挥不了太大的作用。也因此,通常认为Boosting算法比Bagging算法更不容易过拟合,一般在相似的数据上,Boosting算法表现出的过拟合程度会较轻。

2.2 弗里德曼均方误差(梯度提升树中专门的不纯度衡量指标)

弗里德曼均方误差

3.GBDT的提前停止机制

对于任意需要迭代的算法,迭代的背后往往是损失函数的最优化问题。例如在逻辑回归中,在进行梯度下降的迭代时,是希望找到交叉熵损失函数的最小值;而在梯度提升树中,在一轮轮建立弱评估器过程中,也是希望找到对应损失函数的最小值。理想状态下,无论使用什么算法,只要能够找到损失函数上真正的最小值,那模型就达到“收敛”状态,迭代就应该被停止。

然而遗憾的是,我们和算法都不知道损失函数真正的最小值是多少,而算法更不会在达到收敛状态时就自然停止。在机器学习训练流程中,往往是通过给出一个极限资源来控制算法的停止,比如,通过超参数设置允许某个算法迭代的最大次数,或者允许建立的弱评估器的个数。因此无论算法是否在很短时间内就锁定了足够接近理论最小值的次小值、或者算法早已陷入了过拟合状态、甚至学习率太低导致算法无法收敛,大多数算法都会持续(且无效地)迭代下去,直到给与的极限资源全部被耗尽。对于复杂度较高、数据量较大的Boosting集成算法来说,无效的迭代常常发生,因此作为众多Boosting算法的根基算法,梯度提升树自带了提前停止的相关超参数。另外,逻辑回归看起来会自然停止,是因为逻辑回归内置提前停止机制。

GBDT的提前停止机制

4.GBDT的袋外数据

受到随机森林的启发,梯度提升树在每次建树之前,也允许模型对于数据和特征进行随机有放回抽样,构建与原始数据集相同数据量的自助集。在梯度提升树的原理当中,当每次建树之前进行随机抽样时,这种梯度提升树叫做随机提升树(Stochastic Gradient Boosting)。相比起传统的梯度提升树,随机提升树输出的结果往往方差更低(表现的更加稳定),但偏差略高。如果发现GBDT的结果高度不稳定(或者结果处于严重过拟合状态),则可以尝试使用随机提升树(打开控制抽样的参数)。

在GBDT当中,对数据的随机有放回抽样比例由参数subsample确定,当该参数被设置为1时,则不进行抽样,直接使用全部数据集进行训练。当该参数被设置为(0,1)之间的数字时,则使用随机提升树,在每轮建树之前对样本进行抽样(不为1的话是0.7或者0.8之类的)。对特征的有放回抽样比例由参数max_features确定,随机模式则由参数random_state确定,这两个参数在GBDT当中的使用规则都与随机森林中完全一致。
GBDT的袋外数据

三、GBDT调参

GBDT调参思路与贝叶斯优化

总结

欢迎关注我的公众号

相关推荐

  1. jvm参数常用命令总结

    2024-07-09 21:02:04       59 阅读
  2. jvm 参数

    2024-07-09 21:02:04       41 阅读
  3. Hive总结

    2024-07-09 21:02:04       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-09 21:02:04       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-09 21:02:04       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-09 21:02:04       57 阅读
  4. Python语言-面向对象

    2024-07-09 21:02:04       68 阅读

热门阅读

  1. 从vs中删除自带的Microsoft Git Provider

    2024-07-09 21:02:04       17 阅读
  2. 设计模式的一点理解

    2024-07-09 21:02:04       18 阅读
  3. QT 设置控件的展开和消失

    2024-07-09 21:02:04       22 阅读
  4. qt 读取配置文件

    2024-07-09 21:02:04       21 阅读
  5. 王道考研数据机构:中缀表达式转为后缀表达式

    2024-07-09 21:02:04       30 阅读
  6. 基于深度学习的夜间图像修复

    2024-07-09 21:02:04       24 阅读
  7. SQL AND & OR 运算符的使用与区别

    2024-07-09 21:02:04       20 阅读