前言
GBDT作为一个目前最厉害的机器学习的一个算法,似乎广受关注,其中使用最多的扩展或者说库基本上就是sklearn、xgboost、lightgbm。(当然我说的都是基于Python的)
然后就是网上的学习资料真是一坨坨的,非常的令人眼花缭乱,这里记录一下我学习的过程以及一些弯路的地方,因为我发现网上的教程里也是十分多只管抄不管解释的地方,导致阅读的人非常的混淆。由于我一开始就是带着一些问题去学习的,基本原理都了解的差不多,但是无法解答我的问题的我都很理所当然的觉得这是在耍流氓。。
先讲讲我的问题,希望有基础的读者思考一下这个问题的回答,再决定是不是要看这篇文章。
GBDT训练完后,如何从实现预测?请详细的解答?(因为我的目的是要重现这个过程,并且使用这个过程计算训练样本间的距离。)
那么为什么我说很多文章都无法解答这个问题呢,因为大家都说,就是预测结果的相加,但是几乎都没有讲清楚。例如我获得了一个有8个迭代树的GBDT,那我从每个树的预测结果如何得到我总的预测结果呢??肯定不是投票。但又是如何相加呢?
ok。。那么开始正文
正文
首先大家得清楚,GDBT是属于Boosting的一种,同理Adaboost也是Boosting的一种,所以说不要混淆二者的关系和原理。
Adaboost的过程是通过改变错误分类的样本的权重从而达到一个Boosting的目的,因为加入了上一次分错了这样一个考虑因素,下一次自然可以更偏向将其分对。
由于很多资料的不明确和复杂,我决定直接使用一个完整的gbdt(训练到预测)的过程进行阐释。
训练(二分类问题)
参数基本是sklearn的默认参数,所以即强分类器损失函数为LogOddsEstimator, 弱分类器损失函数为BinomialDeviance。
- 根据样本集的
y_true
计算一次初始化的LogOddsEstimator作为初始的整体分类器的损失(loss)。也是作为第一次的预测结果(非常重要!!!!)这里会考虑y的unbalance问题。 - 开始第一次的迭代boosting,通过决策树算法选择最优的分支方案,从而进行得到第一棵树的结构(仅仅是结构)。
- 使用上一个预测结果与不同的树节点(主要为叶节点),对每个节点单独的通过BinomialDeviance计算该节点内所有样本的残差值。从而得到多个累加量,(可用来更新上一个预测结果),导致每个叶节点有一个独立的预测值,同叶节点的样本均为一个值。
- 同理,由于已经建立了第一棵树,所以第二次预测时,此时的上一个预测结果为第一次的预测结果,加上3步中提到的累加量(需要乘上learning rate,再加上一次预测结果)。根据此预测结果进行建树、分叉,更新计算叶节点值。
。。。。。 - 此时,得到了多棵树的GBDT,即由不同树,的多个叶节点的累加值。那么最终的预测结果即,每次的预测结果,按照学习率加权后,累加得到最终的结果。
- 由于是二分类问题,再通过离散化操作,从而得到最终结果。
预测
由于上述的过程建立的一个树,那么进行预测时也就直接开始进行预测。
- 使用相同的训练时的初始化y预测值
- 进入第一棵树后,按照自上而下的过程,将样本分到各自的叶节点。然后就是得到了对应的累加量(自训练好后,累加量就已经不会变化,作为一个固有参数。)
- 将每棵树的累加量(按照学习率加权)与初始化的y预测值进行累加。
- 得到最终结果。
总结
似乎最终能说的也成了每棵树的结果的累加,但是却可以回答以下问题了。
- 加的是什么?
- 初始值是什么?
- 每棵树之间的关系是什么?
补充
由于觉得意犹未尽,觉得似乎还要把GBDT继续了解的更为透彻一点为好。
于是补充了以下问题的学习
- 什么是gain,gain与残差有什么区别?
- xgboost优化的地方在哪里
补充记录
- gain,其实是建立在xgboost的基础上的,这个说法似乎不太好。但意思是想说gain是只有在xgboost中才有的,原因是因为xgboost的建树方式与传统的CART、ID3这些不一样。而gain是一个树分叉前与分叉后的差值(是什么的差值得看情况),所以说gain是一个用来控制树分叉和复杂度和深度的数字,所以说与残差的距离有点远。。。
- 主要优化的是每棵树内部的东西,例如可以并行(节点分割上的并行)、可以限制树的深度、优化其找最优分割的速度。还有少部分有利于整体的则是提供了subsample的参数、弱分类器被扩展(不仅仅只有树)、对缺失值的处理。
参考
由于是学习记录,当然是有许多许多的参考,从上往下是我认为最有用的(有用不代表易读。)
网友评论