集成学习作为当今性能最好的多模型分类器,我们必须要了解它一下。
这里我们从最简单的集成学习Bagging开始讲起,一直讲到GBDT为止。
1.集成学习
集成学习是多模型学习的一种,它是集成多个弱分类器来进行决策。就是“三个臭皮匠赛过诸葛亮”,但是一般来讲是赛不了的,为什么呢?首先如果三个臭皮匠是三胞胎,那么三个臭皮匠和一个臭皮匠是无异的,另外,如何把这三个决策统一起来是另外一个问题。因此我们从这两方面来入手讲解集成学习。
2.Bagging
bagging的想法非常简单,假设我们有T个分类器,每个分类器需要m个训练样本。我们只需要使用自助采样法(有放回采样)获取到这m个样本即可。这样我们就有了T个包含了m个样本的训练集,来训练T个分类器。最终对同一样本进行简单的投票决策即可。
具体算法描述如下图:
输入:训练集
Di={(x1,y1),(x2,y2),..,(xm,ym)}
D
i
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
.
.
,
(
x
m
,
y
m
)
}
基础分类器个数T
过程
1:for t=1,2,3…,T do
2:
ht=训练分类器(Di)
h
t
=
训
练
分
类
器
(
D
i
)
3:
这就是最简单的bagging,它就是兼听则明的一个典型代表,但是它只能去减少方差,但是不能够保证最终的结果更加正确,万一所有的大臣串通一气,你就算听取了所有大臣的意见,仍然是一个昏君。
3.RandomForest
随机森林是在bagging上的一个改进,在bagging中,我们只去扰动了样本,也就是说,虽然每个T的训练样本是服从同分布的,但是样本的个体是不同的,也就是说,我们假设每个T都是一个游客在看一座山,虽然每个人都是独立的看,但是都是在同一方向上看的,因此差异性不会特别大。而随机森林则加入了另一个扰动,那就是训练模型的不同,也就是说每个人都在不同的角度看同一座山,这样描述的会更加准确。
这里我们主要讲解一下结合的策略。常规来讲,主要有这么几种策略:多数表决、平均值、加权表决/平均值。多数表决,就是一人一票,每人都平等对待,然后得票多的结果获胜。平均值则是把所有人的决策取平均,加权的话,就是把每个分类器不平等对待。另外,如果每个分类器性能差异比较大的时候,建议使用多数表决。每个分类器差异较小的时候,建议使用平均值。
另一方面,还有一个Stacking算法,它比较特殊,它会先使用一些初级学习器,然后生成一个新数据集再来进行一次训练。新的数据集主要是添加了初级学习器的预测结果,然后再训练次级学习器,这种方法比较适用于多响应线性回归。
4.Boosting
boosting和bagging的思路完全不同,它是使用同一个训练集,但是每个分类器都是有顺序的,当前分类器依赖于前一个分类器的性能表现。就目前实现而言boosting中最具代表的是AdaBoosting,它主要用于二分类,并且维护一个样本权重表来保证模型的性能。
它的主要思想是,初始化时,所有的样本都具有同权重,当进入第一个分类器分类后,挑选出其中错误的样本,对其权重进行增加,对正确样本权重减少,这样保证下一个分类器对于错误的样本能够更好的修正。具体算法如下:
输入:训练集
Di={(x1,y1),(x2,y2),..,(xm,ym)}
D
i
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
.
.
,
(
x
m
,
y
m
)
}
基础分类器个数T
过程:
D1(x)=1m
D
1
(
x
)
=
1
m
for t=1,2,…,T do
ht=训练分类器(D,Dt)
h
t
=
训
练
分
类
器
(
D
,
D
t
)
ϵt=ht的错误率
ϵ
t
=
h
t
的
错
误
率
ifϵt>0.5thenbreak//这里是说如果错误率大于乱猜了,则不要继续了
i
f
ϵ
t
>
0.5
t
h
e
n
b
r
e
a
k
/
/
这
里
是
说
如
果
错
误
率
大
于
乱
猜
了
,
则
不
要
继
续
了
αt=12ln(1−ϵtϵt)
α
t
=
1
2
l
n
(
1
−
ϵ
t
ϵ
t
)
Dt+1(x)=Dt(x)×exp(−αtf(x)ht(x))Zt
D
t
+
1
(
x
)
=
D
t
(
x
)
×
e
x
p
(
−
α
t
f
(
x
)
h
t
(
x
)
)
Z
t
end for
H(x)=sign(∑Tt=1αtht(x))
H
(
x
)
=
s
i
g
n
(
∑
t
=
1
T
α
t
h
t
(
x
)
)
从上面可以看出,它是一个自适应提升模型,首先一点就是它的第i次的性能会随着第i-1次而不断的调整,最后取得最优值。但是这还不是最后的优化方案,因为还有更优秀的BoostingTree。
5.BoostingTree
提升树主要有两点的提升,第一就是对于Boosting的每一轮迭代,它的目标任务是不同的,每次都是记录残差,而不是真正的标签。也就是说除了第一棵树是正常分类的,后面的树都是不断修正之前的树的预判的,从而达到整体预判效果,具体来讲,它的每个树是CART树,具体的算法如下:
输入:训练数据集T
输出:提升树
fM(x).
f
M
(
x
)
.
(1) 初始化
f0(x)=0
f
0
(
x
)
=
0
(2)对m=1,2,…,M
计算残差:rmi=yi−fm−1(xi),i=1,2,...,N
计
算
残
差
:
r
m
i
=
y
i
−
f
m
−
1
(
x
i
)
,
i
=
1
,
2
,
.
.
.
,
N
使用残差来拟合回归树Tm
使
用
残
差
来
拟
合
回
归
树
T
m
更新提升树fm(x)=fm−1(x)+Tm
更
新
提
升
树
f
m
(
x
)
=
f
m
−
1
(
x
)
+
T
m
(3)得到回归提升树
fM(x)
f
M
(
x
)
那么,什么时候停止呢,使用平方和误差低于某一值时,就认为拟合成功了。但是这还不是最终的结果,最终的为GBDT
6.GBDT
GBDT较上面更新之处在于每次修剪的幅度不同。上面讲的误差使用的是平方损失误差,而GBDT则是使用梯度来解决。算法如下
输入:训练集T,损失函数L
输出:回归树f(x)
(1)初始化
(2)对于m=1,2,…,M
对i=1,2,...,N,计算残差rmi=−[∂L(yi,f(xi))∂f(xi)]f(x)=fm−1(x) 对 i = 1 , 2 , . . . , N , 计 算 残 差 r m i = − [ ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x )
使用rmi拟合一个回归树,得到第n棵树的叶节点区域Rmj 使 用 r m i 拟 合 一 个 回 归 树 , 得 到 第 n 棵 树 的 叶 节 点 区 域 R m j
(3)得到回归树
网上居然没有一个人对这些代码进行解读一下!太难了!
7.总结
今天,我们主要梳理了一遍集成学习的方法,从最基层的Bagging到最顶层的GBDT。