一、GBDT
GBDT(Gradient Boosting Decision Tree),梯度提升决策树。是一种基于决策树的集成算法。
G B D T = G r a d i e n t B o o s t i n g + D e c i s i o n T r e e GBDT = Gradient Boosting + Decision Tree GBDT=GradientBoosting+DecisionTree
- 其中Gradient Boosting 是集成方法boosting中的一种算法,通过梯度提升来对新的学习器进行迭代。
- GBDT中采用的决策树是CART回归树,无论是处理回归还是分类问题,GBDT使用的决策树通通都是都是CART回归树,因为GBDT每次迭代要拟合的是梯度值,是连续值,所以要用回归树。
(一)原理
1、Boosting提升方法:采用
加法模型(即基函数的线性组合):
F
(
x
)
=
∑
f
i
(
x
)
F(x)=\sum f_i(x)
F(x)=∑fi(x)
前向分布算法:
F
t
(
x
)
=
F
t
−
1
(
x
)
+
T
(
x
;
Θ
)
F_t(x)=F_{t-1}(x)+T(x;\Theta)
Ft(x)=Ft−1(x)+T(x;Θ)
通过经验风险最小化确定决策树参数:
Θ
^
m
=
a
r
g
min
Θ
m
∑
i
=
1
N
L
(
y
i
,
f
m
−
1
(
x
i
)
+
T
(
x
i
;
Θ
m
)
)
\hat{\Theta}_m=arg\min\limits_{\Theta_m}\sum_{i=1}^NL(y_i,f_{m-1}(x_i)+T(x_i;\Theta_m))
Θ^m=argΘmmini=1∑NL(yi,fm−1(xi)+T(xi;Θm))
2、学习残差
GBDT每棵加入的新的树,目标就是是学习残差
y
−
F
(
x
)
y-F(x)
y−F(x)。
即:假设已学好t-1个弱学习器(树),则第t棵树
f
t
(
x
)
f_t(x)
ft(x) 学习的目标就是
y
−
F
t
−
1
(
x
)
y-F_{t-1}(x)
y−Ft−1(x)。
3、残差的替代:负梯度
- 平方损失函数: L ( y , F ) = 1 2 ( y − F ( x ) ) 2 L(y,F)=\frac{1}{2}(y-F(x))^2 L(y,F)=21(y−F(x))2
- 残差: y i − F ( x i ) = − 1 2 ∂ ( y − F ( x ) ) 2 F ( x ) = − ∂ L ( y , F ( x ) ) ∂ F ( x ) y_i-F(x_i)=-\frac{1}{2}\frac{\partial(y-F(x))^2}{F(x)}=-\frac{\partial L(y,F(x))}{\partial F(x)} yi−F(xi)=−21F(x)∂(y−F(x))2=−∂F(x)∂L(y,F(x))
按照学习率进行梯度下降迭代:
f m ( x ) = f m − 1 ( x ) − η ∂ L ( y , F ( x ) ) ∂ F ( x ) f_m(x)=f_{m-1}(x)-\eta \frac{\partial L(y,F(x))}{\partial F(x)} fm(x)=fm−1(x)−η∂F(x)∂L(y,F(x))
f m ( x ) = f m − 1 ( x ) + η T m f_m(x)=f_{m-1}(x)+\eta T_m fm(x)=fm−1(x)+ηTm
∴ T m ( x ) = − ∂ L ( y , f m − 1 ( x ) ) ∂ f m − 1 ( x ) \therefore T_m(x)=-\frac{\partial L(y,f_{m-1}(x))}{\partial f_{m-1}(x)} ∴Tm(x)=−∂fm−1(x)∂L(y,fm−1(x))
4、负梯度
≠
\neq
=残差
不同问题的梯度提升树学习算法,使用的损失函数不同(其他损失函数时就不是残差)
- 用平方误差损失函数的回归问题;
- 用指数损失函数的分类问题;
- 用一般损失函数的一般决策问题
(二)算法流程
1、训练数据为 { ( x i , y i ) } i = 1 n \{(x_i,y_i)\}_{i=1}^{n} {(xi,yi)}i=1n,损失函数为 L ( y , F ( x ) ) L(y,F(x)) L(y,F(x)),可以是平方损失、绝对值损失、Huber损失函数等。共迭代M次,训练M棵树。
2、算法流程
- 初始学习器: F 0 ( x ) F_0(x) F0(x)在平方损失函数下,就是初始所有y的均值。
- 残差 r i m r_{im} rim,在进行前一次训练后,拟合的对象为: { ( x i , r i m ) } i = 1 n \{(x_i,r_{im})\}_{i=1}^{n} {(xi,rim)}i=1n,构建CART回归树来拟合。
- 为了避免过拟合,引入学习率 γ \gamma γ。
二、Xgboost算法
(一)目标函数
1、树的集成:
y
i
^
(
t
)
=
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
=
∑
t
=
1
T
f
t
(
x
i
)
\hat{y_i}^{(t)}=\hat{y_i}^{(t-1)}+f_t(x_i)=\sum_{t=1}^Tf_t(x_i)
yi^(t)=yi^(t−1)+ft(xi)=t=1∑Tft(xi)
2、目标函数:
O
B
j
=
L
(
Θ
)
+
Ω
(
Θ
)
Θ
=
{
f
1
,
f
2
,
.
.
.
,
f
T
}
OBj = L(\Theta)+\Omega(\Theta) \ \ \ \ \ \ \ \ \ \Theta=\{f_1,f_2,...,f_T\}
OBj=L(Θ)+Ω(Θ) Θ={f1,f2,...,fT}
其中,损失函数
L
(
Θ
)
L(\Theta)
L(Θ)、模型复杂度
Ω
(
Θ
)
\Omega(\Theta)
Ω(Θ)的定义为:
L
(
Θ
)
=
∑
i
=
1
n
l
(
y
i
,
y
i
^
)
——对所有样本求和
Ω
(
Θ
)
=
∑
k
=
1
K
Ω
(
f
k
)
——对所有树求和
\begin{aligned} L(\Theta)&=\sum_{i=1}^n l(y_i,\hat{y_i}) \ ——对所有样本求和\\ \Omega(\Theta)&=\sum_{k=1}^K\Omega(f_k) \ ——对所有树求和 \end{aligned}
L(Θ)Ω(Θ)=i=1∑nl(yi,yi^) ——对所有样本求和=k=1∑KΩ(fk) ——对所有树求和
泰勒展开:
f
(
x
+
Δ
x
)
≈
f
(
x
)
+
f
′
(
x
)
Δ
x
+
1
2
f
′
′
(
x
)
Δ
x
2
f(x+\Delta{x})\approx f(x)+f'(x)\Delta x+\frac{1}{2} f''(x)\Delta x^2
f(x+Δx)≈f(x)+f′(x)Δx+21f′′(x)Δx2
Δ x \Delta x Δx —— f t ( x i ) f_t(x_i) ft(xi)
f ( x + Δ x ) f(x+\Delta x) f(x+Δx) —— l ( y i , y i ^ ( t − 1 ) + f t ( x i ) ) = l ( y i , y i ^ ( t ) ) l(y_i,\hat{y_i}^{(t-1)}+f_t(x_i))=l(y_i,\hat{y_i}^{(t)}) l(yi,yi^(t−1)+ft(xi))=l(yi,yi^(t))
f ( x ) f(x) f(x) —— l ( y i , y i ^ ( t − 1 ) ) l(y_i,\hat{y_i}^{(t-1)}) l(yi,yi^(t−1))
f ′ ( x ) f'(x) f′(x) —— g i = ∂ l ( y i , y i ^ ( t − 1 ) ) ∂ y i ^ ( t − 1 ) g_i=\frac{\partial l(y_i,\hat{y_i}^{(t-1)})}{\partial \hat{y_i}^{(t-1)}} gi=∂yi^(t−1)∂l(yi,yi^(t−1))
f ′ ′ ( x ) f''(x) f′′(x) —— h i = ∂ 2 l ( y i , y i ^ ( t − 1 ) ) ∂ y i ^ ( t − 1 ) 2 h_i=\frac{\partial^2 l(y_i,\hat{y_i}^{(t-1)})}{\partial{ \hat{y_i}^{(t-1)}}^2} hi=∂yi^(t−1)2∂2l(yi,yi^(t−1))
代入上式、泰勒展开,目标函数最终形式:
O
B
j
(
t
)
=
∑
i
=
1
n
l
(
y
i
,
y
i
^
(
t
)
)
+
∑
k
=
1
K
Ω
(
f
k
)
=
∑
i
=
1
n
l
(
y
i
,
y
i
^
(
t
−
1
)
+
f
t
(
x
i
)
)
+
Ω
(
f
t
)
+
C
=
∑
i
=
1
n
[
l
(
y
i
,
y
i
^
(
t
−
1
)
)
+
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
+
C
\begin{aligned} OBj^{(t)}&=\sum_{i=1}^n l(y_i,\hat{y_i}^{(t)}) +\sum_{k=1}^K\Omega(f_k) \\ &= \sum_{i=1}^n l(y_i,\hat{y_i}^{(t-1)}+f_t(x_i)) +\Omega(f_t)+C \\ &= \sum_{i=1}^n [l(y_i,\hat{y_i}^{(t-1)})+g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)] +\Omega(f_t)+C \end{aligned}
OBj(t)=i=1∑nl(yi,yi^(t))+k=1∑KΩ(fk)=i=1∑nl(yi,yi^(t−1)+ft(xi))+Ω(ft)+C=i=1∑n[l(yi,yi^(t−1))+gift(xi)+21hift2(xi)]+Ω(ft)+C
其中
g
i
=
∂
l
(
y
i
,
y
i
^
(
t
−
1
)
)
∂
y
i
^
(
t
−
1
)
,
h
i
=
∂
2
l
(
y
i
,
y
i
^
(
t
−
1
)
)
∂
y
i
^
(
t
−
1
)
2
g_i=\frac{\partial l(y_i,\hat{y_i}^{(t-1)})}{\partial \hat{y_i}^{(t-1)}},h_i=\frac{\partial^2 l(y_i,\hat{y_i}^{(t-1)})}{\partial{ \hat{y_i}^{(t-1)}}^2}
gi=∂yi^(t−1)∂l(yi,yi^(t−1)),hi=∂yi^(t−1)2∂2l(yi,yi^(t−1))
前t-1颗树已知,所以
∑
i
=
1
n
l
(
y
i
,
y
i
^
(
t
−
1
)
)
\sum_{i=1}^n l(y_i,\hat{y_i}^{(t-1)})
∑i=1nl(yi,yi^(t−1)) 为已知常数项。
O
B
j
(
t
)
=
∑
i
=
1
n
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
+
C
\begin{aligned} OBj^{(t)}&= \sum_{i=1}^n [g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)] +\Omega(f_t)+C \end{aligned}
OBj(t)=i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)+C
(二)模型复杂度:
1、定义:待训练的第t颗树有T个叶子结点,叶子结点的输出向量为
[
ω
1
,
ω
2
,
.
.
.
,
ω
T
]
[\omega_1,\omega_2,...,\omega_T]
[ω1,ω2,...,ωT]。
q
:
R
d
→
{
1
,
2
,
3
,
.
.
.
,
T
}
q:R^d \rightarrow \{1,2,3,...,T\}
q:Rd→{1,2,3,...,T}
所以,
q
(
x
)
q(x)
q(x)表示对于每一个样本点x,其对应的叶子结点。
所以,
w
q
(
x
)
w_{q(x)}
wq(x)表示样本点x对应的叶子结点输出值,也就是树最终拟合的
f
t
(
x
i
)
f_t(x_i)
ft(xi)
2、对于每一个叶子结点 j j j,定义 I j = { i ∣ q ( x i ) = j } I_j=\{i|q(x_i)=j\} Ij={i∣q(xi)=j},表示每个叶子结点所包含的样本 x i x_i xi。
3、所以模型复杂度定义为:
Ω
(
f
t
)
=
γ
T
+
1
2
λ
∑
j
=
1
T
ω
j
2
\Omega(f_t)=\gamma T+\frac{1}{2} \lambda\sum_{j=1}^T \omega_j^2
Ω(ft)=γT+21λj=1∑Tωj2
T
T
T为叶子结点数,
ω
j
\omega_j
ωj表示叶子结点
j
j
j的输出,
γ
\gamma
γ为系数
目标函数最终化简为:
O
B
j
(
t
)
=
∑
i
=
1
n
[
g
i
f
t
(
x
i
)
+
1
2
h
i
f
t
2
(
x
i
)
]
+
Ω
(
f
t
)
=
∑
j
=
1
T
[
(
∑
i
∈
I
j
g
i
)
ω
q
(
x
i
)
+
1
2
(
∑
i
∈
I
j
h
i
+
λ
)
ω
q
(
x
i
)
2
]
+
γ
T
\begin{aligned} OBj^{(t)}&= \sum_{i=1}^n [g_if_t(x_i)+\frac{1}{2}h_if_t^2(x_i)] +\Omega(f_t)\\ &= \sum_{j=1}^T [(\sum_{i\in I_j}g_i) \omega_{q(x_i)}+\frac{1}{2}(\sum_{i\in I_j}h_i+\lambda)\omega_{q(x_i)}^2] +\gamma T \end{aligned}
OBj(t)=i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)=j=1∑T[(i∈Ij∑gi)ωq(xi)+21(i∈Ij∑hi+λ)ωq(xi)2]+γT
令
G
j
=
∑
i
∈
I
j
g
i
,
H
j
=
∑
i
∈
I
j
h
i
G_j=\sum_{i\in I_j}g_i , H_j=\sum_{i\in I_j}h_i
Gj=i∈Ij∑gi,Hj=i∈Ij∑hi
O B j ( t ) = ∑ j = 1 T [ G j ω j + 1 2 ( H i + λ ) ω j 2 ] + γ T \begin{aligned} OBj^{(t)}&= \sum_{j=1}^T [G_j \omega_j+\frac{1}{2}(H_i+\lambda)\omega_j^2] +\gamma T \end{aligned} OBj(t)=j=1∑T[Gjωj+21(Hi+λ)ωj2]+γT
(三)目标函数优化
目标函数为累加的,相互独立的二次函数,所以对于每一项进行优化。即:
w
j
=
a
r
g
min
x
G
j
x
+
1
2
(
H
j
+
λ
)
x
2
w_j=arg\min\limits_{x} \ G_jx+\frac{1}{2}(H_j+\lambda)x^2\\
wj=argxmin Gjx+21(Hj+λ)x2
解得最优参数:
w
j
∗
=
−
G
j
H
j
+
λ
w_j^* = -\frac{G_j}{H_j+\lambda}
wj∗=−Hj+λGj
解得目标函数最小值:
O
b
j
(
t
)
=
−
1
2
∑
j
=
1
T
G
j
2
H
j
+
λ
+
γ
T
Ob_j^{(t)}=-\frac{1}{2}\sum_{j=1}^T\frac{G_j^2}{H_j+\lambda}+\gamma T
Obj(t)=−21j=1∑THj+λGj2+γT
(四) 生成树策略
根据决策树的生成策略,再每次分裂节点的时候我们需要考虑能使得损失函数减小最快的节点,也就是分裂后损失函数减去分裂前损失函数我们称之为Gain:
G
a
i
n
=
1
2
[
G
L
2
H
L
+
λ
+
G
R
2
H
R
+
λ
−
(
G
L
+
G
R
)
2
H
L
+
H
R
+
λ
]
−
λ
Gain=\frac{1}{2}[\frac{G_L^2}{H_L+\lambda}+\frac{G_R^2}{H_R+\lambda}-\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}]-\lambda
Gain=21[HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2]−λ
Gain越大越能说明分裂后目标函数值减小越多。
(五)寻找最优节点
1、精确贪心算法
2、近似算法
(六)Xgboost 参数
xgboost中XGBClassifier()参数,调参的主要目的为选择合适的方法(分类/回归)、避免过拟合
常规参数
booster
gbtree 树模型做为基分类器(默认)
gbliner 线性模型做为基分类器
silent
silent=0时,输出中间过程(默认)
silent=1时,不输出中间过程
nthread
nthread=-1时,使用全部CPU进行并行运算(默认)
nthread=1时,使用1个CPU进行运算。
scale_pos_weight
正样本的权重,在二分类任务中,当正负样本比例失衡时,设置正样本的权重,模型效果更好。例如,当正负样本比例为1:10时,scale_pos_weight=10
模型参数
n_estimatores
含义:总共迭代的次数,即决策树的个数
调参:
early_stopping_rounds
含义:在验证集上,当连续n次迭代,分数没有提高后,提前终止训练。
调参:防止overfitting。
max_depth
含义:树的深度,默认值为6,典型值3-10。
调参:值越大,越容易过拟合;值越小,越容易欠拟合。
min_child_weight
含义:叶子结点中样本的数目最小值,默认值为1。
调参:值越大,避免模型学习到局部的特殊样本,越容易欠拟合;值越小,会出现单个样本成一个叶子结点的情况,越容易过拟合。
subsample
含义:训练每棵树时,使用的数据占全部训练集的比例。默认值为1,典型值为0.5-1。
调参:防止overfitting。
colsample_bytree
含义:训练每棵树时,使用的特征占全部特征的比例。默认值为1,典型值为0.5-1。
调参:防止overfitting。
学习任务参数
learning_rate
含义:学习率,控制每次迭代更新权重时的步长,默认0.3。
调参:值越小,训练越慢。
典型值为0.01-0.2。
objective 目标函数
回归任务
reg:linear (默认)
reg:logistic
二分类
binary:logistic 概率
binary:logitraw 类别
多分类
multi:softmax num_class=n 返回类别
multi:softprob num_class=n 返回概率
rank:pairwise
eval_metric
回归任务(默认rmse)
rmse--均方根误差
mae--平均绝对误差
分类任务(默认error)
auc--roc曲线下面积
error--错误率(二分类)
merror--错误率(多分类)
logloss--负对数似然函数(二分类)
mlogloss--负对数似然函数(多分类)
gamma
惩罚项系数,指定节点分裂所需的最小损失函数下降值。
调参:
alpha
L1范数的系数,默认为1
lambda
L2范数的系数,默认为1
示例
model = XGBClassifier(
booster='gbtree',
eval_metric='auc',
n_estimators=140,
learning_rate =0.05,
max_depth=7,
min_child_weight=0.1,
gamma=20,
subsample=0.7,
colsample_bytree=0.7,
colsample_level=0.7,
objective= 'binary:logistic',
nthread=4,
scale_pos_weight=2,
reg_alpha=5.4
reg_lambda=1,
seed=27,
alpha=0.1,
eta= 0.1,
silent=0)
三、Xgboost 和 GBDT 的区别:
GBDT:
1、优点:非线性变换比较多,表达能力强,而且不需要做复杂的特征工程和特征变换。
2、缺点:Boost 是一个串行过程,不好并行化,而且计算复杂度高,同时不太适合高维稀疏特征;传统 GBDT 在优化时只用到一阶导数信息。
Xgboost:
1、显式地把树模型复杂度作为正则项加到优化目标中。
2、公式推导中用到了二阶导数,用了二阶泰勒展开。(GBDT 用牛顿法貌似也是二阶信息)
3、实现了分裂点寻找近似算法。
4、利用了特征的稀疏性。
5、数据事先排序并且以 block 形式存储,有利于并行计算。
6、基于分布式通信框架 rabit,可以运行在 MPI 和 yarn 上。(最新已经不基于 rabit 了)
7、实现做了面向体系结构的优化,针对 cache 和内存做了性能优化。
四、代码实例
MNIST手写数字识别数据集——分类问题。
import numpy as np
import pandas as pd
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn import metrics
data = pd.read_csv('../input/digit-recognizer/train.csv')
X, y = data.drop(['label'], axis=1), data['label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=12)
model = xgb.XGBClassifier(learning_rate =0.3,
n_estimators=100,
max_depth=9,
min_child_weight=1,
nthread=4,
seed=27)
model.fit(X_train, y_train)
y_hat = model.predict(X_test)
print(metrics.classification_report(y_test, y_hat))
test = pd.read_csv('../input/digit-recognizer/test.csv')
y_pred = model.predict(test)
index = len(y_pred)
index = [i + 1 for i in range(index)]
y_pred.index = index
y_pred.index.name = 'ImageId'
y_pred = y_pred.rename({0: 'Label'}, axis=1)
y_pred.to_csv('./submission.csv')