从头了解Gradient Boosting算法

目的

虽然大多数Kaggle竞赛获胜者使用各种模型的叠加/集合,但是一个特定的模式是大部分集合的部分是梯度提升(GBM)算法的一些变体。以最新的Kaggle比赛获胜者为例:Michael Jahrer的解决方案是在安全驾驶的预测中的表示学习。他的解决方案是6个模型的混合。1 个LightGBM(GBM的变体)和5个神经网络。虽然他的成功归因于他为结构化数据发明的新的半监督学习,但梯度提升模型也发挥了作用。

尽管GBM被广泛使用,许多从业人员仍然将其视为复杂的黑盒算法,只是使用预建的库运行模型。这篇文章的目的是为了简化所谓复杂的算法,并帮助读者直观地理解算法。我将解释基本版本的梯度提升算法,并将在最后分享其不同的变体的链接。我已经从fast.ai库(fastai/courses/ml1/lesson3-rf_foundations.ipynb)取得了基本的DecisionTree代码,最重要的是,我建立了自己的简单版本的基本梯度提升模型。

关于Ensemble, Bagging 和 Boosting的简要描述

当我们试图用任何机器学习技术来预测目标变量时,实际值和预测值的主要差异是噪声,方差和偏差。集成有助于减少这些因素。

一个集合只是一个汇集在一起(例如所有预测的平均值)来作出最终预测的预测器集合。我们使用集成的原因是许多不同的预测变量试图预测相同的目标变量将比任何单一的预测器完成的更好。集成技术进一步分为Bagging和Boosting。

  • Bagging是一个简单的集成技术,我们建立许多独立的预测变量/模型/学习者,并使用一些模型平均技术将它们结合起来。(例如加权平均数,多数票或正态平均数)。

我们通常对每个模型采用随机的子样本/bootstrap数据,因此所有模型彼此之间几乎没有差别。每个观察结果在所有模型中出现的概率相同。因为这种技术需要许多不相关的学习者做出最终的模型,所以通过减少方差来减少错误。Bagging集成的例子是随机森林模型。

  • Boosting是一种集成技术,其中预测变量不是独立的,而是按顺序进行的。

这种技术使用了后面的预测变量从之前的预测变量的错误中学习的逻辑。因此,观测值在后续模型中出现的概率是不相同的,而误差最大的出现最频繁。预测变量可以从一系列模型中选择,如决策树,回归量,分类器等等。因为新的预测变量是从以前的预测变量所犯的错误中学习的,所以需要更少的时间/次数来接近实际的预测。但是我们必须慎重选择停机判据,否则可能导致训练数据过度拟合。梯度提升是Boosting算法的一个例子。

图1.集成

图2. Bagging (独立模式) 和 Boosting (顺序模式).

参考:https://quantdare.com/what-is-the-ding-between-bagging-and-boosting /

梯度提升算法

在维基百科的定义中,梯度提升是一种用于回归和分类问题的机器学习技术,它以弱预测模型(通常是决策树)的集合的形式产生预测模型。

任何监督学习算法的目标是定义一个损失函数,并将其最小化。让我们看看梯度提升算法的数学运算。假设我们将均方根误差(MSE)定义为:

我们希望我们的预测,使我们的损失函数(MSE)最小。 通过使用梯度下降和基于学习速率更新我们的预测,我们可以找到MSE最小的值。

所以,我们基本上是更新预测,使我们的残差总和接近0(或最小),预测值足够接近实际值。

梯度提升背后的直觉

梯度提升背后的逻辑很简单,(可以直观地理解,不使用数学符号)。 我期望任何阅读这篇文章的人都可以熟悉简单的线性回归模型。

线性回归的一个基本假设是其残差之和为0,即残差应该在0左右随机分布。

图3.抽样随机正态分布残差均值在0附近

