极端梯度提升XGBoost
XGBoost属于boosting集成学习方法,其基学习器的学习是串行的。CART回归树的加法模型:
y^=ϕ(x)=i=1∑Kfk(x),fk∈F
其中,F={f(x)=wq(x)}(q:Rm→T,w∈RT)为包含所有CART回归树的函数空间。
-
每个fk对应一个独立的树结构q和叶子结点的得分,它的取值为样本点所在叶结点的得分,
-
树结构q看做一个诸多样本点映射到各个叶子结点的函数,T为叶子结点的个数,
-
wi代表第i个叶子结点的得分。
模型参数为每棵树的结构及其叶结点的得分,或者简单的记作Θ={f1,f2,...,fK},也就是说,这里我们要学习的是一个个函数——学习树模型:定义一个目标函数,然后最优化目标函数。
XGBoost目标函数——正则化思想
基于正则化思想,给定数据集{(xi,yi),1≤i≤n},xi∈Rm,yi∈R,通过最优化以下目标函数来学习模型,
fkminL(ϕ)=i=1∑nl(yi,y^i)+k=1∑KΩ(fk)whereΩ(f)=γT+21λ∣∣w∣∣2
其中,l为损失函数(可微、凸函数);Ω衡量树的复杂度:对叶结点个数T进行惩罚(剪枝),叶结点得分wL2正则化项(光滑的得分函数、避免过拟合)。
优化目标函数——Additive Training
由于我们这里的fk是树,而不是一般地数值向量,不能用像SGD这样的方法来求解,因此采用Additive Training。
第t轮学习中,我们需要寻找最优的ft得到预测 y^i(t)=y^i(t−1)+ft(xi),可写第t轮的目标函数
L(t)=i=1∑nl(yi,y^i(t))+k=1∑tΩ(fk)=i=1∑nl(yi,y^i(t−1)+ft(xi))+Ω(ft)+k=1∑t−1Ω(fk)
最后一项与ft无关,于是第t轮需要求解优化问题,
ftmini=1∑nl(yi,y^i(t−1)+ft(xi))+Ω(ft)
损失函数l(yi,ϕ)在ϕ=y^i(t−1)处进行二阶泰勒展开,
l(yi,ϕ)≈l(yi,y^i(t−1))+gi(ϕ−y^i(t−1))+21hi(ϕ−y^i(t−1))2
其中,
gi=[∂ϕ∂l(yi,ϕ)]ϕ=y^i(t−1),hi=[∂2ϕ∂2l(yi,ϕ)]ϕ=y^i(t−1)
令ϕ=y^i(t),
l(yi,y^i(t))≈l(yi,y^i(t−1))+gi(y^i(t)−y^i(t−1))+21hi(y^i(t)−y^i(t−1))2=l(yi,y^i(t−1))+gift(xi)+21hift2(xi)
l(yi,y^i(t−1))与ft无关,于是,可以求解如下优化问题来近似原问题的解,
ftminL~(t)=i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)
这里gi、hi也与ft无关。
将ft、Ω(ft)写成树模型,即将下式带入目标函数,
ft(x)=wq(x),Ω(ft)=γT+21λ∣∣w∣∣2
得到,
L~(t)=i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)=i=1∑n[giwq(xi)+21hiwq(xi)2]+γT+21λj=1∑Twj2
可以看到,目标函数中第一个累加和是按照样本点累加,第二个累加和是按照叶结点累加。定义每个叶结点j上的样本集合Ij={i∣q(xi)=j},则可以统一写成,
L~(t)=j=1∑T⎣⎡(i∈Ij∑gi)wj+21(i∈Ij∑hi+λ)wj2⎦⎤+γT=j=1∑T[Gjwj+21(Hj+λ)wj2]+γT
至此,优化问题转换为,
q,wminL~(t)=j=1∑T[Gjwj+21(Hj+λ)wj2]+γT
这里Gj,Hj与q(x)有关。
当树的结构q(x)确定后,为使目标函数最小,令
∂wj∂L~(t)=Gjwj+(Hj+λ)wj=0
解得第j个叶结点的最优得分为,
wj∗=−Hj+λGj
此时最优目标函数值为,
L~q∗=−21j=1∑THj+λGj2+γT
L~q∗只与树的结构有关,与叶结点的得分无关,并且它度量了树结构q的好坏:L~q∗越小,树结构q越好。 接下来就是要寻找最优的树结构q(x)。
回归树的学习
策略一:暴力枚举(太复杂,不可行)
- 枚举每一个可能的树结构;
- 对每个树结构,找到使L~q∗最小的树结构q;
- 确定最优树结构后,计算最优的叶子结点得分wj∗=−Hj+λGj
策略二:类似CART回归树的生成
现有树结构q(x),假设对其某个结点做切分,得到L和R两个叶结点,记新的树结构q′,则
gain=L~q∗−L~q′∗=21[HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2]−γ
若L~q∗−L~q′∗>0,则该叶结点切分后得到的树结构更好。通常需要指定一个阈值,当树结构改善程度大于某个数时,才进行切分。
我们得到了判断一个叶结点是否应该切分的标准,现在还需要寻找可能的切分点,一个切分点由切分特征及相应的切分值确定。
一种寻找切分点的方法是,遍历所有特征的所有可能的切分点,计算gain值,选取值最大的切分点去切分,称之为精确算法。
对于连续型特征值,当样本数量非常大,特征取值过多时,精确算法会花费很多时间,且容易过拟合。另一种思想是对特征进行分桶,即找到l个划分点,将位于相邻分位点之间的样本分在一个桶中,在遍历该特征的时候,只需要遍历各个分位点,从而计算最优划分。从算法伪代码中该流程还可以分为两种,全局的近似是在新生成一棵树之前就对各个特征计算分位点并划分样本,之后在每次分裂过程中都采用近似划分,而局部近似就是在具体的某一次分裂节点的过程中采用近似算法。
XGBoost算法流程
比较RF、AdaBoost、GDBT、XGBoost
AdaBoost与GBDT
- Adaboost是通过提高错分样本的权重来定位模型的不足,采用指数损失,基分类器是最常见为决策树(深度为1)
- GBDT是通过负梯度来定位模型的不足,因此GBDT可以使用更多种类的损失函数
RF与GBDT
- 组成RF的树可以是分类树,也可以是回归树;而GBDT只由回归树组成,因为GBDT对所有树的结果累加,累加无法通过分类完成
- 组成RF的树并行生成;GBDT串行生成 ,GBDT更容易过拟合
- 输出结果,RF采用多数投票等;GBDT将所有结果累加,或加权累加
- RF对异常值不敏感,GBDT对异常值敏感
- RF对训练集一视同仁,每棵树分裂特征随机;GBDT基于权值的弱分类器的集成 ,前面的树优先分裂对大部分样本区分的特征,后分裂对小部分样本区分的特征
- RF通过减少模型方差提高性能,GBDT通过减少模型偏差提高性能(低方差和高偏差)
- RF参数主要是树的棵树,GBDT主要是树的深度,一般为1
XGBoost与GBDT
- GBDT以CART作为基分类器,XGBoost还支持线性分类器。可以通过booster[default=gbtree]设置参数:gbtree:tree-based models;gblinear:linear models,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)
- GBDT用到一阶导数信息,XGBoost对代价函数进行了二阶泰勒展开,同时用到一阶与二阶导数,支持自定义代价函数(二阶可导)
- XGBoost在代价函数中加入正则化项,控制模型复杂度,降低模型variance,模型更加简单,防止过拟合,正则项包含树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。代替剪枝
- 分裂结点处通过结构打分和分割损失动态生长。结构分数代替了回归树的误差平方和
- 新增shronkage和column subsampling,为了防止过拟合
- 对缺失值处理。对特征值有缺失的样本,XGBoost可以自动学习它的分裂方向
- XGBoost工具支持并行,可并行的近似直方图算法
- XGBoost的训练速度快于GBDT,10倍量级。
参考:
GBDT与XGBoost
算法原论文:XGBoost: A Scalable Tree Boosting System
PPT:XGBoost Slide