XGBoost

在这里插入图片描述
xgboost既可以做回归也可以做分类
我们知道对于单个的决策树模型容易出现过拟合,计算的结果有些绝对,并且不能在实际中有效应用。所以出现了集成学习方法。如下图,通过两棵树组合进行玩游戏的得分值预测。其中tree1中对小男生的预测分值为2,tree2对小男生的预测分值为0.9。则该小男生的最后得分值为2.9,实现了回归任务。
在这里插入图片描述
将上面集成学习方法推广到一般情况,可知其预测模型为:
在这里插入图片描述

xgboost结构

XGBoost并不是简单重复的将几个CART树进行组合。它是一种加法模型,将模型上次预测(由t-1棵树组合而成的模型)产生的误差作为参考进行下一棵树(第t棵树)的建立。以此,每加入一棵树,将其损失函数不断降低。
一开始在没有树的情况下为0,0的基础上在加入一颗新的树f1(x)进行预测,然后再在f1(x)的基础上新增一颗树f2(x),继续以前面的基础上新增树…即把前面的所有树当成一个整体,在保持了整体效果的情况下,新增一颗树使结果更加好。
在这里插入图片描述

目标函数:

以残差作为损失值,再加上树的惩罚项,其中惩罚项为对叶子节点和参数分布的惩罚。
在这里插入图片描述
在这里插入图片描述

用泰勒展开来近似目标函数