现在把这些残差看作我们的预测模型所犯的错误。虽然基于树的模型(把决策树当作我们梯度提升的基本模型)并不是基于这样的假设,但是如果我们从逻辑上(而不是统计上)考虑这个假设,那么我们可能证明,如果我们能够看到一些残差在0左右的模式,我们可以利用这种模式来拟合模型。

因此,梯度提升算法的直觉就是反复利用残差模式,加强预测能力较弱的模型,使其更好。 一旦我们达到残差没有任何模式可以建模的阶段,我们可以停止建模残差(否则可能导致过度拟合)。 在算法上,我们正在最小化我们的损失函数,使得测试损失达到最小值。

综上所述,

  • 我们首先用简单的模型对数据进行建模,并分析错误的数据。
  • 这些错误通过一个简单的模型来表示数据点是很难的。
  • 那么对于以后的模型,我们特别关注那些难以处理的数据,以使它们正确。
  • 最后,我们通过给每个预测变量赋予一些权重来组合所有的预测变量。

关于同一逻辑的更为技术性的引用写在Probably Approximately Correct: Nature’s Algorithms for Learning and Prospering in a Complex World,“这个想法是多次使用弱的学习方法来获得连续的假设,每一个调整的例子是以往发现困难和错误分类的。...但是,请注意,能做到这一点并不明显”。

拟合梯度提升模型的步骤

让我们思考下面的散点图中显示的模拟数据,其中1个输入(x)和1个输出(y)变量。

图4.模拟数据(x:输入,y:输出)

上面显示的图的数据是使用下面的python代码生成的:

x = np.arange(0,50)
x = pd.DataFrame({'x':x})
# just random uniform distributions in differnt range
y1 = np.random.uniform(10,15,10)
y2 = np.random.uniform(20,25,10)
y3 = np.random.uniform(0,5,10)
y4 = np.random.uniform(30,32,10)

1. 对数据拟合一个简单的线性回归或决策树(我在我的代码中选择了决策树)[将x作为输入,将y作为输出]

xi = x # initialization of input
yi = y # initialization of target
# x,y --> use where no need to change original y
ei = 0 # initialization of error
n = len(yi)  # number of rows
predf = 0 # initial prediction 0
for i in range(30): # loop will make 30 trees (n_estimators).
    tree = DecisionTree(xi,yi) # DecisionTree scratch code can be found in shared github/kaggle link.
                          # It just create a single decision tree with provided min. sample leaf
    tree.find_better_split(0)  # For selected input variable, this splits (<n and >n) data so that std. deviation of
                           # target variable in both splits is minimum as compared to all other splits
    r = np.where(xi == tree.split)[0][0]   #  finds index where this best split occurs
    left_idx = np.where(xi <= tree.split)[0] # index lhs of split
    right_idx = np.where(xi > tree.split)[0] # index rhs of split

2. 计算误差残差。实际目标值减去预测目标值[e1 = y_predicted1 - y]

3. 将误差残差的新模型作为具有相同输入变量的目标变量[称为e1_predicted]

4. 将预测的残差添加到先前的预测中[y_predicted2 = y_predicted1 + e1_predicted]

5. 在剩余的残差上拟合另一个模型。即[e2 = y-y_predicted2]并重复步骤2到5,直到它开始过拟合或残差总和变成恒定。过度拟合可以通过持续检查验证数据的准确性来控制。

     


为了帮助理解基本概念,下面是从零开始完整实现简单梯度提升模型的链接。 [链接:从头开始梯度提升]

共享代码是一种非优化的梯度提升的普通实现。库中的大多数梯度提升模型都经过了很好的优化,并且有很多超参数。

工作梯度提升树的可视化

蓝点(左)是输入(x)与输出(y)的关系•红线(左)显示由决策树预测的值•绿点(右)显示第i次迭代的残差与输入(x)•迭代表示拟合梯度提升树的顺序。

图5.梯度提升预测的可视化(前4次迭代)

图6.梯度提升预测的可视化(第18次至第20次迭代)

