当前位置: 代码迷 >> 综合 >> RF、GBDT、XGBoost、LightGBM比较
  详细解决方案

RF、GBDT、XGBoost、LightGBM比较

热度:72   发布时间:2023-12-14 18:59:15.0

RF、GBDT和XGBoost、LightGBM都属于集成学习(Ensemble Learning),集成学习的目的是通过结合多个基学习器的预测结果来改善单个学习器的泛化能力和鲁棒性。

根据个体学习器的生成方式,目前的集成学习方法大致分为两大类:即个体学习器之间存在强依赖关系、必须串行生成的序列化方法,以及个体学习器间不存在强依赖关系、可同时生成的并行化方法;前者的代表就是Boosting,后者的代表是Bagging和“随机森林”(Random Forest)。

 

1、RF

1.1 原理

  提到随机森林,就不得不提Bagging,Bagging可以简单的理解为:放回抽样,多数表决(分类)或简单平均(回归),同时Bagging的基学习器之间属于并列生成,不存在强依赖关系。

  Random Forest(随机森林)是Bagging的扩展变体,它在以决策树 为基学习器构建Bagging集成的基础上,进一步在决策树的训练过程中引入了随机特征选择,因此可以概括RF包括四个部分:1、随机选择样本(放回抽样);2、随机选择特征;3、构建决策树;4、随机森林投票(平均)。

  随机选择样本和Bagging相同,随机选择特征是指在树的构建中,会从样本集的特征集合中随机选择部分特征,然后再从这个子集中选择最优的属 性用于划分,这种随机性导致随机森林的偏差会有稍微的增加(相比于单棵不随机树),但是由于随机森林的‘平均’特性,会使得它的方差减小,而且方差的减小补偿了偏差的增大,因此总体而言是更好的模型。

  在构建决策树的时候,RF的每棵决策树都最大可能的进行生长而不进行剪枝;在对预测输出进行结合时,RF通常对分类问题使用简单投票法,回归任务使用简单平均法。

  RF的重要特性是不用对其进行交叉验证或者使用一个独立的测试集获得无偏估计,它可以在内部进行评估,也就是说在生成的过程中可以对误差进行无偏估计,由于每个基学习器只使用了训练集中约63.2%的样本,剩下约36.8%的样本可用做验证集来对其泛化性能进行“包外估计”。

  RF和Bagging对比:RF的起始性能较差,特别当只有一个基学习器时,随着学习器数目增多,随机森林通常会收敛到更低的泛化误差。随机森林的训练效率也会高于Bagging,因为在单个决策树的构建中,Bagging使用的是‘确定性’决策树,在选择特征划分结点时,要对所有的特征进行考虑,而随机森林使用的是‘随机性’特征数,只需考虑特征的子集。

1.2 优缺点

  随机森林的优点较多,简单总结:1、在数据集上表现良好,相对于其他算法有较大的优势(训练速度、预测准确度);2、能够处理很高维的数据,并且不用特征选择,而且在训练完后,给出特征的重要性;3、容易做成并行化方法。

RF的缺点:在噪声较大的分类或者回归问题上回过拟合。

 

2、GBDT

  提GBDT之前,谈一下Boosting,Boosting是一种与Bagging很类似的技术。不论是Boosting还是Bagging,所使用的多个分类器类型都是一致的。但是在前者当中,不同的分类器是通过串行训练而获得的,每个新分类器都根据已训练的分类器的性能来进行训练。Boosting是通过关注被已有分类器错分的那些数据来获得新的分类器。

  由于Boosting分类的结果是基于所有分类器的加权求和结果的,因此Boosting与Bagging不太一样,Bagging中的分类器权值是一样的,而Boosting中的分类器权重并不相等,每个权重代表对应的分类器在上一轮迭代中的成功度。

2.1 原理

  GBDT与传统的Boosting区别较大,它的每一次计算都是为了减少上一次的残差,而为了消除残差,我们可以在残差减小的梯度方向上建立模型,所以说,在GradientBoost中,每个新的模型的建立是为了使得之前的模型的残差往梯度下降的方法,与传统的Boosting中关注正确错误的样本加权有着很大的区别。

  在GradientBoosting算法中,关键就是利用损失函数的负梯度方向在当前模型的值作为残差的近似值,进而拟合一棵CART回归树。

  GBDT的会累加所有树的结果,而这种累加是无法通过分类完成的,因此GBDT的树都是CART回归树,而不是分类树(尽管GBDT调整后也可以用于分类但不代表GBDT的树为分类树)。

