分享

机器学习梯度提升算法

 脑系科数据科学 2020-04-28

Introduction of Gradient Boosting Model of Machine Learning

前言:机器学习是什么

上一篇把近期回归模型的进展拓展了一遍,但实际上并没有谈到机器学习的精华所在,因此这边重新带大家顺过一遍。

近几年AI相关的技术又重新受到关注,从16年Alpha Go事件以来,大家开始爆炸性地关注这个技术未来的发展性与应用面,而的确我们现在看到这些技术越来越多的可能性,比方说科大迅飞开发出来的语音辨识机器,NYC研究生开发出来的YOLO物件侦测系统(可以用在自驾车、图像辨别等),NVIDIA近来研究出基于深度学习框架与光影辨识技术的GPU等等。

实际上,机器学习是AI产业里面最主要的技术之一。顾名思义,机器学习是旨在教会机器如何“学习'' ,而要让机器知道如何学习,某种程度上我们必须先理解人类是如何学习的,人类有一套自己的学习标准,用来模仿是我们目前想到最快的方式。举例来说,你有没有想过人是怎么样知道眼前的物体是一辆车或是一棵树?其实道理很简单,我们从小开始看到各式各样的物体,每次都有人告诉我们,这是车、这是树,久而久之我们就知道长相类似的物体会被归类为车子或树,而机器也是一样的,也就是说,在让机器开始学习之前,你必须喂给他学习资源,也就是数据,让机器从已知的样本中去得到一组泛用的规律,并且运用这个规律去预测或分类未知的资料。因此,这整个科目就成了庞大的交叉学科,因为要产生这个规律,你必须用机率论、数理统计、计算机理论、资料结构与演算法等等的学科去组 出来。

机器学习跨学科领域以及发展方向,Source:Udacity

再举个例子,假设我们有一组量化数据,去解释人长得好不好看,比方说老王是5分,小王是8分,我们在下这些判断前实质上是经过好多的变数去组合出来的,比方说鼻子挺不挺、眼睛大不大等等,当然对人类来说这些变数非常多,很可能是复杂又模糊的,我们不会描述一个人说他的眼睛长度大概6.32公分,鼻子倾斜角度75度,所以他长得好看。我们会说这是一种“感觉”,比方我觉得这个人五官很深邃,或是脸部很有古典美的气质,透过这些来判断一个人好不好看。但是对于机器来说可不是如此,机器可以很快速地处理大量且复杂的数据集,因此只要我喂给他足够的样本,下次他就可以根据一个人脸部大量的变数去说,这个人长得好不好看,有多好看。

聪明的你很快就发现,咦?这不就是回归模型吗? 是的,回归模型是机器学习中一个重要的演算法,能够协助机器去预测连续型数值,当然我们还有其他演算法去处理分类问题、聚类问题或降噪问题等等,但我们既然在谈时间序列,那本篇就会以机器学习中的各种回归模型为主,来介绍我们是如何架构资料分析的Pipeline。

机器学习中的回归模型

回归问题经过两百多年,绝对有更多元且更精准的模型发展出来,我简单列出目前比较常见的回归模型:Linear Model 一般线性模型、Ridge Regression 岭回归、Lasso回归、Elastic Net弹性网络、SVM 支持向量机等,还有比较违反以往对回归模型印象的树状演算法,譬如Decision Tree的回归树、SGD Regressor 随机梯度下降、Ranfom Forest Regression随机森林回归、....等等,整个目不暇给。

对于资料分析师或是工程师来说,深入了解这些演算法就有一定的必要,目前的Open Sources 或Packages非常方便,使得用机器学习来做分析的门槛不断下降,然而,当我们希望找到一组最佳的模型来拟和资料的时候,往往要做到参数调整甚至模型调整,更厉害的科学家甚至开创出新的模型,这些就都需要坚强的数学实力与电脑科学实力。

我们今天仍然不会介绍所有的模型(实际上也讲不完),但我们会来提到近几年在Kaggle(世界知名资料科学平台,虽然在去年被Google收购了而引起一阵哀号)竞赛上非常流行的XGBoost,是当时几乎囊括了大部分竞赛获胜队伍所使用的演算法,但在此之前我们需要先来点准备知识预热一下:

梯度下降(Gradient Descent)

记得我们说过,要找到一个最佳的模型我们应该要尽可能的最小化损失函数(Loss Function),而在这个前提下我们有一个最暴力但也最精确的做法叫做梯度下降法(Gradient Descent ):

假设我们有一个损失函数,我们并不知道在哪一个点它会出现最小值,但我们知道的是,只要一个函数在随机一点a 可微分且有定义,则该函数在a 点与梯度相反的方向下降的最快。梯度是什么,我们可以把梯度函数考虑成一个三维空间的一座山,沿着山坡往山顶最陡的方向就是所谓的梯度,因此,只要我们沿着最陡的地方反方向一路往前走,我们就能够用最快的速度达到最小值(也就是谷底),图示来说就会像这样:

Source:researchgate.net

接下来有一个问题产生了,我们如何用最快的步数去达到最小值呢(你总不希望程式执行个三天三夜)?这里要注意的是,我们一开始并不知道这座山长什么样,我们只能去判断A点朝哪个方向走最陡,但往那个方向走如果一次走太小步,我们有机率会花费非常多的时间才能够达到谷底,但如果一次走太大步,我们有可能会错过谷底导致估计变得非常不准,这时候我们就引进一个参数的概念,叫做Learning Rate(学习速率)。

在一个标准梯度下降的情况,我们可以将公式写成:

其中的符号η 就代表Learning Rate,范围在0到1之间。另外,有时候我们不是只想对单一函数做梯度下降,而是对函数空间作优化,那么我们的a 点就变成了函数f(x),要找到一个最佳的F*(x)。

Source:https://blog.csdn.net/google19890102/article/details/51746402

梯度提升算法(Gradient Boosting Algorithms)

在了解XGBoost以前,我们要先看一个概念叫做梯度提升(Gradient Boosting),这东西其实是两个部分所组成的,也就是我们刚刚提到的梯度下降法(Gradient Descent)以及提升算法(Boosting Algorithms ):

提升算法是机器整体学习中一个重要的环节(另一个是Bagging),Boosting是什么呢?想像我们刚才说的函数空间里头包含很多函数,这些函数实际上是指我们的基底学习器(Base Learning Models)所产生的损失函数,比方说我建立了一个线性回归与一个多项式回归,它们都有各自的损失函数,而我们要找到一个最佳的函数F(X),在这边就是模型的组合,来最小化总体损失,因此Boosting的算法实际上就是训练出多个模型再去做加权汇总,图示如下:

Source:https://blog.csdn.net/google19890102/article/details/51746402

那,如果把这两者结合到一起,就变成梯度提升算法(Gradient Boosting),也就是Boosting模型组合的方式是使用梯度下降的方法去算出来的,具体流程如下:

Source:researchgate.net

由上图我们可以发现,因为每一个函数实际上跟系数a以及相关系数有关,我们也要同时对这些数值做梯度下降之后去做加总得到下一个我们要计算的函数对象。唯一要注意的是,我们在建置这类模型时,会希望基底学习器彼此之间的表现(Performance)不要差异太大,否则建构Boosting算法就会用处不大,程式只要极大偏重于表现好的学习模型即可。

极限梯度提升(Extreme Gradient Boosting, XGBoost)

终于进入正题啦!什么是XGBoost呢?如果你认为前面那种程度不够暴力,那我们就来得更暴力一点,考虑一个二阶信息的梯度提升模型,也就是对函数做泰勒展开到二阶态,就会变成:

Source:https://blog.csdn.net/sinat_22594309/article/details/60957594

Omega我们可以先不用管他,只是一个惩罚项而已,另外,我们刚才一直没有提到说使用的f(x)函数是什么,这里揭开神秘面纱,叫做决策树模型(Decision Tree Model),XGBoost在其上引入了Tree Pruning的概念,不过这边我就不再多说了不然篇幅会变得落落长,对于该演算法想了解的,推荐两篇延伸阅读(上面没有数学下面有):