泰勒展开公式:
在这里插入图片描述
目标函数公式:
在这里插入图片描述
对比上面的式子,其中对应关系:
在这里插入图片描述
f(x)为原来前面的整体部分,∆x为新增的一颗树,所以可以展开f(x+∆x):
先令一次导数为gi,二次导数为hi:
在这里插入图片描述
即可得到展开的目标函数
在这里插入图片描述
又因为前面的整体部分的结果是固定的,所以前面部分得到的残差为常数项,可去掉:
在这里插入图片描述
而ft(xi)是将xi分到某个节点,然后与权重参数相乘,得到得分值,所以ft(xi)替换为wq(xi)即得到 xi 相应的得分值
左边求和符号从1到n是对n个样本的遍历,而最终每个样本都是落在叶子节点上的,所以可以转换为对叶子节点的遍历,在对叶子节点内的样本进行变量是一样的效果,j为叶子节点的编号。
由于f(x)将样本分到叶子节点,其中的每个样本都有一个f`(x)即gi,和f``(x)即hi,所以得到一下式子:
在这里插入图片描述
这里将叶子节点内的每个样本的一次导和二次导直接做求和得到Gi,Hi
在这里插入图片描述

求解目标函数

让目标函数为0,即可得到最优的权重参数wj,带回目标函数即为最终的目标函数。
在这里插入图片描述

打分函数

上面的Obj值代表当指定一个树结构时,在目标上面最多减少多少,我们可以把它称为结构分数。可以认为这是一个类似与基尼指数一样更一般的对树结构进行打分的函数。如下面的例子所示
在这里插入图片描述
对于求得Obj分数最小的树结构,我们可以枚举所有的可能性,然后对比结构分数来获得最优的树结构,然而这种方法计算消耗太大,更常用的是贪心法(事实上绝大多数树模型都是这样的,只考虑当前节点的划分最优),每次尝试对已经存在的叶节点(最开始的叶节点是根节点)进行分割,然后获得分割后的增益为:
在这里插入图片描述

精确搜索分裂算法

在这里以Gain作为判断是否分割的条件,这里的Gain可以看作是未分割前的Obj减去分割后的左右Obj,因此如果Gain<0,则此叶节点不做分割,然而这样对于每次分割还是需要列出所有的分割方案(对于特征的值的个数为n时,总共有2^n - 2 种划分)。
而实际中是采用近似贪心方法:

  • 先将所有样本按照gi从小到大排序,
  • 然后进行遍历,查看每个节点是否需要分割(对于特征的值的个数为n时,总共有n−1种划分)
    例如:现有n个样本,每个样本有m个特征,我们要判断第j个特征(比如年龄)能不能作为根节点分裂,则:
  • 首先对所有样本按年龄进行排序,假设年龄有5个值分别为10、20、30、40、50,这样就将样本分成5堆
  • 然后再进行下面图示的方法遍历各个分裂点,如10为一堆,20、30、40、50为一堆,10、20为一堆,30、40、50为一堆。。。
    在这里插入图片描述
    在这里插入图片描述
    伪代码解释:
    对所有样本 I 的第k维的值进行排序,x_jk为分裂点,对于每个分裂点 j 都进行Gain的比较,并将最大的 j 记录下来(即为合适的分裂点)
时间复杂度
  • 对于一层排序,需要Nlog(N),N为样本数目
  • 由于有D个特征,k层,所有为kDNlog(N)

近似搜索分裂算法

当数据较小的时候,可以按照以上的方法进行,但是数据量很大的时候,内存不能装入全部数据,这时候只能近似

近似算法的步骤
  • 近似算法还是得遍历所有特征的,只是当我们选择分裂点的时候,并不是尝试所有的分裂点,而是将在分裂点中进行抽样
    比如某个特征是连续值的,0到100,小数点也算的话,分裂点就有很多个可能
  • 近似算法就是根据特征的值的百分位数,提出特征的一些候选分裂点
    0到100的连续值,可以按10%,20%,30%…的值进行分裂
  • 然后再将样本分进不同的桶中,统计样本量
  • 计算比较各个分裂点的Gain
根据候选分裂点提出的时间,分为
  • 全局近似:在构造树的初始阶段提出所有的候选分裂点,然后对各个层次采用相同的候选
    *提出候选的次数少,但每次的候选数目多(因为候选不更新)
  • 局部近似:在每次分裂都重新提出候选
    *对层次较深的树更合适
    在这里插入图片描述
    伪代码解释:
  • 先对第k维的特征分为多个百分位数,
  • 再对每个样本进行分桶,即
    s_k,v(第k维样本,第v个百分位点) < x_j,k(第j个样本,第k维特征) < s_k,v-1(第k维样本,第v-1个百分位点)
  • 然后进行Gain计算比较

稀疏特征

XGBoost以统一的方式处理缺失(稀疏特征视为缺失值)的情况,分裂中只选择没有缺失的数据去进行节点分支,然后缺失情况默认指定一个方向,其效率paper里说了是提升了50倍。
算法的主要思想是,分别假设特征缺失的样本属于右子树和左子树,而且只在不缺失的样本上迭代,分别计算缺失样本属于右子树和左子树的增益,选择增益最大的方向为缺失数据的默认方向,在不缺失样本情况下分裂后,把第一个缺失样本放左边计算下loss function和放右边进行比较,同样对付第二个、第三个…缺失样本在这里插入图片描述

XGBoost算法流程

link
在这里插入图片描述
大家知道,Boosting算法的弱学习器是没法并行迭代的,但是单个弱学习器里面最耗时的是决策树的分裂过程,XGBoost针对这个分裂做了比较大的并行优化。对于不同的特征的特征划分点,XGBoost分别在不同的线程中并行选择分裂的最大增益。

同时,对训练的每个特征排序并且以块的的结构存储在内存中,方便后面迭代重复使用,减少计算量。计算量的减少参见上面第4节的算法流程,首先默认所有的样本都在右子树,然后从小到大迭代,依次放入左子树,并寻找最优的分裂点。这样做可以减少很多不必要的比较。

具体的过程如下图所示:
在这里插入图片描述
此外,通过设置合理的分块的大小,充分利用了CPU缓存进行读取加速(cache-aware access)。使得数据读取的速度更快。另外,通过将分块进行压缩(block compressoin)并存储到硬盘上,并且通过将分块分区到多个硬盘上实现了更大的IO。

特征重要性

采用树集成学习的好处之一就是可以从训练好的预测模型得到特征的重要性

  • 单棵树中的特征重要性:每个特征分裂点对性能的提升量,并用每个节点的样本数加权
    性能测量可以是用于选择分裂点的指标或其他更特别的误差函数
  • 整个模型的特征重要性:模型中每棵树的平均

子采样和权值收缩

其实这两个技巧都是为了减低overfitting,首先子采样分为样本子采样和特征子采样。子采样算是RF的代表了,通常来说我们使用特征取样更多。鄙人私下认为,特征子采样从不同角度去考量样本能让模型更具有多样性。另外权值收缩也就是对叶子节点的权值乘上收缩因子,该收缩因子是人为设定的参数。其作用是为了给后面的迭代保留优化空间。大家想想假如一棵树把损失函数降得很低很低,那么后续的优化空间就少了,训练的样本和特征也就少了,最后也就overfitting。当然XGB不仅仅只有这些tricks,例如leaf-wise, 后剪枝,树高度控制等。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值