常见的集成学习框架有三种:Bagging,Boosting 和 Stacking。三种集成学习框架在基学习器的产生和综合结果的方式上会有些区别,我们先做些简单的介绍。
Bagging 全称叫 Bootstrap aggregating,看到 Bootstrap 我们立刻想到著名的开源前端框架(抖个机灵,是 Bootstrap 抽样方法) ,每个基学习器都会对训练集进行有放回抽样得到子训练集,比较著名的采样法为 0.632 自助法。每个基学习器基于不同子训练集进行训练,并综合所有基学习器的预测值得到最终的预测结果。Bagging 常用的综合方法是投票法,票数最多的类别为预测类别。
Boosting 训练过程为阶梯状,基模型的训练是有顺序的,每个基模型都会在前一个基模型学习的基础上进行学习,最终综合所有基模型的预测值产生最终的预测结果,用的比较多的综合方式为加权法。
Stacking 是先用全部数据训练好基模型,然后每个基模型都对每个训练样本进行的预测,其预测值将作为训练样本的特征值,最终会得到新的训练样本,然后基于新的训练样本进行训练得到模型,然后得到最终预测结果。
那么,为什么集成学习会好于单个学习器呢?原因可能有三:
上节介绍了集成学习的基本概念,这节我们主要介绍下如何从偏差和方差的角度来理解集成学习。
偏差(Bias)描述的是预测值和真实值之差;方差(Variance)描述的是预测值作为随机变量的离散程度。放一场很经典的图:
模型的偏差与方差
我们常说集成学习中的基模型是弱模型,通常来说弱模型是偏差高(在训练集上准确度低)方差小(防止过拟合能力强)的模型,但并不是所有集成学习框架中的基模型都是弱模型。Bagging 和 Stacking 中的基模型为强模型(偏差低,方差高),而Boosting 中的基模型为弱模型(偏差高,方差低)。
在 Bagging 和 Boosting 框架中,通过计算基模型的期望和方差我们可以得到模型整体的期望和方差。为了简化模型,我们假设基模型的期望为 μ \mu μ ,方差 σ 2 \sigma^{2} σ2 ,模型的权重为 r r r,两两模型间的相关系数 ρ \rho ρ相等。由于 Bagging 和 Boosting 的基模型都是线性组成的,那么有: E ( F ) = E ( ∑ i m r i f i ) = ∑ i m r i E ( f i ) \begin{aligned} E(F) &=E\left(\sum_{i}^{m} r_{i} f_{i}\right) \\ &=\sum_{i}^{m} r_{i} E\left(f_{i}\right) \end{aligned} E(F)=E(i∑mrifi)=i∑mriE(fi)模型总体方差(公式推导参考协方差的性质,协方差与方差的关系):
Var ( F ) = Var ( ∑ i m r i f i ) = ∑ i m Var ( r i f i ) + ∑ i ≠ j m Cov ( r i f i , r j f j ) = ∑ i m r i 2 Var ( f i ) + ∑ i ≠ j m ρ r i r j Var ( f i ) Var ( f j ) = m r 2 σ 2 + m ( m − 1 ) ρ r 2 σ 2 = m r 2 σ 2 ( 1 − ρ ) + m 2 r 2 σ 2 ρ \begin{aligned} \operatorname{Var}(F) &=\operatorname{Var}\left(\sum_{i}^{m} r_{i} f_{i}\right) \\ &=\sum_{i}^{m} \operatorname{Var}\left(r_{i} f_{i}\right)+\sum_{i \neq j}^{m} \operatorname{Cov}\left(r_{i} f_{i}, r_{j} f_{j}\right) \\ &=\sum_{i}^{m} r_{i}{ }^{2} \operatorname{Var}\left(f_{i}\right)+\sum_{i \neq j}^{m} \rho r_{i} r_{j} \sqrt{\operatorname{Var}\left(f_{i}\right)} \sqrt{\operatorname{Var}\left(f_{j}\right)} \\ &=m r^{2} \sigma^{2}+m(m-1) \rho r^{2} \sigma^{2} \\ &=m r^{2} \sigma^{2}(1-\rho)+m^{2} r^{2} \sigma^{2} \rho \end{aligned} Var(F)=Var(i∑mrifi)=i∑mVar(rifi)+i=j∑mCov(rifi,rjfj)=i∑mri2Var(fi)+i=j∑mρrirjVar(fi)Var(fj)=mr2σ2+m(m−1)ρr2σ2=mr2σ2(1−ρ)+m2r2σ2ρ模型的准确度可由偏差和方差共同决定: Error = bias 2 + v a r + ξ \text { Error }=\text { bias }^{2}+v a r+\xi Error = bias 2+var+ξ
对于 Bagging 来说,每个基模型的权重等于 1/m 且期望近似相等,故我们可以得到: E ( F ) = ∑ i m r i E ( f i ) = m 1 m μ = μ Var ( F ) = m r 2 σ 2 ( 1 − ρ ) + m 2 r 2 σ 2 ρ = m 1 m 2 σ 2 ( 1 − ρ ) + m 2 1 m 2 σ 2 ρ = σ 2 ( 1 − ρ ) m + σ 2 ρ \begin{aligned} E(F) &=\sum_{i}^{m} r_{i} E\left(f_{i}\right) \\ &=m \frac{1}{m} \mu \\ &=\mu \\ \operatorname{Var}(F) &=m r^{2} \sigma^{2}(1-\rho)+m^{2} r^{2} \sigma^{2} \rho \\ &=m \frac{1}{m^{2}} \sigma^{2}(1-\rho)+m^{2} \frac{1}{m^{2}} \sigma^{2} \rho \\ &=\frac{\sigma^{2}(1-\rho)}{m}+\sigma^{2} \rho \end{aligned} E(F)Var(F)=i∑mriE(fi)=mm1μ=μ=mr2σ2(1−ρ)+m2r2σ2ρ=mm21σ2(1−ρ)+m2m21σ2ρ=mσ2(1−ρ)+σ2ρ通过上式我们可以看到:
在此我们知道了为什么 Bagging 中的基模型一定要为强模型,如果 Bagging 使用弱模型则会导致整体模型的偏差提高,而准确度降低。
Random Forest 是经典的基于 Bagging 框架的模型,并在此基础上通过引入特征采样和样本采样来降低基模型间的相关性,在公式中显著降低方差公式中的第二项,略微升高第一项,从而使得整体降低模型整体方差。
对于 Boosting 来说,由于基模型共用同一套训练集,所以基模型间具有强相关性,故模型间的相关系数近似等于 1,针对 Boosting 化简公式为: E ( F ) = ∑ i m r i E ( f i ) Var ( F ) = m r 2 σ 2 ( 1 − ρ ) + m 2 r 2 σ 2 ρ = m 1 m 2 σ 2 ( 1 − 1 ) + m 2 1 m 2 ρ 2 1 = σ 2 \begin{aligned} E(F) &=\sum_{i}^{m} r_{i} E\left(f_{i}\right) \\ \operatorname{Var}(F) &=m r^{2} \sigma^{2}(1-\rho)+m^{2} r^{2} \sigma^{2} \rho \\ &=m \frac{1}{m^{2}} \sigma^{2}(1-1)+m^{2} \frac{1}{m^{2}} \rho^{2} 1 \\ &=\sigma^{2} \end{aligned} E(F)Var(F)=i∑mriE(fi)=mr2σ2(1−ρ)+m2r2σ2ρ=mm21σ2(1−1)+m2m21ρ21=σ2通过观察整体方差的表达式我们容易发现:
基于 Boosting 框架的 Gradient Boosting Decision Tree 模型中基模型也为树模型,同 Random Forrest,我们也可以对特征进行随机抽样来使基模型间的相关性降低,从而达到减少方差的效果。
️那么这里有一个小小的疑问,Bagging 和 Boosting 到底用的是什么模型呢?
Random Forest(随机森林),用随机的方式建立一个森林。RF 算法由很多决策树组成,每一棵决策树之间没有关联。建立完森林后,当有新样本进入时,每棵决策树都会分别进行判断,然后基于投票法给出分类结果。
Random Forest(随机森林)是 Bagging 的扩展变体,它在以决策树为基学习器构建 Bagging 集成的基础上,进一步在决策树的训练过程中引入了随机特征选择,因此可以概括 RF 包括四个部分:
随机选择样本和 Bagging 相同,采用的是 Bootstrap 自助采样法;随机选择特征是指在每个节点在分裂过程中都是随机选择特征的(区别与每棵树随机选择一批特征)。
这种随机性导致随机森林的偏差会有稍微的增加(相比于单棵不随机树),但是由于随机森林的“平均”特性,会使得它的方差减小,而且方差的减小补偿了偏差的增大,因此总体而言是更好的模型。
随机采样由于引入了两种采样方法保证了随机性,所以每棵树都是最大可能的进行生长就算不剪枝也不会出现过拟合。
优点:
AdaBoost(Adaptive Boosting,自适应增强),其自适应在于:前一个基本分类器分错的样本会得到加强,加权后的全体样本再次被用来训练下一个基本分类器。同时,在每一轮中加入一个新的弱分类器,直到达到某个预定的足够小的错误率或达到预先指定的最大迭代次数。
Adaboost 迭代算法有三步:
Adaboost 模型是加法模型,学习算法为前向分步学习算法,损失函数为指数函数的分类问题。
加法模型:最终的强分类器是由若干个弱分类器加权平均得到的。
前向分布学习算法:算法是通过一轮轮的弱学习器学习,利用前一个弱学习器的结果来更新后一个弱学习器的训练集权重。第 k 轮的强学习器为: F k ( x ) = ∑ i = 1 k α i f i ( x ) = F k − 1 ( x ) + α k f k ( x ) F_{k}(x)=\sum_{i=1}^{k} \alpha_{i} f_{i}(x)=F_{k-1}(x)+\alpha_{k} f_{k}(x) Fk(x)=i=1∑kαifi(x)=Fk−1(x)+αkfk(x)定义损失函数为 n 个样本的指数损失函数: L ( y , F ) = ∑ i = 1 n exp ( − y i F k ( x i ) ) L(y, F)=\sum_{i=1}^{n} \exp \left(-y_{i} F_{k}\left(x_{i}\right)\right) L(y,F)=i=1∑nexp(−yiFk(xi))利用前向分布学习算法的关系可以得到: L ( y , F ) = ∑ i = 1 m exp [ ( − y i ) ( F k − 1 ( x i ) + α k f k ( x i ) ) ] = ∑ i = 1 m exp [ − y i F k − 1 ( x i ) − y i α k f k ( x i ) ] = ∑ i = 1 m exp [ − y i F k − 1 ( x i ) ] exp [ − y i α k f k ( x i ) ] \begin{aligned} L(y, F) &=\sum_{i=1}^{m} \exp \left[\left(-y_{i}\right)\left(F_{k-1}\left(x_{i}\right)+\alpha_{k} f_{k}\left(x_{i}\right)\right)\right] \\ &=\sum_{i=1}^{m} \exp \left[-y_{i} F_{k-1}\left(x_{i}\right)-y_{i} \alpha_{k} f_{k}\left(x_{i}\right)\right] \\ &=\sum_{i=1}^{m} \exp \left[-y_{i} F_{k-1}\left(x_{i}\right)\right] \exp \left[-y_{i} \alpha_{k} f_{k}\left(x_{i}\right)\right] \end{aligned} L(y,F)=i=1∑mexp[(−yi)(Fk−1(xi)+αkfk(xi))]=i=1∑mexp[−yiFk−1(xi)−yiαkfk(xi)]=i=1∑mexp[−yiFk−1(xi)]exp[−yiαkfk(xi)]因为 F k − 1 ( x ) F_{k-1}(x) Fk−1(x)已知,所以令 w k , i = exp ( − y i F k − 1 ( x i ) ) w_{k, i}=\exp \left(-y_{i} F_{k-1}\left(x_{i}\right)\right) wk,i=exp(−yiFk−1(xi)),随着每一轮迭代而将这个式子带入损失函数,损失函数转化为: L ( y , F ( x ) ) = ∑ i = 1 m w k , i exp [ − y i α k f k ( x i ) ] L(y, F(x))=\sum_{i=1}^{m} w_{k, i} \exp \left[-y_{i} \alpha_{k} f_{k}\left(x_{i}\right)\right] L(y,F(x))=i=1∑mwk,iexp[−yiαkfk(xi)]将 f k ( x ) f_{k}(x) fk(x)带入损失函数,并对 α \alpha α求导,使其等于 0,则就得到了: α k = 1 2 log 1 − e k e k \alpha_{k}=\frac{1}{2} \log \frac{1-e_{k}}{e_{k}} αk=21logek1−ek其中, e k e_k ek即为我们前面的分类误差率。 e k = ∑ i = 1 m w k i ′ I ( y i ≠ f k ( x i ) ) ∑ i = 1 m w k i ′ = ∑ i = 1 m w k i I ( y i ≠ f k ( x i ) ) e_{k}=\frac{\sum_{i=1}^{m} w_{k i}^{\prime} I\left(y_{i} \neq f_{k}\left(x_{i}\right)\right)}{\sum_{i=1}^{m} w_{k i}^{\prime}}=\sum_{i=1}^{m} w_{k i} I\left(y_{i} \neq f_{k}\left(x_{i}\right)\right) ek=∑i=1mwki′∑i=1mwki′I(yi=fk(xi))=i=1∑mwkiI(yi=fk(xi))最后看样本权重的更新。利用 F k ( x ) = F k − 1 ( x ) + α k f k ( x ) F_k(x)=F_{k-1}(x)+\alpha_kf_k(x) Fk(x)=Fk−1(x)+αkfk(x) 和 w k + 1 , i = w k , i e x p [ − y i α k f k ( x , i ) ] w_{k+1,i}=w_{k,i}exp[-y_i\alpha_kf_k(x,i)] wk+1,i=wk,iexp[−yiαkfk(x,i)],即可得到: w k + 1 , i = w k , i e x p [ − y i α k f k ( x i ) ] w_{k+1,i}=w_{k,i}exp[-y_i\alpha_kf_k(x_i)] wk+1,i=wk,iexp[−yiαkfk(xi)]
这样就得到了样本权重更新公式。
为了防止 Adaboost 过拟合,我们通常也会加入正则化项,这个正则化项我们通常称为步长(learning rate)。对于前面的弱学习器的迭代 F k ( x ) = F k − 1 ( x ) + α k f k ( x ) F_{k}(x)=F_{k-1}(x)+\alpha_{k} f_{k}(x) Fk(x)=Fk−1(x)+αkfk(x)加上正则化项 μ \mu μ我们有: F k ( x ) = F k − 1 ( x ) + μ α k f k ( x ) F_{k}(x)=F_{k-1}(x)+\mu \alpha_{k} f_{k}(x) Fk(x)=Fk−1(x)+μαkfk(x) μ \mu μ 的取值范围为 0 < μ < 1 0<\mu<1 0<μ<1。对于同样的训练集学习效果,较小的 μ \mu μ意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。
优点:
缺点:
GBDT(Gradient Boosting Decision Tree)是一种迭代的决策树算法,该算法由多棵决策树组成,从名字中我们可以看出来它是属于 Boosting 策略。GBDT 是被公认的泛化能力较强的算法。
GBDT 由三个概念组成:Regression Decision Tree(即 DT)、Gradient Boosting(即 GB),和 Shrinkage(一个重要演变)
如果认为 GBDT 由很多分类树那就大错特错了(虽然调整后也可以分类)。对于分类树而言,其值加减无意义(如性别),而对于回归树而言,其值加减才是有意义的(如说年龄)。GBDT 的核心在于累加所有树的结果作为最终结果,所以 GBDT 中的树都是回归树,不是分类树,这一点相当重要。
回归树在分枝时会穷举每一个特征的每个阈值以找到最好的分割点,衡量标准是最小化均方误差。
上面说到 GBDT 的核心在于累加所有树的结果作为最终结果,GBDT 的每一棵树都是以之前树得到的残差来更新目标值,这样每一棵树的值加起来即为 GBDT 的预测值。
模型的预测值可以表示为: F k ( x ) = ∑ i = 1 k f i ( x ) F_{k}(x)=\sum_{i=1}^{k} f_{i}(x) Fk(x)=i=1∑kfi(x) f i ( x ) f_i(x) fi(x) 为基模型与其权重的乘积,模型的训练目标是使预测值 F k ( x ) F_k(x) Fk(x)逼近真实值 y,也就是说要让每个基模型的预测值逼近各自要预测的部分真实值。由于要同时考虑所有基模型,导致了整体模型的训练变成了一个非常复杂的问题。所以研究者们想到了一个贪心的解决手段:每次只训练一个基模型。那么,现在改写整体模型为迭代式: F k ( x ) = F k − 1 ( x ) + f k ( x ) F_{k}(x)=F_{k-1}(x)+f_{k}(x) Fk(x)=Fk−1(x)+fk(x)这样一来,每一轮迭代中,只要集中解决一个基模型的训练问题:使 F k ( x ) F_k(x) Fk(x)逼近真实值 y y y 。
举个例子:比如说 A 用户年龄 20 岁,第一棵树预测 12 岁,那么残差就是 8,第二棵树用 8 来学习,假设其预测为 5,那么其残差即为 3,如此继续学习即可。
那么 Gradient 从何体现?其实很简单,其残差其实是最小均方损失函数关于预测值的反向梯度(划重点): − ∂ ( 1 2 ( y − F k ( x ) ) 2 ) ∂ F k ( x ) = y − F k ( x ) -\frac{\partial\left(\frac{1}{2}\left(y-F_{k}(x)\right)^{2}\right)}{\partial F_{k}(x)}=y-F_{k}(x) −∂Fk(x)∂(21(y−Fk(x))2)=y−Fk(x)
也就是说,预测值和实际值的残差与损失函数的负梯度相同。
但要注意,基于残差 GBDT 容易对异常值敏感,举例:
很明显后续的模型会对第 4 个值关注过多,这不是一种好的现象,所以一般回归类的损失函数会用绝对损失或者 Huber 损失函数来代替平方损失函数。
GBDT 的 Boosting 不同于 Adaboost 的 Boosting,GBDT 的每一步残差计算其实变相地增大了被分错样本的权重,而对与分对样本的权重趋于 0,这样后面的树就能专注于那些被分错的样本。
Shrinkage 的思想认为,每走一小步逐渐逼近结果的效果要比每次迈一大步很快逼近结果的方式更容易避免过拟合。即它并不是完全信任每一棵残差树。 F i ( x ) = F i − 1 ( x ) + μ f i ( x ) ( 0 < μ ≤ 1 ) F_{i}(x)=F_{i-1}(x)+\mu f_{i}(x) \quad(0<\mu \leq 1) Fi(x)=Fi−1(x)+μfi(x)(0<μ≤1)
Shrinkage 不直接用残差修复误差,而是只修复一点点,把大步切成小步。本质上 Shrinkage 为每棵树设置了一个 weight,累加时要乘以这个 weight,当 weight 降低时,基模型数会配合增大。
更多请见:https://zhuanlan.zhihu.com/p/86263786