我们观察到,在第20次迭代之后,残差在0附近是随机分布的(我并不是说随机的正态分布),我们的预测非常接近真实值。(迭代在sklearn实现中被称为n_estimators)。这将是一个很好的点来停止或开始过度拟合模型。

让我们看看我们的模型在第五十次迭代中的样子。

我们可以看到,即使在第50次迭代之后,残差对x的曲线看起来也与我们在第20次迭代中看到的相似。 但是,模型变得越来越复杂,预测过度的训练数据,并试图学习每个训练数据。 所以,最好是停止在第20次迭代。

用于绘制所有上述数据的Python代码片段

  # plotting after prediction
  xa = np.array(x.x) # column name of x is x
  order = np.argsort(xa)
  xs = np.array(xa)[order]
  ys = np.array(predf)[order]
  #epreds = np.array(epred[:,None])[order]
  f, (ax1, ax2) = plt.subplots(1, 2, sharey=True, figsize = (13,2.5))
  ax1.plot(x,y, 'o')
  ax1.plot(xs, ys, 'r')
  ax1.set_title(f'Prediction (Iteration {i+1})')
  ax1.set_xlabel('x')
  ax1.set_ylabel('y / y_pred')
  ax2.plot(x, ei, 'go')
  ax2.set_title(f'Residuals vs. x (Iteration {i+1})')
  ax2.set_xlabel('x')
  ax2.set_ylabel('Residuals')

更多有用的资源

1.我的github repo和关于从头开始GBM的kaggle核心链接:

https://www.kaggle.com/grroverpr/gradient-boosting-simplified/

https://github.com/groverpr/Intro-to-Machine-Learning/blob/master/algo_scratch/gradient%20boosting%20from%20scratch.ipynb

2.关于从头开始决策树的Fast.ai github repo链接(Massive

ML / DL相关资源):

https://github.com/fastai/fastai

3. Alexander Ihler(需翻墙)的视频。这个视频真的帮助我了理解梯度提升算法。

4. 一位Kaggle专家解释梯度提升:本戈曼

http://blog.kaggle.com/2017/01/23/a-kaggle-master-explains-gradient-boosting/

5.广泛使用的GBM算法:

XGBoost || Lightgbm|| Catboost ||

sklearn.ensemble.GradientBoostingClassiber

作者信息

Prince Grover,南佛罗里达大学数据科学硕士学生,Manifold.ai数据科学实习生。

本文由北邮@爱可可-爱生活老师推荐,阿里云组织翻译。

文章原标题《Gradient Boosting from scratch》

作者:Prince Grover 译者:董昭男

文章为简译,更为详细内容,请查看原文(需翻墙),查看PDF

时间: 2024-10-25 10:50:44

从头了解Gradient Boosting算法的相关文章

R: 学习Gradient Boosting算法,提高预测模型准确率

引言 预测模型的准确率可以用2种方法来提高:要么进行特征设计,要么直接使用boosting算法.参加过许多数据科学大赛后,我发现许多人喜欢用boosting算法,因为它只需更少的时间就能产生相似的结果. 目前有许多boosting算法,如Gradient Boosting. XGBoost,.AdaBoost和Gentle Boost等等.每个算法都有自己基本的数学原理并且在使用它们时都会发现有一些细微的变化.如果你刚接触boosting算法,那太好了!从现在开始你可以在一周内学习所有这些概念.

Gradient Boosting Decision Tree学习

Gradient Boosting Decision Tree,即梯度提升树,简称GBDT,也叫GBRT(Gradient Boosting Regression Tree),也称为Multiple Additive Regression Tree(MART),阿里貌似叫treelink. 首先学习GBDT要有决策树的先验知识. Gradient Boosting Decision Tree,和随机森林(random forest)算法一样,也是通过组合弱学习器来形成一个强学习器.GBDT的发明

A Gentle Introduction to the Gradient Boosting Algorithm for Machine Learning

