上一篇集成学习—GBDT原理理解中提到,由于GBDT的弱学习器之间存在依赖关系,难以并行训练数据,因此若数据量较大时程序运行太慢。这里可以通过加入了自采样的SGBT来达到部分并行,这是一个能改善GBDT的一种方法。
SGBT全称Stochastic Gradient Boosting Tree,也就是随机梯度提升树,它是在2002年Jerome H. Friedman的《Stochastic Gradient Boosting》这篇论文中提出。
实际上,SGBT只是在GBDT的基础上加了一个随机子采样,不把全部的数据都放进去做boosting,而是只随机选取一部分,这样可以减少计算量,加快模型学习的速度。
原论文的关键原理如下:
Breiman(1996)在他的“bagging”过程中引入了一个概念,将随机性注入到函数估计过程中可以提高它们的性能。AdaBoost的早期实现(Freund和Schapire, 1996)也采用了随机抽样,但这被认为是对确定性权重的近似,因为有的基学习器不支持带权重的样本(这里和西瓜书上说的是一致的),而不是作为算法的基本步骤。Breiman(1999)提出了一个混合套袋提升过程(“适应性套袋 adaptive bagging”)用于最小二乘拟合加性模型。它在每次boosting迭代中用对应的套袋的基学习器来替代之前常规的boosting程序中的基学习器,用袋外残差来替代普通的残差。
受Breiman(1999)启发,对梯度提升算法进行了小小的改动,即将随机性整合到梯度提升算法中。特别地,在每次迭代中,从所有的训练集中随机地(不重复)进行子采样,然后使用这个随机抽取的子样本而不是全部样本用来拟合一个基学习器(第4行),并计算模型对当前迭代的更新(第5行)。
令 { y i , x i } 1 N \{y_i,x_i\}_1^N {yi,xi}1N表示全部训练集样本, { π ( i ) } 1 N \{\pi(i)\}_1^N {π(i)}1N表示整数 { 1 , … , N } \{1,\dots,N\} {1,…,N}的随机重排。则大小为 N ~ < N \tilde{N}<N N~<N的随机子样本表示为 { y π ( i ) , x π ( i ) } 1 N \{y_{\pi(i)},x_{\pi(i)}\}_1^N {yπ(i),xπ(i)}1N。随机梯度提升算法为:
- 初始化 F 0 ( x ) = arg min γ ∑ i = 1 N L ( y i , γ ) F_0(x)=\arg\min_\gamma\sum_{i=1}^NL(y_i,\gamma) F0(x)=argminγ∑i=1NL(yi,γ)
- 对
m
=
1
m=1
m=1到
M
M
M循环:
(1) N N N个数据随机打乱 { π ( i ) } 1 N = r a n d _ p e r m { i } 1 N \{\pi(i)\}_1^N=rand\_perm\{i\}_1^N {π(i)}1N=rand_perm{i}1N
(2)对 i = 1 , 2 , … , N ~ i=1,2,\dots,\tilde{N} i=1,2,…,N~,计算: r ~ m π ( i ) = − [ ∂ L ( y π ( i ) , F ( x π ( i ) ) ) ∂ F ( x π ( i ) ) ] F = F m − 1 \tilde r_{m}^{\pi(i)}=-\bigg[{\partial L(y_{\pi(i)},F(x_{\pi(i)}))\over \partial F(x_{\pi(i)})}\bigg]_{F=F_{m-1}} r~mπ(i)=−[∂F(xπ(i))∂L(yπ(i),F(xπ(i)))]F=Fm−1(3) 对 { x π ( i ) , r ~ m π ( i ) } 1 N \{x_{\pi(i)},\tilde r_{m}^{\pi(i)}\}_1^N {xπ(i),r~mπ(i)}1N拟合一个回归树,得到第 m m m颗树的叶结点区域 R m j , j = 1 , 2 , … , J R_m^{j},\ j=1,2,\dots,J Rmj, j=1,2,…,J
(4) 对 j = 1 , 2 , … , J j=1,2,\dots,J j=1,2,…,J,计算: γ m j = arg min γ ∑ x π ( i ) ∈ R m j L ( y π ( i ) , F m − 1 ( x π ( i ) ) + γ ) \gamma_m^{j}=\arg\min_\gamma\sum_{x_{\pi(i)}\in R_m^{j}}L(y_{\pi(i)},F_{m-1}(x_{\pi(i)})+\gamma) γmj=argγminxπ(i)∈Rmj∑L(yπ(i),Fm−1(xπ(i))+γ)(5)更新 F m ( x ) = F m − 1 ( x ) + ν ⋅ ∑ j = 1 J γ m j I ( x ∈ R m j ) F_m(x)=F_{m-1}(x)+\nu\cdot\sum_{j=1}^J\gamma_m^{j}I(x\in R_m^{j}) Fm(x)=Fm−1(x)+ν⋅∑j=1JγmjI(x∈Rmj) - 输出 F ^ ( x ) = F M ( x ) \hat F(x)=F_M(x) F^(x)=FM(x)
当 N ~ = N \tilde{N}=N N~=N时就没有随机性,这个算法就和之前的GBDT是一样的。比例 f = N ~ / N f=\tilde{N}/N f=N~/N越小,在连续迭代中的随机样本就会差别越大,因此,整个程序的整个随机性就越大。用 f = 1 / 2 f=1/2 f=1/2的值大致等价于在每次迭代中使用自助采样(boostrap)。使用 N ~ = f ⋅ N \tilde{N}=f\cdot N N~=f⋅N也会使得计算量减少 f f f倍。然而,使用越小的 f f f值会减少每次迭代用来训练基学习器的数据量,这会导致单个基学习器的方差增加。