GBDT & xgboost

xgboost,GBDT在广告中的应用:

把用户和广告提出特征来,做组合,例如:男性&IT类, 统计这个类型下的点击率;来一个新样本,对应在这个特征上的点击率,作为一个特征值; 所有特征值就是GBDT输入特征向量;

 

GBDT的目标:最小化平方误差损失函数L=\sum_{}^{i}(y[i] - F_{t}(x[i]))^{2}

残差版本:把F_{t}(x[i])拆分成F_{t-1}(x[i]) + f_{t}(x[i]),  L转化为:\sum_{}^{i}((y[i] - F_{t-1}(x[i])) - f_{t}(x[i]))^{2}  ;即每个弱分类器f_{t}(x[i])只需要拟合残差(y[i] - F_{t-1}(x[i])即可;

梯度下降版本F_{t-1}(x[i])视为自变量,L视为因变量,所有样本i的dL/dF_{t-1}(x[i])构成的向量,就是梯度方向;即F_{t}(x[i])沿着该梯度方向的反方向进行变化可最大程度减少误差;即F_{t}(x[i]) = F_{t-1}(x[i]) - 梯度*步长;即所有样本i的f_{t}(x[i])需要拟合样本i的梯度*步长;

关于以上两个版本的对比:残差版本拟合的是全局最优值;梯度下降版本拟合的是向局部最优迈进的一步;前者最大问题是,由于它依赖残差,cost function一般固定为反映残差的均方差,因此很难处理纯回归问题之外的问题。而后者求解方法为梯度下降,只要可求导的cost function都可以使用。 

梯度下降版本的损失函数是平方损失函数时,梯度值就是残差(此时两个版本等价)。

CART树

GBDT要用CART树去拟合所有样本的残差(或者梯度);CART树是回归树;每个节点会有一个叶子值,最终拟合误差是所有样本(y[i]-叶子值)^2之和

建树用的还是贪心法:每个中间节点,对所有特征的所有分界点进行“试分”,即试着分成左右两个子节点,每个子节点选择使得自己节点内所有样本的均方误差最小的叶子值(也就是样本均值,用求导等于0求解得到的),计算一遍左右子节点的总误差;最终选择使这个总误差最小的划分;

2014年Facebook的paper (GBDT+LR): 把GBDT的输出作为稀疏特征,输入到LR;

 

xgboost:

把损失函数拆成2部分:\sum_{}^{i}L(F_{t-1}(x[i]) + f_{t}(x[i])) ;F_{t}(x[i])视为x,f_{t}(x[i])视为\bigtriangleupx,  套入到f(x+\bigtriangleupx)的二阶泰勒展开,得到关于L(F_{t}(x[i]))的一阶导和二阶导和f_{t}(x[i])的一次项和二次项的式子,再加上所有叶子值得平方正则项;f_{t}(x[i])使用样本落在的最终叶子上得叶子值w[k]来代替,可以转化为关于每个w[k]做未知数得二次方程,求解二次方程的最优自变量值(可以用求导等于0,也可使用初中的公式),得到每个w[k]的最优取值,带入方程得到该叶子节点对应的最优L。

建树的时候,每次划分使用贪心策略,即找在当前一分二能得到的最小误差,而不管最终的全局误差;具体实现是枚举所有特征,每次对父节点的所有样本,在该特征上进行排序,每次累加左子树(累减右子树)的一阶导项G[i]和二阶导项H[i],计算左右子树误差和;最终取所有特征所有划分里误差最小的那个划分点即可;(G[i]和H[i]们,不取决于特征,只和上次回归结果有关,所以在计算本轮弱分类器之前就先计算好)

 

xgboost和GBDT的区别:

   1)将树模型的复杂度加入到正则项中,来避免过拟合,因此泛化性能会优于GBDT。

   2)损失函数是用泰勒展开式展开的,同时用到了一阶导和二阶导,可以加快优化速度。

  3)和GBDT只支持CART作为基分类器之外,还支持线性分类器,在使用线性分类器的时候可以使用L1,L2正则化。

  4)引进了特征子采样,像RandomForest那样,这种方法既能降低过拟合,还能减少计算。

  5)在寻找最佳分割点时,考虑到传统的贪心算法效率较低,实现了一种近似贪心算法,用来加速和减小内存消耗,除此之外还考虑了稀疏数据集和缺失值的处理,对于特征的值有缺失的样本,XGBoost依然能自动找到其要分裂的方向。

  6)XGBoost支持并行处理,XGBoost的并行不是在模型上的并行,而是在特征上的并行,将特征列排序后以block的形式存储在内存中,在后面的迭代中重复使用这个结构。这个block也使得并行化成为了可能,其次在进行节点分裂时,计算每个特征的增益,最终选择增益最大的那个特征去做分割,那么各个特征的增益计算就可以开多线程进行。

             xgboost在训练之前,预先对数据进行排序,然后保存block结构,后面的迭代中重复的使用这个结构,大大减小计算量。这个block结构也使得并行称为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行

 

xgboost论文中文翻译

人家也用了2种方法:1. 按本特征值排序,顺序扫描,精细化找split点;2.直方图,按特征值的分布进行分桶,最后桶们aggregate,再顺序扫桶找split点(适用于多机分布式并行)

所有特征是训练刚开始的时候排序的,建好指向原始样本的索引;树的每层,只扫描一遍索引,该样本属于哪个叶子就更新哪个叶子;所有特征可以多机多线程并行扫描;

缺失值的处理:先把该特征上的所有缺失值的样本算作右子树,扫一遍;再全都算作左子树,扫一遍;2组score连起来求最优即可;

他也意识到了,数据集大到让操作系统文件缓存不够用(排空),才能精确测试I/O性能!

 

使用xgboost做二分类任务

样本在所有树的叶子节点值之加权和\hat{y[i]},要经过sigmoid函数,得到(0,1)范围的预测值;

损失函数就是极小化"负对数似然函数", 也叫交叉熵损失函数;式子里的y[i]是{0,1}取值的label, \hat{y[i]}是(-\infty,+\infty)范围的叶子节点值;

其他步骤和回归任务完全一样:将该损失函数对 \hat{y[t-1][i]}求一阶导和二阶导,得到g[i]和h[i],本子树要拟合的w[i],带入泰勒展开式子,得到最优w[i]取值和对应的最优L值;枚举所有特征的所有划分点,得到最最优的划分和左右子树的w[i]取值;最终样本们分到哪个叶子节点,就用哪个w做自己的y[t][i]; y[i] = y[t-1][i] + y[t][i]; y[i]经过sigmoid函数可得(0,1)的分类概率;

做多分类任务:对于k分类问题,每一轮迭代中,是构建了k个树,每一颗树的预测值代表对每个分类的打分,记为fk(x),那么其loss就是对应的softmax的loss。(某个样本,它在k组树的打分之加权和,就是它的k个类的打分, 把这k个打分经过softmax函数得到k个概率值就是分类结果)(损失函数用的还是极小化"负对数似然函数")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值