A Gentle Introduction to the Gradient Boosting Algorithm for Machine Learning by Jason Brownlee on September 9, 2016 in XGBoost 0 0 0 0   Gradient boosting is one of the most powerful techniques for building predictive models. In this post you will d

How to Configure the Gradient Boosting Algorithm

How to Configure the Gradient Boosting Algorithm by Jason Brownlee on September 12, 2016 in XGBoost 0 0 0 0   Gradient boosting is one of the most powerful techniques for applied machine learning and as such is quickly becoming one of the most popula

想去机器学习初创公司做数据科学家?这里有最常问的40道面试题

导读   想去机器学习初创公司做数据科学家?这些问题值得你三思! 机器学习和数据科学被看作是下一次工业革命的驱动器.这也意味着有许许多多令人激动的初创公司正在起步成长.寻找专业人士和数据科学家.它们可能是未来的特斯拉.谷歌. 对于有职业抱负的你来说,看好一家好的创业公司团队后,如何能够脱颖而出,进入一家靠谱的创业团队呢? 想得到这样的工作并不容易.首先你要强烈认同那个公司的理念.团队和愿景.同时你可能会遇到一些很难的技术问题.而这些问题则取决于公司的业务.他们是咨询公司?他们是做机器学习产品的?

GBDT:梯度提升决策树

综述 GBDT(Gradient Boosting Decision Tree) 又叫 MART(Multiple Additive Regression Tree),是一种迭代的决策树算法,该算法由多棵决策树组成,所有树的结论累加起来做最终答案.它在被提出之初就和SVM一起被认为是泛化能力较强的算法. GBDT中的树是回归树(不是分类树),GBDT用来做回归预测,调整后也可以用于分类. GBDT的思想使其具有天然优势可以发现多种有区分性的特征以及特征组合.业界中,Facebook使用其来自动发

分分钟带你杀入Kaggle Top 1%

不知道你有没有这样的感受,在刚刚入门机器学习的时候,我们一般都是从MNIST.CIFAR-10这一类知名公开数据集开始快速上手,复现别人的结果,但总觉得过于简单,给人的感觉太不真实.因为这些数据太"完美"了(干净的输入,均衡的类别,分布基本一致的测试集,还有大量现成的参考模型),要成为真正的数据科学家,光在这些数据集上跑模型是远远不够的.现实中你几乎不可能遇到这样的数据(现实数据往往有着残缺的输入,类别严重不均衡,分布不一致甚至随时变动的测试集,几乎没有可以参考的论文),这往往让刚进入

XGBoost参数调优完全指南(附Python代码)

简介 如果你的预测模型表现得有些不尽如人意,那就用XGBoost吧.XGBoost算法现在已经成为很多数据工程师的重要武器.它是一种十分精致的算法,可以处理各种不规则的数据. 构造一个使用XGBoost的模型十分简单.但是,提高这个模型的表现就有些困难(至少我觉得十分纠结).这个算法使用了好几个参数.所以为了提高模型的表现,参数的调整十分必要.在解决实际问题的时候,有些问题是很难回答的--你需要调整哪些参数?这些参数要调到什么值,才能达到理想的输出? 这篇文章最适合刚刚接触XGBoost的人阅读

机器学习算法基础(Python和R语言实现)

简介 谷歌的无人驾驶汽车已经受到了世人很大的关注,但公司的未来却是在机器学习领域,因为这项技术将使电脑更智能,更人性化.--埃里克·施密特(谷歌主席) 我们可能正经历着人类最明确定义的阶段,这个阶段计算机计算从大型主机,到个人电脑,到云计算.但这些并不是根本原因,而是接下来几年中将会发生的. 这个时期使那些像我一样的人们兴奋的是工具和技术的开放,这得以于计算机领域的蓬勃发展.今天,作为一名数据科学家,我能以很低的成本搭建一个拥有复杂算法的数据处理系统.但是达到这样的结果,我也经历了在黑夜中艰苦的