2.2 优缺点

  GBDT的性能在RF的基础上又有一步提升,因此其优点也很明显,1、它能灵活的处理各种类型的数据;2、在相对较少的调参时间下,预测的准确度较高。

当然由于它是Boosting,因此基学习器之前存在串行关系,难以并行训练数据。

 

3、XGBoost

3.1 原理

  XGBoost的性能在GBDT上又有一步提升,而其性能也能通过各种比赛管窥一二。坊间对XGBoost最大的认知在于其能够自动地运用CPU的多线程进行并行计算,同时在算法精度上也进行了精度的提高。

  由于GBDT在合理的参数设置下,往往要生成一定数量的树才能达到令人满意的准确率,在数据集较复杂时,模型可能需要几千次迭代运算。但是XGBoost利用并行的CPU更好的解决了这个问题。

3.2优点

  1、传统的GBDT以CART树作为基学习器,XGBoost还支持线性分类器(gblinear做提升运算),这个时候XGBoost相当于L1和L2正则化的逻辑斯蒂回归(分类)或者线性回归(回归);

传统的GBDT在优化的时候只用到一阶导数信息,XGBoost则对代价函数进行了二阶泰勒展开,得到一阶和二阶导数;

  2、XGBoost在代价函数中加入了正则项,用于控制模型的复杂度。从权衡方差偏差来看,它降低了模型的方差,使学习出来的模型更加简单,放置过拟合,这也是XGBoost优于传统GBDT的一个特性;

  3、shrinkage(缩减),相当于学习速率(XGBoost中的eta)。XGBoost在进行完一次迭代时,会将叶子节点的权值乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。(GBDT也有学习速率);

  4、列抽样。XGBoost借鉴了随机森林的做法,支持列抽样,不仅防止过 拟合,还能减少计算;

  5、对缺失值的处理。对于特征的值有缺失的样本,XGBoost还可以自动 学习出它的分裂方向;

      6、XGBoost工具支持并行。Boosting不是一种串行的结构吗?怎么并行 的?注意XGBoost的并行不是tree粒度的并行,XGBoost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。XGBoost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),XGBoost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代 中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。

        7、分裂算法有两种,一种是精确的分裂,一种是近似分裂算法,精确分裂算法就是把每个属性的每个取值都当作一次阈值进行遍历,采用的决策树是CART。近似分裂算法是对每个属性的所有取值进行分桶,按照各个桶之间的值作为划分阈值,xgboost提出了一个特殊的分桶策略,一般的分桶策略是每个样本的权重都是相同 的,但是xgboost使每个样本的权重为损失函数在该样本点的二阶导(泰勒展开不应该是损失函数关于模型的展开吗?为什么会有在该样本点的二阶导这种说法? 因为模型是对所有样本点都通用的,把该样本输入到二阶导公式中就可以得到了)。

        8、可以自定义损失函数,只要可以求二阶导数

3.3缺点

   1、level-wise 建树方式对当前层的所有叶子节点一视同仁,有些叶子节点分裂收益非常小,对结果没影响,但还是要分裂,加重了计算代价。

         2、预排序方法空间消耗比较大,不仅要保存特征值,也要保存特征的排序索引,同时时间消耗也大,在遍历每个分裂点时都要计算分裂增益(不过这个缺点可以被近似算法所克服)

 

4、lightGBM

