集成学习
介绍
集成学习(ensemble learning)通过构建并结合多个弱学习器(也叫基学习器)来完成机器学习任务,提升单个学习器的性能。
集成学习主要三个类别:Bagging,Boosting和Stacking。Bagging有随机森林算法,Boosting有Adaboost、GBDT等算法,Stacking没有具体的算法,只是把多种算法融合在一起。
Bagging使用了有放回抽样方法,每次从训练数据抽取N个样本(N是训练数据的大小),训练一个基学习器,最后综合多个基学习器得到最终的模型。Bagging中的基学习器可以并行训练,彼此之间没有依赖关系。
Boosting也可以称为提升方法,实际采用加法模型(基学习器的线性组合)与前向分步算法。Boosting会初始化一个先验模型作为当前模型。根据训练数据的权值或者根据训练数据和当前模型的残差训练一个基学习器,并将这个基学习器添加到当前模型中,下一轮会根据训练数据和更新后的模型再训练一个基学习器。所以,Boosting中的基学习器是相互依赖的,只能串行训练。
Stacking是一种可以把多种算法融合在一起的集成方法,也称为模型融合。给定训练集和测试集,选择一个模型,比如逻辑回归,对训练集进行K
折交叉验证,因此可以训练K
个逻辑回归模型。对于每个模型,
- 需要对对应的验证集进行预测,然后把所有验证集的预测结果叠加起来,可以得到一个列向量,长度等于训练集的大小。该向量可以看作训练集的一个新的特征。
- 需要对预测集进行预测,然后把测试集的预测结果相加并求平均值,长度等于测试集的大小。该向量可以看作测试集的特征。
接下来可以选择参数不同的逻辑回归模型或者选择其他模型,再生成多个新的特征。
最后,在新的训练集进行训练一个算法,并对新的测试集进行预测。
Stacking过程如下图所示:
Bagging和Boosting的区别
Bagging选择不稳定的、方差大的基学习器,比如决策树和神经网络,不可以选线性模型;Boosting方法选择拟合能力强的基学习器,比如决策树和线性学习器。
从方差和偏差的角度看,Bagging方法主要关注降低方差,Boosting方法主要关注降低偏差。但是在GBDT的实现中,也可以使用数据和特征抽样方法来降低方差。
Boosting降低偏差比较容易理解,每次对当前模型在训练数据上的预测值与真实值的残差拟合一棵树,使训练误差越来越小。
Bagging降低方差不太好理解。Bagging中的每个基学习器在不完全相同的数据集上训练,基学习器之间的方差比较大。但是,基学习器的效果是优于随机的,而且每个学习器的误差有一定独立性。通过集成所有基学习器的预测结果,可以使模型的预测结果趋于正确值,降低了模型的方差,提高了模型的泛化能力。
随机森林
随机森林(Random Forest)是一种Bagging集成算法。它对Bagging进行了改进,选择CART决策树作为基学习器;还有在分裂结点时,随机抽取一部分特征并选择其中最好的特征。
Adaboost
介绍
Adaboost是一种Boosting集成算法。它为每一个样本分配了一个权重,根据训练数据和对应的权重训练一个基学习器,计算该学习器的加权分类误差率,然后根据分类误差率调整每个样本的权重:减小分类正确的样本的权重,增大分类错误的样本的权重。Adaboost依次训练多个基学习器,最终组合所有学习器为最终的模型。
描述
训练数据是二类的,目标值是-1
或+1
。训练集大小为N
,每个样本的初始权重为1/N
,权重之和为1
。
需要训练多个基学习器,对于一个基学习器:
- 根据当前的训练数据和权重,训练一个基学习器 G m G_m Gm,使该学习器的分类误差率最低。分类误差率是分类错误的数据的权重之和。
- 假设分类误差率为
e
m
e_m
em,计算该基学习器的系数
α
m
=
1
2
l
n
1
−
e
m
e
m
\alpha_m=\frac{1}{2}ln\frac{1-e_m}{e_m}
αm=21lnem1−em。分类正确的样本的权重乘以
e
−
α
m
e^{-\alpha_m}
e−αm,分类错误的样本的权重乘以
e
α
m
e^{\alpha_m}
eαm,然后对所有样本的权重进行归一化,保证权重之和为
1
。 - 因为分类误差率小于二分之一,所以 α m > 0 \alpha_m>0 αm>0,分类正确的样本权重减小,分类错误的样本权重增大。
最后,构建基学习器的线性组合: G ( x ) = s i g n ( ∑ m = 1 M α m G m ( x ) ) G(x)=sign(\sum_{m=1}^{M}\alpha_mG_m(x)) G(x)=sign(∑m=1MαmGm(x))。
提升树
介绍
提升树(Boosting Tree)是一种Boosting集成算法。提升树算法使用决策树作为基学习器,对分类问题是二叉分类树,回归问题是二叉回归树。
对于二分类问题,提升树算法只需要将AdaBoost 算法中的基学习器限制为二叉分类树即可。可以说这时的提升树算法是Adaboost算法的特殊情况。
对于回归问题,提升树算法每次根据训练数据的真实目标值和当前模型的预测值的残差训练一个基学习器,更新当前模型,并不断重复。
前提:
- 提升树模型可表示为决策树的加法模型: f M ( x ) = ∑ m = 1 M T ( x ; Θ m ) f_M(x)=\sum_{m=1}^MT(x;\Theta_m) fM(x)=∑m=1MT(x;Θm)。
- 首先初始化提升树 f 0 ( x ) = 0 f_0(x)=0 f0(x)=0,则第 m m m 步的模型为: f m ( x ) = f m − 1 ( x ) + T ( x ; Θ m ) f_m(x)=f_{m-1}(x)+T(x;\Theta_m) fm(x)=fm−1(x)+T(x;Θm)。
- 通过经验风险最小化确定下一棵决策树的参数。换句话说,下一棵决策树需要拟合训练数据和当前模型的残差。
Θ ^ m = arg min Θ m ∑ i = 1 N L ( y i , f m − 1 ( x i ) + T ( x i ; Θ m ) ) \hat{\Theta}_m=\arg\underset{\Theta_m}{\min}\sum_{i=1}^NL(y_i,{\color{Red} f_{m-1}(x_i)+T(x_i;\Theta_m)}) Θ^m=argΘmmini=1∑NL(yi,fm−1(xi)+T(xi;Θm))
描述
输入:训练集 T = { ( x 1 , y 1 ) , . . , ( x N , y N ) } , x i ∈ R n , y i ∈ R T=\{(x_1,y_1),..,(x_N,y_N)\},\; x_i \in R^n,\; y_i \in R T={(x1,y1),..,(xN,yN)},xi∈Rn,yi∈R。
输出:提升树模型 f M ( x ) f_M(x) fM(x)。
- 初始化当前模型 f 0 ( x ) = 0 f_0(x)=0 f0(x)=0
- 对
m
=
1
,
2
,
.
.
.
,
m
m=1,2,...,m
m=1,2,...,m,
- 计算残差, r m , i = y i − f m − 1 ( x i ) , i = 1 , 2 , . . , N {\color{Red} r_{m,i}}=y_i-f_{m-1}(x_i),\quad i=1,2,..,N rm,i=yi−fm−1(xi),i=1,2,..,N
- 拟合残差,学习下一个回归树的参数, Θ ^ m = arg min Θ m ∑ i = 1 N L ( r m , i , T ( x i ; Θ m ) ) \hat{\Theta}_m=\arg\underset{\Theta_m}{\min}\sum_{i=1}^N L({\color{Red} r_{m,i}},{\color{Blue} T(x_i;\Theta_m)}) Θ^m=argΘmmin∑i=1NL(rm,i,T(xi;Θm))
- 更新当前模型, f m ( x ) = f m − 1 ( x ) + T ( x ; Θ m ) f_m(x)=f_{m-1}(x)+T(x;\Theta_m) fm(x)=fm−1(x)+T(x;Θm)
- 得到回归提升树, f M ( x ) = ∑ m = 1 M T ( x ; Θ m ) f_M(x)=\sum_{m=1}^MT(x;\Theta_m) fM(x)=∑m=1MT(x;Θm)
GBDT
介绍
GBDT(Gradient Boosting Decision Tree,梯度提升树)是一种以提升树算法为基础的Boosting集成算法。它使用CART回归树作为基学习器,不管是分类任务还是回归任务。
GBDT的关键是利用损失函数在当前模型的负梯度作为残差的近似值,根据不同的任务选择不同的损失函数。
用梯度近似的好处:提升树利用加法模型与前向分步算法实现学习的优化过程。当损失函数是平方损失和指数损失函数时,每一步的优化很简单的。但对一般损失函数而言,往往每一步优化并不那么容易。利用负梯度近似残差,可以引入更多的损失函数,解决更多的问题。
描述
输入:训练集 T = { ( x 1 , y 1 ) , . . , ( x N , y N ) } , x i ∈ R n , y i ∈ R T=\{(x_1,y_1),..,(x_N,y_N)\},\; x_i \in R^n,\; y_i \in R T={(x1,y1),..,(xN,yN)},xi∈Rn,yi∈R。
输出:提升树模型 f M ( x ) f_M(x) fM(x)。
- 初始化一棵回归树,最小化当前损失, f 0 ( x ) = arg min c ∑ i = 1 N L ( y i , c ) f_0(x)=\color{Red} \arg\underset{c}{\min}\sum_{i=1}^NL(y_i,c) f0(x)=argcmin∑i=1NL(yi,c)
- 对
m
=
1
,
2
,
.
.
.
,
m
m=1,2,...,m
m=1,2,...,m,
- 对 i = 1 , 2 , . . , N i=1,2,..,N i=1,2,..,N,计算负梯度, r m , i = − ∂ L ( y i , f m − 1 ( x i ) ) ) ∂ f m − 1 ( x i ) r_{m,i}=-\frac{\partial L(y_i,{\color{Red} f_{m-1}(x_i)}))}{\partial {\color{Red} f_{m-1}(x_i)}} rm,i=−∂fm−1(xi)∂L(yi,fm−1(xi)))
- 对 r m , i r_{m,i} rm,i 拟合一棵回归树,得到第m棵树的叶节点区域: R m , j , j = 1 , 2 , . . , J R_{m,j},\;j=1,2,..,J Rm,j,j=1,2,..,J
- 对 j = 1 , 2 , . . , J j=1,2,..,J j=1,2,..,J,估计叶结点区域的值, c m , j = arg min c ∑ x i ∈ R m , j L ( y i , f m − 1 ( x i ) + c ) c_{m,j}={\color{Red} \arg\underset{c}{\min}}\sum_{x_i\in R_{m,j}}L(y_i,{\color{Blue} f_{m-1}(x_i)+c}) cm,j=argcmin∑xi∈Rm,jL(yi,fm−1(xi)+c)
- 更新当前模型, f m ( x ) = f m − 1 ( x ) + ∑ j = 1 J c m , j I ( x ∈ R m , j ) f_m(x)=f_{m-1}(x)+\sum_{j=1}^J c_{m,j}{\color{Blue} I(x\in R_{m,j})} fm(x)=fm−1(x)+∑j=1Jcm,jI(x∈Rm,j)
- 得到最终的提升树模型, f M ( x ) = ∑ i = 1 M ∑ j = 1 J c m , j I ( x ∈ R m , j ) f_M(x)=\sum_{i=1}^M\sum_{j=1}^Jc_{m,j}{\color{Blue} I(x\in R_{m,j})} fM(x)=∑i=1M∑j=1Jcm,jI(x∈Rm,j)
说明:
- 第 1 步初始化,估计使损失函数最小的常数值,得到一棵只有一个根节点的树。对于分类,该常数值为训练数据中目标值的众数;对于标准回归,该常数值是训练数据中目标值的平均数。
- 第 2(i) 步计算损失函数的负梯度,将其作为残差的估计。对平方损失而言,负梯度就是残差;对于一般的损失函数,它是残差的近似。
- 第 2(ii) 步拟合一棵回归树,以负梯度为目标值。此时叶子结点保存了负梯度的近似值。
- 第 2(iii) 步利用线性搜索估计叶节点区域的值,更新叶子结点。对不同的损失函数,估计叶结点区域的值有不同的方法。在算法实现中,一般用学习率来代替线性搜索。
- 第 2(iv) 步更新当前模型。
如何做多分类
如果数据集有多个类别,需要对每个样本的类标签进行onehot处理。举个例子,假设数据集有3个类别,样本 ( x , y ) (x,y) (x,y)属于第二个类别。onehot处理后,样本的类标签 y y y变为 ( 0 , 1 , 0 ) T (0,1,0)^T (0,1,0)T。此时,该样本分身为3个数据,分别是 ( x , 0 ) , ( x , 1 ) , ( x , 0 ) (x,0), (x,1), (x,0) (x,0),(x,1),(x,0)。
如果数据集有K个类别,一个数据变为K个数据,数据量变为原来的K倍,需要对每个类标签的数据拟合一棵回归树。所以,对于多分类问题,每次需要拟合K棵回归树。
损失函数
介绍一下sklearn
中GBDT使用的损失函数。TODO
给定一个样本 ( x , y ) (x,y) (x,y), x ∈ R d x \in R^d x∈Rd是样本特征, y y y是样本的真实目标值。给定 y ^ \hat{y} y^是当前模型对该样本的预测值。
分类
一、交叉熵损失函数
二分类交叉熵:
- 损失函数的形式为: L ( x ) = − [ y ln h ( y ^ ) + ( 1 − y ) ln ( 1 − h ( y ^ ) ) ] = − [ y y ^ + ln ( 1 − h ( y ^ ) ) ] L(x) = -[y\ln{h(\hat{y})}+ (1-y)\ln{(1-h(\hat{y}))}]=-[y\hat{y}+\ln{(1-h(\hat{y}))}] L(x)=−[ylnh(y^)+(1−y)ln(1−h(y^))]=−[yy^+ln(1−h(y^))],其中 y ∈ { 0 , 1 } y \in \{0,1\} y∈{0,1}, h ( y ^ ) = 1 / ( 1 + e − y ^ ) h(\hat{y})=1/(1+e^{-\hat{y}}) h(y^)=1/(1+e−y^)为sigmoid变换函数,其输出值可以认为是该样本属于正类的概率。
- 损失函数对当前模型的负梯度为: − ∂ L ∂ y ^ = y − h ( y ^ ) -\frac{\partial{L}}{\partial{\hat{y}}}=y-h(\hat{y}) −∂y^∂L=y−h(y^)。
多分类交叉熵:
- 在多分类问题中,需要对目标值
y
y
y进行onehot处理。假设有K个类别,
y
y
y转化为K维向量
(
y
[
1
]
,
y
[
2
]
,
.
.
.
,
y
[
K
]
)
T
∈
R
K
(y[1],y[2],...,y[K])^T \in R^K
(y[1],y[2],...,y[K])T∈RK,其中一个元素对应一个类别,而且只有一个元素为1,其余均为0。预测值
y
^
∈
R
K
\hat{y} \in R^K
y^∈RK,其中每个元素
y
^
[
k
]
\hat{y}[k]
y^[k]为对应类别
k
的预测值。 - 损失函数的形式为:
L
(
x
)
=
−
∑
j
=
1
K
y
[
j
]
ln
h
(
y
^
[
j
]
)
L(x)=-\sum_{j=1}^{K}y[j]\ln h(\hat{y}[j])
L(x)=−∑j=1Ky[j]lnh(y^[j]),其中
h
(
y
^
[
j
]
)
=
e
y
^
[
j
]
/
∑
k
=
1
K
e
y
^
[
k
]
h(\hat{y}[j])=e^{\hat{y}[j]}{}/ \sum_{k=1}^{K}e^{\hat{y}[k]}
h(y^[j])=ey^[j]/∑k=1Key^[k]为softmax变换函数,其输出值可以认为是该样本属于类别
j
的概率。 - 损失函数对当前模型的负梯度为: − ∂ L ∂ y ^ = y − h ( y ^ ) ∈ R K -\frac{\partial{L}}{\partial{\hat{y}}}=y-h(\hat{y}) \in R^K −∂y^∂L=y−h(y^)∈RK。
二、指数损失函数
Adaboost算法使用该损失函数。该损失函数只适用于二分类。
- 损失函数的形式为: L ( x ) = e x p ( − y h ( y ^ ) ) L(x)=exp(-yh(\hat{y})) L(x)=exp(−yh(y^)),其中 y ∈ { − 1 , 1 } y \in \{-1,1\} y∈{−1,1}。
- 损失函数对当前模型的负梯度为:
回归
一、最小平方误差损失函数
标准回归的损失函数。
- 损失函数的形式为: L ( x ) = 1 2 ( y − y ^ ) 2 L(x)=\frac{1}{2}(y-\hat{y})^2 L(x)=21(y−y^)2。
- 损失函数对当前模型的负梯度为: − ∂ L ∂ y ^ = y − y ^ -\frac{\partial{L}}{\partial{\hat{y}}}=y-\hat{y} −∂y^∂L=y−y^。
二、最小绝对误差损失函数
- 损失函数的形式为: L ( x ) = 1 2 ∣ y − y ^ ∣ L(x)=\frac{1}{2}|y-\hat{y}| L(x)=21∣y−y^∣。
- 损失函数对当前模型的负梯度为: − ∂ L ∂ y ^ -\frac{\partial{L}}{\partial{\hat{y}}} −∂y^∂L。
三、huber损失函数
前面两者的组合,能够减少异常值的影响。
四、分位数损失函数。
XGBoost
介绍
XGBoost是陈天奇等人开发的高度优化的GBDT算法。
前提
推导
TODO
优点
优点包括:
- XGBoost中的基学习器既可以使用CART回归树,也可以使用线性学习器
- 加入了正则化项,包括叶子节点个数和叶子节点的得分值,防止过拟合
- 不仅使用了一阶导数,还使用了二阶导数,损失更精确,而且还可以自定义损失函数
- 在选择分裂特征时,使用了并行优化,而传统的GBDT会枚举每个特征
- 考虑了训练数据存在稀疏值和缺失值的情况,可以为缺失值或特定的值指定分支的默认方向,提升了算法的效率
- 支持数据抽样和列抽样,不仅能降低过拟合,还能减少计算量
参数
XGBoost的参数可以分为三类:普通参数,基学习器参数和学习目标参数。
- 普通参数,控制总体的功能。
- booster [default=gbtree],基学习器的种类
- 基学习器参数,控制单个学习器的属性。
- eta/learning_rate [default=0.3],学习率,一般为0.01-0.5之间
- gamma [default=0],结点分裂所需的最小损失减少阈值,损失小于该阈值则结点不进行分裂
- max_depth [default=6],树的最大深度,一般为3-10之间
- min_child_weight [default=1],叶子结点中的样本权重之和最小值。如果某次分裂产生一个叶子结点,其中的样本权重之和小于该值,则不会进行分裂
- max_delta_step [default=0],不太常用,默认值表示没有限制
- subsample [default=1],训练数据的抽样比例,可以防止过拟合
- colsample_bytree [default=1],列(特征)抽样的比例,防止过拟合
- lambda [default=1],L2正则化系数
- alpha [default=0],L1正则化系数
- 学习目标参数,控制训练目标的表现。
- objective [default=reg:squarederror]
- reg:squarederror,回归问题,平方损失
- reg:squaredlogerror,回归问题,平方对数损失
- binary:logistic,二分类逻辑损失,输出概率
- binary:logitraw,二分类逻辑损失,输出逻辑转换之前的分数
- binary:hinge,二分类折页损失,预测为0或1,不能输出概率
- multi:softmax,多分类softmax损失,需要设置num_class参数
- multi:softprob,和前者相同,但是输出一个向量,表示每个样本属于每个类的概率
- eval_metric[default according to objective],验证数据的评估指标。回归默认rmse,分类一般为error,还包括rmse、mae、logloss、error、merror、mlogloss、auc。
- objective [default=reg:squarederror]