总而言之,透过极限梯度提升,我们能够大幅度提升模型表现,这是拜更精准的模型损失评估所赐,同时,我们也并不用担心这些运算会导致训练速度过慢,这个演算法的设计准许电脑CPU能够多线并行(详情要研究电脑硬体结构才会比较了解),另外,XGBoost也可以传入稀疏矩阵(Sparse Matrix)的输入,某种程度上也节省了前期资料处理的时间。

好了,说了半天我们还是直接上实作吧!

*题外话:相比于LightGBM与CatBoost这两个新兴的算法(2017年)而言,基本上XGBoost就要显得慢了许多,但三者在特征切分的方式上略有不同,因此我们也难以仅根据模型训练速度去评估哪个模型较佳。

建构XGBoost模型

首先,我们引入forecastxgb套件(在Python之中就叫做xgboost),并且这边我们对于趋势以及季节性简单做出一些调整,我们在这边透过decompose方法来处理季节性,代码如下:

跟上面提到的方法一样,我们用XGBoost建构出回归模型以后,就可以去对之后的资料做出预测,这个预测是基于自回归模型,也因此我们的函数叫做xgbar(),就是XGB+AR模型的意思。

我们也可以用上一篇提到的Lagged Regression的方式来建立模型,线性回归的RMSE在1.7左右,而XGBoost落在1.475,等于减少了13.3%的误差。

参数调整(Parameter Tuning)

一个模型基本上我们会再透过参数调整去想办法得到更好的表现,对于梯度提升模型来说,有一些参数会显得比较重要,通常这也是资料科学家的重头戏之一,透过对于演算法以及资料本身的深刻理解,去调整参数以追求更好的精确度,因而达到所谓的“产品研发”等级。当然,现在说机器学习门槛下奖的其中一个原因在于,即便对于模型或资料本身不够了解,我们还是可以用网格搜索的方式去暴力得到最佳解(也就是所有参数都跑一遍),然而,如果希望给予实际价值,也就是知道怎么样解释模型参数并给出商业上的建议,实际上还是要求分析师对于模型有一定的理解程度。

在这边先把XGBoost完整参数的说明连结附上:

直觉上我会去调整的参数包括各种惩罚项,这一来与资料分布的状况有关,二来与模型用来测试的分数基准有关,评估函数方式以及学习速率等,而其他的参数就视情况调整或是透过网格搜索,也就是暴力调整(只要不会train太久当然就随便你,但大部分时候都不太可能让你称心如意)

介绍一下自己调参的几个目标:

  1. 学习速率与迭代次数:这个非常好理解,学习速率越小则越有可能找到最优点,但相对地训练次数就必须提高,而相反学习速率越大可以更快地训练模型,但有可能出现震荡而找不到最佳值。因此这两个参数是最优先要调整的,通常我都是用逼近的方式(否则暴力搜索真的太久了)。

  2. 树状演算法参数:这边的说明可以在上面决策树的延伸阅读找到,不过这必须要是在你的演算法是tree才能使用。我自己的原则是,把参数分成非限制跟限制参数来看,非限制参数在避免Overfit的前提下调大,限制参数则根据样本情况去调整,比方说样本数量很大,我会调高每个节点的最小样本数以避免机器无法取样到足够有用的特征等。

  3. 惩罚项以及损失函数:通常如果竞赛或是公司专案有很明确的评断标准,那就让这个参数与该标准一致即可,如果没有则放心地都尝试看看。

基本上以上三个是我一定会去调整的,其他一些比较Minor的参数就见仁见智,通常这些调整完之后模型的绩效就已经到了一个临界值了,再能透过调整其他参数大幅改善绩效的情况相对很少。

最后要谨记的是,Gradient Boosting基本上可以无限深度无限迭代地去降低误差,因此我们必须经过Train-Test-Split的步骤来避免所谓的Overfitting,也就是说虽然训练资料的表现很好,但在测试资料的表现就很差的情况。

总结

讲完了XGBoost,我们接下来走进深度学习的范围试试看,下一篇会讲解所谓的神经网络(Neural Networks)到底是怎么一回事,以及如何建构一个人工神经网络(Artificial Neural Networks)来协助时间序列资料的预测。如果你喜欢我的文章,还请下方按个Clap唷!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多