4.1 与XGboost对比

  1、xgboost采用的是level-wise的分裂策略,每一层的节点可以做并行,而lightGBM采用了leaf-wise的策略,区别是xgboost对每一层所有节点做无差别分裂,可能有些节点的增益非常小,对结果影响不大,但是xgboost也进行了分裂,带来了务必要的开销。 leaft-wise的做法是在当前所有叶子节点中选择分裂收益最大的节点进行分裂,如此递归进行,很明显leaf-wise这种做法容易过拟合,因为容易陷入比较高的深度中,因此需要对最大深度或最大叶子数做限制,从而避免过拟合。

  2、lightgbm使用了基于histogram的决策树算法,这一点不同与xgboost中的 exact 算法,histogram算法在内存和计算代价上都有不小优势。

  (1)内存上优势:很明显,直方图算法的内存消耗为(#data* #features * 1Bytes)(因为对特征分桶后只需保存特征离散化之后的值),而xgboost的exact算法内存消耗为:(2 * #data * #features* 4Bytes),因为xgboost既要保存原始feature的值,也要保存这个值的顺序索引,这些值需要32位的浮点数来保存。

  (2)计算上的优势,预排序算法在选择好分裂特征计算分裂收益时需要遍历所有样本的特征值,时间为(#data),而直方图算法只需要遍历桶就行了,时间为(#bin)

  3、直方图做差加速

一个子节点的直方图可以通过父节点的直方图减去兄弟节点的直方图得到,从而加速计算。

  4、lightgbm支持直接输入categorical 的feature

在对离散特征分裂时,每个取值都当作一个桶,分裂时的增益算的是”是否属于某个category“的gain。类似于one-hot编码。

        5、多线程优化

        6、xgboost的预排序算法决定每个特征访问梯度的顺序是随机的,row_idx_to_node_idx表(这个表是用来确定每个节点对应的样本的)的访问也是随机的,会cache miss,而构建直方图时不同的特征会按相同的顺序访问梯度。在大数据量下顺序访问比随机访问快4倍以上,随机访问需要查询操作。

        7、xgboost处理可以指定missing值,对于missing值,一开始分裂的时候不使用这些值,分裂完后分别把这些值放到左子树和右子树计算增益,取增益高的方向为missing值的分裂方向。

        8、传统特征并行,适用于数据量比较小,但是特征比较多的情况,每个worker都保存所有数据点,但有不同的特征,在找出最优切分点后,worker间传播数据点的indexs,使得每个worker都进行分割。

        lightGBM优化后的特征并行,在每个worker上不仅保存所有数据点,还保留所有特征,那么就不需要传播indexs了

        传统数据并行,适用于数据量比较多,但是特征比较少的情况,每个worker保存部分数据点和所有特征,通过合并局部的直方图来分裂

        lightGBM优化后的数据并行,叫投票并行,每个worker通过计算局部的增益选出最优的topK个最优特征,然后所有worker一起选全局topK特征,在合并直方图的时候只使用这些特征,可以降低通信量。

        9、GOSS

        针对数量大,GOSS保留所有的梯度较大的实例,在梯度小的实例上使用随机采样。为了抵消对数据分布的影响,计算信息增益的时候,GOSS对小梯度的数据引入常量乘数。GOSS首先根据数据的梯度绝对值排序,选取top a个实例。然后在剩余的数据中随机采样b个实例。接着计算信息增益时为采样出的小梯度数据乘以(1-a)/b,这样算法就会更关注训练不足的实例,而不会过多改变原数据集的分布。

        10、EFB

        10.1 选择需要绑定的特征

        1、建立一个图,每个边有权重,其权重和特征之间总体冲突相关。

        2、按照降序排列图中的度数来排序特征。

        3、检查每个排序之后的每个特征,这个特征绑定到使得冲突最小的绑定,或者建立一个新的绑定。

        为了继续提高效率,LightGBM提出了一个更加高效的无图的排序策略:将特征按照非零值个数排序,这和使用图节点的度排序相似,因为更多的非零值通常会导致冲突。

        10.2 特征合并

        通过将互斥特征放在不同的箱中来构建bundle。这可以通过将偏移量添加到特征原始值中实现,例如,假设bundle中有两个特征,原始特征A取值[0, 10],B取值[0, 20]。我们添加偏移量10到B中,因此B取值[10, 30]。通过这种做法,就可以安全地将A、B特征合并,使用一个取值[0, 30]的特征取代AB。

        EFB算法能够将许多互斥的特征变为低维稠密的特征,就能够有效的避免不必要0值特征的计算。实际,通过用表记录数据中的非零值,来忽略零值特征,达到优化基础的直方图算法。通过扫描表中的数据,建直方图的时间复杂度将从O(#data)降到O(#non_zero_data)。