GBDT和XGBOOST算法原理
GBDT
以多分类问题为例介绍GBDT的算法,针对多分类问题,每次迭代都需要生成K个树(K为分类的个数),记为\(F_{mk}(x)\),其中m为迭代次数,k为分类。
针对每个训练样本,使用的损失函数通常为\[L(y_i, F_{m1}(x_i), ..., F_{mK}(x_i))=-\sum_{k=1}^{K}I({y_i}=k)ln[p_{mk}(x_i)]=-\sum_{k=1}^{K}I({y_i}=k)ln(\frac{e^{F_{mk}(x_i)}}{\sum_{l=1}^{K}e^{F_{ml}(x_i)}})\]
此时损失函数的梯度可以表示为\[g_{mki}=-\frac{\partial{L(y_i, F_{m1}(x_i), ..., F_{mK}(x_i))}}{\partial{F_{mk}(x_i)}}=I({y_i}=k)-p_{mk}(x_i)=I({y_i}=k)-\frac{e^{F_{mk}(x_i)}}{\sum_{l=1}^{K}e^{F_{ml}(x_i)}}\]
GBDT算法的流程如下所示:
- for k=1 to K: Initialize \(F_{0k}(x)=0\)
- for m=1 to M:
- for k=1 to K: compute \(g_{m-1,ki}\) for each sample \((x_i, y_i)\)
- for k=1 to K: build up regression tree \(R_{mkj}\)(j=1 to Jmk refer to the leaf nodes) from training samples \((x_i, g_{m-1,ki})_{i=1,...,N}\)
- for k=1 to K: compute leaf weights \(w_{mkj}\) for j=1 to Jmk
- for k=1 to K: \(F_{mk}(x)=F_{m-1,k}(x)+\eta*\sum_{j=1}^{J_{mk}}w_{mkj}I({x}\in{R_{mkj}})\), \(\eta\)为学习率
针对\(w_{mkj}\)的计算,有\[w_{mkj(j=1...J_{mk},k=1...K)}=argmin_{w_{kj(j=1...J_{mk},k=1...K)}}\sum_{i=1}^{N}L(y_i, ..., F_{m-1,k}(x_i)+\sum_{j=1}^{J_{mk}}w_{kj}I({x_i}\in{R_{mkj}}), ...)\]
为了求得w的值,使上述公式的一阶导数为0,利用Newton-Raphson公式(在这个问题中将初始值设为0,只进行一步迭代,并且Hessian矩阵只取对角线上的值),记\(L_i=L(y_i, ..., F_{m-1,k}(x_i)+\sum_{j=1}^{J_{mk}}w_{kj}I({x_i}\in{R_{mkj}}), ...)\),有\[w_{mkj}=-\frac{\sum_{i=1}^N\partial{L_i}/\partial{w_{kj}}}{\sum_{i=1}^N\partial^2{L_i}/\partial{w_{kj}^2}}=\frac{\sum_{i=1}^{N}I({x_i}\in{R_{mkj}})[I({y_i}=k)-p_{m-1,k}(x_i)]}{\sum_{i=1}^{N}I^2({x_i}\in{R_{mkj}})p_{m-1,k}(x_i)[1-p_{m-1,k}(x_i)]}=\frac{\sum_{x_i\in{R_{mkj}}}g_{m-1,ki}}{\sum_{x_i\in{R_{mkj}}}\lvert{g_{m-1,ki}}\rvert(1-\lvert{g_{m-1,ki}}\rvert)}\]
文献[1]在\(w_{mkj}\)的前面乘以了\(\frac{K-1}{K}\)的系数,可能原因是在分类器的建立过程中,可以把任意一个\(F_k(x)\)始终设为0,只计算剩余的\(F_k(x)\),因此\(w_{mkj} \gets \frac{1}{K}*0+\frac{K-1}{K}w_{mkj}\)
参考文献
[1] Friedman, Jerome H. Greedy function approximation: A gradient boosting machine. Ann. Statist. 29 (2001), 1189--1232.
XGBOOST
仍以多分类问题介绍XGBOOST的算法,相对于GBDT的一阶导数,XGBOOST还引入了二阶导数,并且加入了正则项。
区别于上文的符号,记\[g_{mki}=\frac{\partial{L(y_i, F_{m1}(x_i), ..., F_{mK}(x_i))}}{\partial{F_{mk}(x_i)}}=p_{mk}(x_i)-I({y_i}=k)=\frac{e^{F_{mk}(x_i)}}{\sum_{l=1}^{K}e^{F_{ml}(x_i)}}-I({y_i}=k)\]以及\[h_{mki}=\frac{\partial^2{L(y_i, F_{m1}(x_i), ..., F_{mK}(x_i))}}{\partial{F_{mk}(x_i)}^2}=p_{mk}(x_i)[1-p_{mk}(x_i)]\]
XGBOOST的计算流程如下:
- for k=1 to K: Initialize \(F_{0k}(x)=0\)
- for m=1 to M:
- for k=1 to K: compute \(g_{m-1,ki}\) and \(h_{m-1,ki}\) for each sample \((x_i, y_i)\)
- for k=1 to K: compute regression tree \(f_{mk}(x)=\sum_{j=1}^{J_{mk}}w_{mkj}I({x}\in{R_{mkj}})\), where \(R_{mkj}\)(j=1 to Jmk) refer to the leaf nodes, to minimize the function \(\sum_{i=1}^{N}[g_{m-1,ki}f_{mk}(x_i)+\frac{1}{2}h_{m-1,ki}f_{mk}(x_i)^2]+\Omega(f_{mk})\), where \(\Omega\) is the regularization function
- for k=1 to K: \(F_{mk}(x)=F_{m-1,k}(x)+\eta*\sum_{j=1}^{J_{mk}}w_{mkj}I({x}\in{R_{mkj}})\), \(\eta\)为学习率
针对回归树\(f_{mk}(x)=\sum_{j=1}^{J_{mk}}w_{mkj}I({x}\in{R_{mkj}})\)的求解,记\(\Omega(f_{mk})=\gamma J_{mk}+\frac \lambda {2}\sum_{j=1}^{J_{mk}}w_{mkj}^2\),最小化问题变为Jmk个独立的二次函数之和:\[\sum_{j=1}^{J_{mk}}[(\sum_{x_i \in R_{mkj}}g_{m-1,ki})w_{mkj}+\frac{1}{2}(\lambda+\sum_{x_i \in R_{mkj}}h_{m-1,ki})w_{mkj}^2]+\gamma J_{mk}\]
假设回归树的结构已经固定,记\(T_k=J_{mk},G_{kj}=\sum_{x_i \in R_{mkj}}g_{m-1,ki}和H_{kj}=\sum_{x_i \in R_{mkj}}h_{m-1,ki}\),此时在\(w_{mkj}=-\frac{G_{kj}}{H_{kj}+\lambda}\)时目标函数取得最小值,最小值为\(-\frac{1}{2}\sum_{j=1}^{T_k}\frac{G_{kj}^2}{H_{kj}+\lambda}+\gamma T_k\)
使用贪心算法确定回归树的结构,从一个节点开始不断进行分裂,分裂的规则是挑选使分裂增益最大的特征和分裂点进行分裂,直到达到某个停止条件为止。假设待分裂的节点为\(I\),分裂后的两个节点分别为\(I_L\)和\(I_R\),那么分裂增益可以表示为:\[-\frac{1}{2}\frac{(\sum_{x_i \in I}g_{m-1,ki})^2}{\lambda+\sum_{x_i \in I}h_{m-1,ki}}+\frac{1}{2}[\frac{(\sum_{x_i \in I_L}g_{m-1,ki})^2}{\lambda+\sum_{x_i \in I_L}h_{m-1,ki}}+\frac{(\sum_{x_i \in I_R}g_{m-1,ki})^2}{\lambda+\sum_{x_i \in I_R}h_{m-1,ki}}]-\gamma\]
XGBOOST的Python包中的重要参数
- eta(alias:learning_rate): learning rate or shrinkage,同上文的\(\eta\),常用值0.01~0.2
- gamma(alias: min_split_loss): min loss reduction to create new tree split,同上文的\(\gamma\)
- lambda(alias: reg_lambda): L2 regularization on leaf weights,同上文的\(\lambda\)
- alpha(alias: reg_alpha): L1 regularization on leaf weights
- max_depth: max depth per tree,常用值3~10
- min_child_weight: minimum sum of instance weight(hessian) of all observations required in a child,即在一个节点中的样本的损失函数二阶导数之和,以多分类为例,\(\sum_{x_i \in I}h_{mki}=\sum_{x_i \in I}p_{mk}(x_i)[1-p_{mk}(x_i)]\)
- subsample: % samples used per tree,常用值0.5~1
- colsample_bytree: % features used per tree,常用值0.5~1
- 针对样本类别不均衡问题,若是二分类问题,可以设置参数scale_pos_weight,通常设为sum(negative instances)/sum(positive instances); 若是多分类问题,可以通过xgboost.DMatrix(...,weight,...)或者在Scikit-Learn API中调用fit(...,sample_weight,...)
- 特征重要性可以通过该特征被选中作为节点分裂特征的次数来度量
- xgboost应用示例可参见文章Xgboost应用及调参示例
GBDT和XGBOOST算法原理的更多相关文章
- XGBoost算法原理小结
在两年半之前作过梯度提升树(GBDT)原理小结,但是对GBDT的算法库XGBoost没有单独拿出来分析.虽然XGBoost是GBDT的一种高效实现,但是里面也加入了很多独有的思路和方法,值得单独讲一讲 ...
- 机器学习总结(一) Adaboost,GBDT和XGboost算法
一: 提升方法概述 提升方法是一种常用的统计学习方法,其实就是将多个弱学习器提升(boost)为一个强学习器的算法.其工作机制是通过一个弱学习算法,从初始训练集中训练出一个弱学习器,再根据弱学习器的表 ...
- xgboost算法原理
XGBoost是2014年3月陈天奇博士提出的,是基于CART树的一种boosting算法,XGBoost使用CART树有两点原因:对于分类问题,CART树的叶子结点对应的值是一个实际的分数,而非一个 ...
- 转载:XGBOOST算法梳理
学习内容: CART树 算法原理 损失函数 分裂结点算法 正则化 对缺失值处理 优缺点 应用场景 sklearn参数 转自:https://zhuanlan.zhihu.com/p/58221959 ...
- 机器学习相关知识整理系列之三:Boosting算法原理,GBDT&XGBoost
1. Boosting算法基本思路 提升方法思路:对于一个复杂的问题,将多个专家的判断进行适当的综合所得出的判断,要比任何一个专家单独判断好.每一步产生一个弱预测模型(如决策树),并加权累加到总模型中 ...
- GBDT算法原理深入解析
GBDT算法原理深入解析 标签: 机器学习 集成学习 GBM GBDT XGBoost 梯度提升(Gradient boosting)是一种用于回归.分类和排序任务的机器学习技术,属于Boosting ...
- 提升学习算法简述:AdaBoost, GBDT和XGBoost
1. 历史及演进 提升学习算法,又常常被称为Boosting,其主要思想是集成多个弱分类器,然后线性组合成为强分类器.为什么弱分类算法可以通过线性组合形成强分类算法?其实这是有一定的理论基础的.198 ...
- 随机森林RF、XGBoost、GBDT和LightGBM的原理和区别
目录 1.基本知识点介绍 2.各个算法原理 2.1 随机森林 -- RandomForest 2.2 XGBoost算法 2.3 GBDT算法(Gradient Boosting Decision T ...
- 机器学习算法总结(四)——GBDT与XGBOOST
Boosting方法实际上是采用加法模型与前向分布算法.在上一篇提到的Adaboost算法也可以用加法模型和前向分布算法来表示.以决策树为基学习器的提升方法称为提升树(Boosting Tree).对 ...
随机推荐
- javascript 判断对象类型
typeof typeof是一个一元运算符,它返回的结果 始终是一个字符串,对不同的操作数,它返回不同的结果. 此表总结了typeof所有可能的返回值: 操作数类型 返回值 undefined &qu ...
- Python定时任务框架APScheduler
http://blog.csdn.net/chosen0ne/article/details/7842421 APScheduler是基于Quartz的一个Python定时任务框架,实现了Quartz ...
- BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树
BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树 题意: 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i, ...
- i春秋——Misc之百度杯
今天心里很是不开森,想想往日何必那么努力呢?不如你的比比皆是,可是人家就是因为有关系,你又能怎样呢? 你所有应该有的都被打翻了,别灰心,至少你曾经努力过! 愿我未来的学弟学妹们都能一直开开心心的过好每 ...
- 回归树(Regression Tree)
目录 回归树 理论解释 算法流程 ID3 和 C4.5 能不能用来回归? 回归树示例 References 说到决策树(Decision tree),我们很自然会想到用其做分类,每个叶子代表有限类别中 ...
- STM32学习笔记(一):跑马灯
本实验所采用的开发板为正点原子的MiniSTM32f103rc开发板,主函数程序如下,注释如下:main.c #include "stm32f10x.h" void Delay(u ...
- 怎么动态生成js变量
动态生成全局变量: //简单的用字符串作为变量名 window['hello'] = "hello, world"; alert(hello); //批量定义 for(var ...
- Mybatis:缓存,动态SQL,注解SQL以及动态标签使用
1 转义字符 字符 转义 描述 < < 小于 <= <= 小于等于 > > 大于 >= >= 大于等于 <> <> 不等于 &a ...
- 从壹开始前后端分离 39 || 想创建自己的dotnet模板么?看这里
缘起 开工是利啦!哈喽各位小伙伴,周三好呀,新的一年又开始了,老张给大家做个榜样,新的一年也要好好学习哟,这两天闲的无事就整理整理了这个系列的 Github 代码,增加了一个英文的 README ,然 ...
- go语言调度器源代码情景分析之三:内存
本文是<go调度器源代码情景分析>系列 第一章 预备知识的第2小节. 内存是计算机系统的存储设备,其主要作用是协助CPU在执行程序时存储数据和指令. 内存由大量内存单元组成,内存单元大小为 ...