1. XGBoost介绍
XGBoost模型即是一些“串联”树结构的组合,最终预测结果由多棵树共同决定。
模型公式: y=f(z)=∑Kk=1fk(z) y = f ( z ) = ∑ k = 1 K f k ( z )
模型预测: y^i=∑Kk=1f^k(xi) y ^ i = ∑ k = 1 K f ^ k ( x i )
类似模型预测,第 t t 步的估计可以表示为 。如何有效的估计每棵树,且如何重组多棵树使得XGBoost成为如今竞赛的常胜将军?我们需要解决以下三个问题:
问题0:树的组合方式
问题1:每棵树的结构-分枝
问题2:每个枝节点的预测值
下面分别按步骤依次解决上面三个问题:
解决方案0:树的组合方式是“串联”,即每一个树是建立在前面所有树预测残差的基础上优化得到。所以后续树的结构和枝节点的预测值也将按照“并联”方式逐个估计。
解决方案2:常规的解决方案是先解决树的结构,再确定每个节点的估计值,但XGBoost的推导过程是先假设树的结构的基础上先估计每个节点预测值,进而完善树的结构。任何优化问题之前,损失函数的确定是重中之重。XGBoost采用的是惩罚式损失 Obj=L+Ω O b j = L + Ω ,其中 L L 为损失函数,为惩罚项。且惩罚函数为: Ω=γT+λ∑Tj=1ω2j Ω = γ T + λ ∑ j = 1 T ω j 2 ,其中 T T 是枝节点的个数,是 j j 枝上的得分。假设已得到棵树,我们来估计第 t t 棵树的结构和节点估计。首先将数据和估计带入损失函数得:
将以上损失函数部分进行二次Taylor展开得:Obj(t)∼∑i=1n(ℓ(yi,y^(t−1)i)+gifi+12hif2i)+γT+λ∑j=1Tω2j∼∑i=1n(gifi+12hif2i)+γT+λ∑j=1Tω2j∼∑j=1T∑i∈Ij(gifi+12hif2i)+γT+λ∑j=1Tω2j=∑j=1T((∑i∈Ijgi)ωj+12(∑i∈Ijhi)ω2j)+γT+λ∑j=1Tω2j=∑j=1T((∑i∈Ijgi)ωj+12(∑i∈Ijhi+λ)ω2j)+γT=∑j=1T12(∑i∈Ijhi+λ)(ω2j+2∑i∈Ijgi∑i∈Ijhi+λωj)+γT=∑j=1T12(∑i∈Ijhi+λ)(ωj+∑i∈Ijgi∑i∈Ijhi+λ)2−12∑j=1T(∑i∈Ijgi)2∑i∈Ijhi+λ+γT=0(788)(789) O b j ( t ) ∼ ∑ i = 1 n ( ℓ ( y i , y ^ i ( t − 1 ) ) + g i f i + 1 2 h i f i 2 ) + γ T + λ ∑ j = 1 T ω j 2 ∼ ∑ i = 1 n ( g i f i + 1 2 h i f i 2 ) + γ T + λ ∑ j = 1 T ω j 2 ∼ ∑ j = 1 T ∑ i ∈ I j ( g i f i + 1 2 h i f i 2 ) + γ T + λ ∑ j = 1 T ω j 2 = ∑ j = 1 T ( ( ∑ i ∈ I j g i ) ω j + 1 2 ( ∑ i ∈ I j h i ) ω j 2 ) + γ T + λ ∑ j = 1 T ω j 2 (788) = ∑ j = 1 T ( ( ∑ i ∈ I j g i ) ω j + 1 2 ( ∑ i ∈ I j h i + λ ) ω j 2 ) + γ T = ∑ j = 1 T 1 2 ( ∑ i ∈ I j h i + λ ) ( ω j 2 + 2 ∑ i ∈ I j g i ∑ i ∈ I j h i + λ ω j ) + γ T (789) = ∑ j = 1 T 1 2 ( ∑ i ∈ I j h i + λ ) ( ω j + ∑ i ∈ I j g i ∑ i ∈ I j h i + λ ) 2 − 1 2 ∑ j = 1 T ( ∑ i ∈ I j g i ) 2 ∑ i ∈ I j h i + λ + γ T = 0
其中 gi=∂y(t−1)ℓ(yi,y^(t−1)i) g i = ∂ y ( t − 1 ) ℓ ( y i , y ^ i ( t − 1 ) ) 和 hi=∂2y(t−1)ℓ(yi,y^(t−1)i) h i = ∂ y ( t − 1 ) 2 ℓ ( y i , y ^ i ( t − 1 ) ) ,且 Ij I j 为 j j 个节点包含的数据指标集。将上面(84)式对求导得dObj(t)dωj=∑i∈Ijgi+(∑i∈Ijhi+λ)ωj=0 d O b j ( t ) d ω j = ∑ i ∈ I j g i + ( ∑ i ∈ I j h i + λ ) ω j = 0或从上式(85)的二次函数重组可以得到
ω∗j=−∑i∈Ijgi∑i∈Ijhi+λ ω j ∗ = − ∑ i ∈ I j g i ∑ i ∈ I j h i + λ且此时的目标函数可表达为:Obj(t)=−12∑j=1T(∑i∈Ijgi)2∑i∈Ijhi+λ+γT=−12∑j=1T((∑i∈Ijgi)2∑i∈Ijhi+λ+γ)=−12∑j=1T(GH+λ−2γ) O b j ( t ) = − 1 2 ∑ j = 1 T ( ∑ i ∈ I j g i ) 2 ∑ i ∈ I j h i + λ + γ T = − 1 2 ∑ j = 1 T ( ( ∑ i ∈ I j g i ) 2 ∑ i ∈ I j h i + λ + γ ) = − 1 2 ∑ j = 1 T ( G H + λ − 2 γ )- 解决方案1:如何得到树的结构呢?关键是确定每棵树的节点变量和如何划分节点。首先方案是:a. 对于每个节点,遍历全部变量 b. 对于每个变量,将所有的观测进行排序并进行扫描式,得到最好的切分点。如何判定切分点的好坏呢?根据以上增加该切分点,目标函数得变化量:
Δ=Obj(t)−(Obg(t)L+Obj(t)R)=12(GLHL+λ+GRHR+λ−GH+λ)−γ Δ = O b j ( t ) − ( O b g L ( t ) + O b j R ( t ) ) = 1 2 ( G L H L + λ + G R H R + λ − G H + λ ) − γ达到最大。
2. R简单实现
# Load packages
library(xgboost)
# Read data from xgboost package
data('agaricus.train', package = 'xgboost')
data('agaricus.test', package = 'xgboost')
tr <- agaricus.train
te <- agaricus.test
# Investigate data set
str(tr$data) ## dgCMatrix: Sparse matrix class from package Matrix
# Train xgboost model
## Input features: dense or sparse matrix both are ok
## Target variable: numeric vector(0-n for classification and real values for regression)
## Objective: 'reg:linear' for regression or 'binary:logistic'
## Number of iteration: number of trees added to the model
cv.res <- xgb.cv(data = tr$data, nfold = 5, label = tr$label,
nround = 10, objective = 'binary:logistic') # Cross Validation
cv.res <- xgb.cv(data = tr$data, nfold = 5, label = tr$label,
nround = 10, objective = 'binary:logistic',
eval_metric = 'auc') # Cross Validation
bst <- xgboost(data = tr$data, label = tr$label,
nround = 2, objective = 'binary:logistic',
eval_metric = 'auc')
pred <- predict(bst, te$data)
table(pred, te$label)