在机器学习的有监督学习算法中,我们的目标是学习出一个稳定的且在各个方面表现都较好的模型,但实际情况往往不这么理想,有时我们只能得到多个有偏好的模型(弱监督模型,在某些方面表现的比较好)。集成学习就是组合这里的多个弱监督模型以期得到一个更好更全面的强监督模型,集成学习潜在的思想是即便某一个弱分类器得到了错误的预测,其他的弱分类器也可以将错误纠正回来。
集成方法是将几种机器学习技术组合成一个预测模型的元算法,以达到减小方差(bagging)、偏差(boosting)或改进预测(stacking)的效果。
集成学习在各个规模的数据集上都有很好的策略。
数据集大:划分成多个小数据集,学习多个模型进行组合
数据集小:利用Bootstrap方法进行抽样,得到多个数据集,分别训练多个模型再进行组合
集合方法可分为两类:
- 序列集成方法,其中参与训练的基础学习器按照顺序生成(例如 AdaBoost)。序列方法的原理是利用基础学习器之间的依赖关系。通过对之前训练中错误标记的样本赋值较高的权重,可以提高整体的预测效果。
- 并行集成方法,其中参与训练的基础学习器并行生成(例如 Random Forest)。并行方法的原理是利用基础学习器之间的独立性,通过平均可以显著降低错误
1.bagging
bagging即套袋法,先说一下bootstrap,bootstrap也称为自助法,它是一种有放回的抽样方法,目的为了得到统计量的分布以及置信区间,其算法过程如下:
A)从原始样本集中抽取训练集。每轮从原始样本集中使用Bootstraping的方法抽取n个训练样本(在训练集中,有些样本可能被多次抽取到,而有些样本可能一次都没有被抽中)。共进行k轮抽取,得到k个训练集。(k个训练集之间是相互独立的)
B)每次使用一个训练集得到一个模型,k个训练集共得到k个模型。(注:这里并没有具体的分类算法或回归方法,我们可以根据具体问题采用不同的分类或回归方法,如决策树、感知器等)
C)对分类问题:将上步得到的k个模型采用投票的方式得到分类结果;对回归问题,计算上述模型的均值作为最后的结果。(所有模型的重要性相同)
2.boosting
主要思想是将弱分类器组装成一个强分类器。在PAC(probably approximately correct,概率近似正确)学习框架下,则一定可以将弱分类器组装成一个强分类器。
关于Boosting的两个核心问题:
1)在每一轮如何改变训练数据的权值或概率分布?
通过提高那些在前一轮被弱分类器分错样例的权值,减小前一轮分对样例的权值,来使得分类器对误分的数据有较好的效果。
2)通过什么方式来组合弱分类器?
通过加法模型将弱分类器进行线性组合。
3.stacking
Stacking 是先用全部数据训练好基模型,然后每个基模型都对每个训练样本进行的预测,其预测值将作为训练样本的特征值,最终会得到新的训练样本,然后基于新的训练样本进行训练得到模型,然后得到最终预测结果。
4.实例
4.1Random Forest(bagging)
随机森林中,集成中的每棵树都是由从训练集中抽取的样本(即 bootstrap 样本)构建的。另外,与使用所有特征不同,这里随机选择特征子集,从而进一步达到对树的随机化目的。
根据下列算法而建造每棵树 :
- 用N来表示训练样本的个数,M表示特征数目。
- 从N个训练样本中以有放回抽样的方式,取样N次,形成一个训练集(即bootstrap取样),并用未抽到的用例(样本)作预测,评估其误差。
- 对于每一个节点,随机选择m(m<<M)个特征,决策树上每个节点的决定都是基于这些特征确定的。根据这m个特征,从这m个特征中选择最优的特征分裂。
- 每棵树都会完整成长而不会剪枝,这有可能在建完一棵正常树状分类器后会被采用)。
4.2Adaboost
Adaboost 算法采用调整样本权重的方式来对样本分布进行调整,即提高前一轮个体学习器错误分类的样本的权重,而降低那些正确分类的样本的权重,这样就能使得错误分类的样本可以受到更多的关注,从而在下一轮中可以正确分类,使得分类问题被一系列的弱分类器“分而治之”。对于组合方式,AdaBoost采用加权多数表决的方法,具体地,加大分类误差率小的若分类器的权值,减小分类误差率大的若分类器的权值,从而调整他们在表决中的作用。
其算法流程如下:
有如下二分类数据集(N为样本数):
T
=
{
(
x
1
,
y
1
)
,
(
x
1
,
y
1
)
,
…
,
(
x
N
,
y
N
)
}
y
i
ϵ
Y
=
{
−
1
,
1
}
T=\left\{\left(x_{1}, y_{1}\right),\left(x_{1}, y_{1}\right), \ldots,\left(x_{N}, y_{N}\right)\right\} \quad y_{i} \epsilon Y=\{-1,1\}
T={(x1,y1),(x1,y1),…,(xN,yN)}yiϵY={−1,1}
输入:数据集 T;弱学习算法
输出:最终分类器G(x)
(1) 初始化训练数据的权值分布
D
1
=
(
w
11
,
w
12
,
…
,
w
1
N
)
,
w
1
i
=
1
N
,
i
=
1
,
2
,
…
,
N
D_{1}=\left(w_{11}, w_{12}, \ldots, w_{1 N}\right), \quad w_{1 i}=\frac{1}{N}, \quad i=1,2, \ldots, N
D1=(w11,w12,…,w1N),w1i=N1,i=1,2,…,N
(2) 对
m
=
1
,
2
,
.
.
.
,
M
m=1,2,...,M
m=1,2,...,M (弱分类器的个数,对每个弱分类器做如下):
(a)使用具有权值分布
D
m
D_m
Dm训练数据集学习,得到基本分类器;
G
m
(
x
)
:
X
→
{
−
1
,
1
}
G_{m}(x): X \rightarrow\{-1,1\}
Gm(x):X→{−1,1} (b) 计算
G
m
(
x
)
G_m(x)
Gm(x)在训练数据集上的分类误差率
e
m
e_{m}
em (错误分类的样本的权重之和);
e
m
=
∑
i
=
1
N
P
(
G
m
(
x
i
)
≠
y
i
)
=
∑
i
=
1
N
w
m
i
I
(
G
m
(
x
i
)
≠
y
i
)
e_{m}=\sum_{i=1}^{N} P\left(G_{m}\left(x_{i}\right) \neq y_{i}\right)=\sum_{i=1}^{N} w_{m i} I\left(G_{m}\left(x_{i}\right) \neq y_{i}\right)
em=i=1∑NP(Gm(xi)=yi)=i=1∑NwmiI(Gm(xi)=yi) (c) 计算
G
m
(
x
)
G_m(x)
Gm(x)的系数 (弱分类器的权重, 反函数,误差率越大,则权重越小,反之越大);
α
m
=
1
2
log
1
−
e
m
e
m
\alpha_{m}=\frac{1}{2} \log \frac{1-e_{m}}{e_{m}}
αm=21logem1−em (d) 更新训练数据集的权值分布;
D
m
+
1
=
(
w
m
+
1
,
1
,
w
m
+
1
,
2
,
…
,
w
m
+
1
,
N
)
w
m
+
1
,
i
=
w
m
i
Z
m
exp
(
−
α
m
y
i
G
m
(
x
i
)
)
,
i
=
1
,
2
,
…
,
N
\begin{array}{l} D_{m+1}=\left(w_{m+1,1}, w_{m+1,2}, \ldots, w_{m+1, N}\right) \\ w_{m+1, i}=\frac{w_{m i}}{Z_{m}} \exp \left(-\alpha_{m} y_{i} G_{m}\left(x_{i}\right)\right), \quad i=1,2, \ldots, N \end{array}
Dm+1=(wm+1,1,wm+1,2,…,wm+1,N)wm+1,i=Zmwmiexp(−αmyiGm(xi)),i=1,2,…,N
其中,
Z
m
Z_m
Zm为规范化因子
Z
m
=
∑
i
=
1
N
w
m
i
exp
(
−
α
m
y
i
G
m
(
x
i
)
)
Z_{m}=\sum_{i=1}^{N} w_{m i} \exp \left(-\alpha_{m} y_{i} G_{m}\left(x_{i}\right)\right)
Zm=i=1∑Nwmiexp(−αmyiGm(xi))
它使得
D
m
+
1
D_{m+1}
Dm+1成为一个概率分布
(3) 构建基本分类器的线性组合
f
(
x
)
=
∑
m
=
1
M
α
m
G
m
(
x
)
f(x)=\sum_{m=1}^{M} \alpha_{m} G_{m}(x)
f(x)=m=1∑MαmGm(x)
得到最终的分类器
G
(
x
)
=
sign
(
f
(
x
)
)
=
sign
(
∑
m
=
1
M
α
m
G
m
(
x
)
)
G(x)=\operatorname{sign}(f(x))=\operatorname{sign}\left(\sum_{m=1}^{M} \alpha_{m} G_{m}(x)\right)
G(x)=sign(f(x))=sign(m=1∑MαmGm(x))
注:
∑
i
=
1
N
w
m
i
=
1
w
m
+
1
,
i
=
{
w
m
i
Z
m
e
−
α
m
G
m
(
x
i
)
=
y
i
w
m
i
Z
m
e
α
m
,
G
m
(
x
i
)
≠
y
i
\begin{array}{l} \sum_{i=1}^{N} w_{m i}=1 \\ w_{m+1, i}=\left\{\begin{array}{ll} \frac{w_{m i}}{Z_{m}} e^{-\alpha_{m}} & G_{m}\left(x_{i}\right)=y_{i} \\ \frac{w_{m i}}{Z_{m}} e^{\alpha_{m}} & , G_{m}\left(x_{i}\right) \neq y_{i} \end{array}\right. \end{array}
∑i=1Nwmi=1wm+1,i={Zmwmie−αmZmwmieαmGm(xi)=yi,Gm(xi)=yi
4.3 GBDT
GBDT(Gradient Boosting Decision Tree)是一种迭代的决策树算法,该算法由多棵决策树组成,GBDT中的树是回归树(不是分类树),GBDT用来做回归预测。
GBDT主要由两个概念组成:Regression Decistion Tree(即DT,回归树),Gradient Boosting(梯度迭代),搞定这两个概念就能明白GBDT是如何工作的。
4.3.1 Regression Decistion Tree回归树
以一个回归问题为例,Regression Tree的目的也是经验风险或者结构风险最小化(经验风险:训练样本集的平均损失;结构风险:加入正则化的训练样本集的平均损失)。参考:回归树
切分变量:在每次划分时,选择 feature
切分点:选择将该feature space 一分为二的 split
- 给定一个数据集 D = ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x i , y i ) , . . . , ( x n , y n ) D={(x1,y1),(x2,y2),...,(xi,yi),...,(xn,yn)} D=(x1,y1),(x2,y2),...,(xi,yi),...,(xn,yn),其中 x i xi xi是一个 m m m维的向量,即 x i xi xi 含有 m m m 个 f e a t u r e s features features。
- 回归问题的目标就是构造一个函数 f ( x ) f(x) f(x) 能够拟合数据集 D D D 中的元素,使得 m s e mse mse最小,即:
min 1 n ∑ i = 1 n ( f ( x i ) − y i ) 2 \min \frac{1}{n} \sum_{i=1}^{n}\left(f\left(\boldsymbol{x}_{i}\right)-y_{i}\right)^{2} minn1i=1∑n(f(xi)−yi)2
- 假设构造的回归树有
M
M
M片叶子,即将输入空间
X
X
X划分成了
M
M
M个单元
R
1
,
R
2
,
.
.
.
,
R
M
R_1,R_2,...,R_M
R1,R2,...,RM,同时意味着最多会有
M
M
M个不同的预测值。
min 1 n ∑ m = 1 M ∑ x i ∈ R m ( c m − y i ) 2 \min \frac{1}{n} \sum_{m=1}^{M} \sum_{\boldsymbol{x}_{i} \in R_{m}}\left(c_{m}-y_{i}\right)^{2} minn1m=1∑Mxi∈Rm∑(cm−yi)2
其中, c m c_m cm 表示第 m m m 片叶子的预测值(叶子中含有的训练集元素的均值)。(遍历每一个叶子,遍历叶子内的样本,计算均方误差)
c m = ave ( y i ∣ x i ∈ lea f m ) c_{m}=\operatorname{ave}\left(y_{i} \mid \boldsymbol{x}_{i} \in \operatorname{lea} f_{m}\right) cm=ave(yi∣xi∈leafm) - 遍历所有的切分变量和切分点,然后选出 叶子节点
m
s
e
mse
mse 之和最小的那种情况作为划分。选择第
j
j
j 个
f
e
a
t
u
r
e
feature
feature
x
j
x^j
xj 和它取的值
s
s
s,作为切分变量和切分点,则切分变量和切分点将父节点的输入空间一分为二:
R 1 { j , s } = { x ∣ x ( j ) ≤ s } R 2 { j , s } = { x ∣ x ( j ) > s } \begin{array}{l} R_{1}\{j, s\}=\left\{\boldsymbol{x} \mid \boldsymbol{x}^{(j)} \leq s\right\} \\ R_{2}\{j, s\}=\left\{\boldsymbol{x} \mid \boldsymbol{x}^{(j)}>s\right\} \end{array} R1{j,s}={x∣x(j)≤s}R2{j,s}={x∣x(j)>s} - 选择切分变量
j
j
j 和 切分点
s
s
s 的公式如下:
min
j
,
s
[
min
c
1
∑
x
i
∈
R
1
{
j
,
s
}
(
y
i
−
c
1
)
2
+
min
c
2
∑
x
i
∈
R
2
{
j
,
s
}
(
y
i
−
c
2
)
2
]
\min _{j, s}\left[\min _{c 1} \sum_{x_{i} \in R_{1}\{j, s\}}\left(y_{i}-c_{1}\right)^{2}+\min _{c_{2}} \sum_{x_{i} \in R_{2}\{j, s\}}\left(y_{i}-c_{2}\right)^{2}\right]
j,smin⎣⎡c1minxi∈R1{j,s}∑(yi−c1)2+c2minxi∈R2{j,s}∑(yi−c2)2⎦⎤
分枝时穷举每一个feature的每个阈值找最好的分割点,但衡量最好的标准不再是最大熵,而是最小化平方误差
4.3.2 Gradient Boosting梯度迭代
Boosting,迭代,即通过迭代多棵树来共同决策。这怎么实现呢?难道是每棵树独立训练一遍,比如A这个人,第一棵树认为是10岁,第二棵树认为是0岁,第三棵树认为是20岁,我们就取平均值10岁做最终结论?当然不是!且不说这是投票方法并不是GBDT,只要训练集不变,独立训练三次的三棵树必定完全相同,这样做完全没有意义。之前说过,GBDT是把所有树的结论累加起来做最终结论的,所以可以想到每棵树的结论并不是年龄本身,而是年龄的一个累加量。GBDT的核心就在于,每一棵树学的是之前所有树结论和的残差,这个残差就是一个加预测值后能得真实值的累加量。比如A的真实年龄是18岁,但第一棵树的预测年龄是12岁,差了6岁,即残差为6岁。那么在第二棵树里我们把A的年龄设为6岁去学习,如果第二棵树真的能把A分到6岁的叶子节点,那累加两棵树的结论就是A的真实年龄;如果第二棵树的结论是5岁,则A仍然存在1岁的残差,第三棵树里A的年龄就变成1岁,继续学。这就是Gradient Boosting在GBDT中的意义。
4.3.3 GBDT
还是年龄预测,简单起见训练集只有4个人,A,B,C,D,他们的年龄分别是14,16,24,26。其中A、B分别是高一和高三学生;C,D分别是应届毕业生和工作两年的员工。如果是用一棵传统的回归决策树来训练,会得到如下图1所示结果:
现在我们使用GBDT来做这件事,由于数据太少,我们限定叶子节点做多有两个,即每棵树都只有一个分枝,并且限定只学两棵树。我们会得到如下图2所示结果:
在第一棵树分枝和图1一样,由于A,B年龄较为相近,C,D年龄较为相近,他们被分为两拨,每拨用平均年龄作为预测值。此时计算残差(残差的意思就是: A的预测值 + A的残差 = A的实际值),所以A的残差就是16-15=1(注意,A的预测值是指前面所有树累加的和,这里前面只有一棵树所以直接是15,如果还有树则需要都累加起来作为A的预测值)。进而得到A,B,C,D的残差分别为-1,1,-1,1。然后我们拿残差替代A,B,C,D的原值,到第二棵树去学习,如果我们的预测值和它们的残差相等,则只需把第二棵树的结论累加到第一棵树上就能得到真实年龄了。这里的数据显然是我可以做的,第二棵树只有两个值1和-1,直接分成两个节点。此时所有人的残差都是0,即每个人都得到了真实的预测值。
A: 14岁高一学生,购物较少,经常问学长问题;预测年龄A = 15 – 1 = 14
B: 16岁高三学生;购物较少,经常被学弟问问题;预测年龄B = 15 + 1 = 16
C: 24岁应届毕业生;购物较多,经常问师兄问题;预测年龄C = 25 – 1 = 24
D: 26岁工作两年员工;购物较多,经常被师弟问问题;预测年龄D = 25 + 1 = 26
4.4 XGBoost
XGBoost在本质上时GBDT,在算法和工程上进行改进,使得速度和效率发挥到极致,也叫X(Extreme)GBoost。
4.5 LightGBM
参考文献