在2019年9月16日11晚,Jay Chou开始发布了他的新歌说好不哭
的时候,不到12个小时,售出量就已经达到了500万,还导致了QQ音乐系统瘫痪,这充分看出周董的高流量人气,当然,作为90后的我也是其中粉丝之一。这告诉我们的是,无论做什么,扎实的基础很重要的,如果周董没有扎实的音乐基础(PS:当然,也不否认他在音乐方面也具备一定的天赋),他也不会在经过这么长时间后重发表新歌时再次受到很多的粉丝的喜爱,记得小时候就特别喜欢周董的歌曲,一直到现在,仍然如此。哈哈,可能有些扯远了,但是通过这件事情,我自己也有些思考。作为IT圈的研究者而言,站在周董的层面思考,带给我的是,在你想实现或者完成某件事情的时候,你需要在前期打下扎实的基础,不断地往前走;站在研发角度来看,对于QQ音乐的系统架构设计者,在设计之初,肯定没想到有这么一天,当用户流量达到这个级别时,QQ音乐系统会承受不了,当然这也是腾讯QQ音乐负责人始料未及的。但是对于这些类似的事情,在微博的身上同样也出现类似的情况。这背后的思考就是对于这些平台类的系统不仅具备高稳定性等几个高要求,还需要具备一定承受压力的能力,这也表示平台类的软件开发需要逐步走向自适应化、智能化。
讲述了这么多,咱们继续来"砌墙"——总结一些提升方法的算法以及相关推导。
相关概念
- 弱可学习:可以找到一个方法,用这个方法预测输出变量,对于分类问题,会比随机猜测的效果略好。
- 强可学习:可以学习的效果很好。
- PAC学习框架:在第1章讲的泛化误差上界的定理,也就是说,可以用一个训练误差和一个小的参数以一定的概率控制泛化误差。
- 提升方法的基本思路:如果能找到一个弱可学习算法,那就可以将该算法提升为强可学习算法。
提升方法属于集成学习中的一种,集成学习就是用一些比较简单的模型,将它们综合起来构成一个复杂的模型。
集成学习两个主要类别:序列方法、并行方法。
- 序列方法:当我们学到一个模型,再学下一个模型时,下一个模型依赖上一个模型的结果。
- 并行方法:可以同时学很多模型,这些模型之间不会相互影响。
AdaBoost算法
AdaBoost算法是一个非常重要的序列方法,提出得比较早,具有很强的理论支撑;之后就是提升树,AdaBoost主要解决二分类问题,提升树分为回归树提升方法和分类树提升方法,既可以用分类树提升方法解决多分类问题,也可以用回归树提升方法解决回归问题(当输出变量是连续变量时,该问题称为回归问题)。
模型
AdaBoost实质上是一种加法模型。
[输入:训练数据集T={(x_1,y_1),(x_2,y_2),cdots,(x_N,y_N)},其中x_i in mathcal{X} \ subseteq extbf{R}^n, y_i in mathcal{Y} = {-1, +1};弱学习算法;\
输出:最终分类器G(x)。\
(1)初始化训练数据的权值分布D_1 = (w_{11},cdots,w_{1i},cdots,w_{1N}), quad w_{1i}=frac{1}{N}, quad i = 1, 2, cdots, N \
(2)对m=1,2,cdots,M表示学习每个小分类器的过程。\(a)使用具有权值分布D_m的训练数据集学习,得到基本分类器G_m(x):mathcal{X}
ightarrow {-1,+1} \ (b)计算G_m(x)在训练数据集上的分类误差率。
\ displaystyle e_m=sum_{i=1}^N P(G_m(x_i)
eq y_i)=sum_{i=1}^N w_{mi}I(G_m(x_i)
eq y_i)\
(c)计算G_m(x)的系数。 \
alpha_m=frac{1}{2} ln frac{1-e_m}{e_m} \
(d)更新训练数据集的权值分布。\
D_{m+1}=(w_{m+1,1},cdots,w_{m+1,i},cdots,w_{m+1,N}) \ w_{m+1,i}=frac{w_{mi}}{Z_m}exp (-alpha_m y_i G_m(x_i)), quad i=1, 2, cdots, \
N 其中,Z_m是规范化因子displaystyle Z_m=sum_{i=1}^N w_{mi} exp(-alpha_m y_i G_m(x_i)) 它使D_{m+1}成为一个概率分布。\
(3)构建基本分类器的线性组合。\
displaystyle f(x)=sum_{m=1}^M alpha_m G_m(x) 得到最终分类器displaystyle G(x)= ext{sign}(f(x))= ext{sign}Big( sum_{m=1}^M alpha_m G_m(x) Big)
]
策略——训练误差分析
[AdaBoost的损失函数是一个指数函数L(y,f(x))=exp[-yf(x)],二分类中y in {-1, +1}, f(x) in {-1, +1},\如果预测值等于真实值(预测正确即y=f(x)),yf(x)=1,损失为e^{-1},\如果不相等(预测错误即y
eq f(x)),损失为e,这个与我们平常看到的损失不一致,这里即使预测正确,\也是有损失的,预测错误比预测正确的损失大。
]
AdaBoost最基本的性质是能在学习过程中不断减少训练误差,即在训练数据集上的分类误差率。对于以上的定理有相关的推导。
数学推导
[定理1. (AdaBoost的训练误差界)AdaBoost算法最终分类器的训练误差界为:\
frac{1}{N}sum_{i=1}^N I(G(x_i)
eq y_i) leqslant frac{1}{N} sum_i exp(-y_i f(x_i)) = prod_m Z_m\
]
证明过程:
[对于正确分类点,I(G(x_i)
eq y_i) = 0 leqslant exp (-y_i f(x_i)) = e^{-1},\
对于误分类点,I(G(x_i)
eq y_i) = 1 leqslant exp (-y_i f(x_i)) = e^1,所以可得I(G(x_i)
eq y_i) leqslant exp (-y_i f(x_i)),\故displaystyle frac{1}{N}sum_{i=1}^N I(G(x_i)
eq y_i) leqslant frac{1}{N} sum_i exp(-y_i f(x_i))成立。\
现证明displaystyle frac{1}{N} sum_i exp(-y_i f(x_i)) = prod_m Z_m:\
displaystyle ecause Z_m=sum_i w_{mi} exp(-alpha_m y_i G_m(x_i)) displaystyle quad w_{m+1,i}=frac{w_{mi}}{Z_m} exp(-alpha_m y_i G_m(x_i))\
herefore Z_m cdot w_{m+1,i} = w_{mi} exp(-alpha_m y_i G_m(x_i))\
即:egin{array}{rl} Z_1 cdot w_{2,i} = & w_{1,i} exp(-alpha_1 y_i G_1(x_i)) \ Z_2 cdot w_{3,i} = & w_{2,i} exp(-alpha_2 y_i G_2(x_i)) \ vdots & \ Z_{M-1} cdot w_{M,i} = & w_{M-1,i} exp(-alpha_{M-1} y_i G_{M-1}(x_i)) end{array}\
因此将上述各式都相乘,相同的项可以约去,得到:\
displaystyle prod_{m=1}^{M-1} Z_m w_{M,i} = w_{1,i} exp(-y_i sum_{m=1}^{M-1} alpha_m G_m{x_i})\
对比要证明的等式displaystyle frac{1}{N} sum_i exp(-y_i f(x_i)) = prod_{m=1}^M Z_m,其中f(x_i)=sum_{m=1}^M alpha_m G_m(x_i)\
左右两边都乘以exp(-alpha_M y_i G_M(x_i))\
displaystyle ecause w_{1,i}=frac{1}{N}\
displaystyle herefore prod_{m=1}^{M-1} Z_m w_{M,i} cdot exp(-alpha_M y_i G_M(x_i)) = frac{1}{N} exp(-y_i f(x_i)) \
由于最终得到的是关于整个数据集的,所以需要两边求和。\
displaystyle herefore prod_{m=1}^{M-1} Z_m sum_i w_{M,i} exp(-alpha_M y_i G_M(x_i)) = frac{1}{N} sum_i exp(-y_i f(x_i))\
ecause Z_M=sum_i w_{M,i} exp(-alpha_M y_i G_M(x_i))\
displaystyle herefore prod_{m=1}^{M-1} Z_m cdot Z_M = frac{1}{N} sum_i exp(-y_i f(x_i)) \
displaystyle herefore prod_{m=1}^{M} Z_m = frac{1}{N} sum_i exp(-y_i f(x_i)),得证.\
定理的直观理解:训练误差可以被Z_m的连乘控制住,如果要训练误差小,就只要最小化\每一个Z_m,displaystyle Z_m=sum_i w_{mi} exp(-alpha_m y_i G_m(x_i)),w_{mi}是通过上一轮训练得到的,\G_m是本轮已经训练得到的,所以已知w_{mi},G_m,求解的是alpha_m,\通过最小化Z_m求解alpha_m= mathop{arg min} limits_{alpha_m} Z_m。\
displaystyle frac{partial Z_m}{partial alpha_m} = sum_i Big( -w_{mi} y_i G_m(x_i) exp(-alpha_m y_i G_m(x_i)) Big)\
即:displaystyle alpha_m=frac{1}{2} ln frac{1-e_m}{e_m}
]
[定理2. (二类分类问题AdaBoost的训练误差界)\
prod_{m=1}^M Z_m = prod_{m=1}^M [2 sqrt{e_m(1-e_m)}] = prod_{m=1}^M sqrt{(1-4gamma_m^2)} leqslant exp ig( -2 sum_{m=1}^M gamma_m^2 ig),\其中,displaystyle gamma_m = frac{1}{2}-e_m \
e_m越小,说明当前分类器效果越好,gamma_m越大,frac{1}{2}可以看做是分类问题中,随机猜测分类结果的最大误差率。\ gamma_m可以解释成当前的基本分类器对于随机猜测结果的提升程度。提升程度越大,gamma_m越大,\上界displaystyle exp ig( -2 sum_{m=1}^M gamma_m^2 ig)就越小,训练误差随着迭代次数的增加而越小,\减小的速度是以指数速度变小的,也就是说,训练次数增多的时候,训练误差降低的速度会变快。
]
证明过程:
[egin{aligned} Z_m =& sum_{i=1}^N w_{mi} exp(-alpha_m y_i G_m(x_i)) \ =&sum_{y_i=G_m(x_i) w_{mi} e^{-alpha_m}} + sum_{y_i
eq G_m(x_i) w_{mi} e^{alpha_m}} end{aligned}\ displaystyle ecause e_m=sum_{G_m(x_i)
eq y_i} w_{mi}, alpha_m=frac{1}{2} ln frac{1-e_m}{e_m}\ displaystyle herefore sum_{y_i=G_m(x_i) w_{mi} e^{-alpha_m}} + sum_{y_i
eq G_m(x_i) w_{mi} e^{alpha_m}} = (1-e_m)e^{-alpha_m} + e_m e^{alpha_m} \ displaystyle ecause e^{-alpha_m} = sqrt{frac{e_m}{1-e_m}}, e^{alpha_m} = sqrt{frac{1-e_m}{e_m}}\ displaystyle herefore (1-e_m)e^{-alpha_m} + e_m e^{alpha_m} = 2 sqrt{e_m (1- e_m)} herefore Z_m = 2 sqrt{e_m (1- e_m)} \ displaystyle ecause gamma_m = frac{1}{2} - e_m \ herefore 2 sqrt{e_m (1- e_m)} = sqrt{1-4 gamma_m^2} \ displaystyle herefore prod_{m=1}^M Z_m = prod_{m=1}^M [2 sqrt{e_m(1-e_m)}] = prod_{m=1}^M sqrt{(1-4gamma_m^2)}\ 再考虑displaystyle prod_{m=1}^M sqrt{(1-4 gamma_m^2)} leqslant exp ig( -2 sum_{m=1}^M gamma_m^2 ig)\ 由e^x和sqrt{1-x}在点x=0的泰勒展开式推导,泰勒展开是用一个多项式逼近任意一个函数。\ 考察sqrt{(1-4 gamma^2)} leqslant exp( -2 gamma^2)\ displaystyle f(x)=sqrt{1-x}=(1-x)^{frac{1}{2}} \ displaystyle f'(x) = -frac{1}{2}(1-x)^{-frac{1}{2}} \ displaystyle f''(x) = -frac{1}{4}(1-x)^{-frac{3}{2}}\ f(x)在x=0处的二阶泰勒展开为:\ egin{aligned} f(x) &= f(0) + xf'(0) + frac{1}{2} xf''(0) + cdots \&= 1 - frac{1}{2} x - frac{1}{8} x^2 + cdots end{aligned} \ herefore f(4 gamma^2) approx 1 - 2 gamma^2 - 2 gamma^4 \ g(x) = e^x \ g'(x) = e^x g''(x) = e^x\ g(x)在x=0处的二阶泰勒展开为:\ egin{aligned} g(x) &= g(0) + x g'(0) + frac{1}{2} x^2 g''(0) + cdots \&= 1 + x + frac{1}{2} x^2 + cdots end{aligned} \ herefore g(-2 gamma^2) approx 1 - 2 gamma^2 + 2 gamma^4 \ herefore egin{array}{l} f(4 gamma^2) = sqrt{(1-4 gamma^2)} approx 1 - 2 gamma^2 - 2 gamma^4 \ g(-2 gamma^2) = exp( -2 gamma^2) approx 1 - 2 gamma^2 + 2 gamma^4 end{array} \ displaystyle ecause gamma_m = frac{1}{2} - e_m ,gamma_m的取值范围是displaystyle [0,frac{1}{2}]\ 所以当更高阶次方出现的时候,后面的高阶项趋近于0,那么影响g(-2 gamma^2)和f(4 gamma^2)关系的只有前面的项,\判断1 - 2 gamma^2 - 2 gamma^4和1 - 2 gamma^2 + 2 gamma^4 的大小,等同于判断f(4 gamma^2)和g(-2 gamma^2)的大小。\ ecause 1 - 2 gamma^2 - 2 gamma^4 leqslant 1 - 2 gamma^2 + 2 gamma^4\ herefore f(4 gamma^2) leqslant g(-2 gamma^2) \ displaystyle herefore prod_{m=1}^M sqrt{(1-4 gamma_m^2)} leqslant exp ig( -2 sum_{m=1}^M gamma_m^2 ig) ,得证.
]
算法——前向算法
有了模型和策略,当拟合加法模型时,需要求解很多的参数,有一个比较简单的算法(前向分步算法)。
[输入:训练数据集T={(x_1,y_1),(x_2,y_2),cdots, (x_N,y_N)},损失函数L(y,f(x)),基函数集{b(x;gamma)};\ 输出:加法模型f(x)。\ (1)初始化f_0(x)=0。\ (2)对m=1,2,cdots,M。\ (a)极小化损失函数。(eta_m, gamma_m) = mathop{arg min} limits_{eta,gamma} sum_{i=1}^N L(y_i, f_{m-1}(x_i) + eta b(x_i;gamma))。\ (b)更新f_m(x)=f_{m-1}(x) + eta_m b(x;gamma_m)。\ (3)得到加法模型f(x)=f_M(x)=sum_{m=1}^M eta_m b(x;gamma_m)。\ 这样,前向分步算法将同时求解从m=1到M所有参数eta_m,gamma_m的优化问题简化为\逐次求解各个eta_m, gamma_m的优化问题。
]
提升树
提升树与AdaBoost算法的思路是非常像的,也是考虑一个加法模型,AdaBoost算法中没有规定所用的分类器,提升树中,基本分类器为分类树或回归树(分类树用来做分类问题,回归树用来做回归问题),所用的算法依然是前向分步算法。对于分类树的提升树,如果是二分类问题,该算法和AdaBoost算法是等价的。
假如不用平方误差损失,换成其他的损失函数时,残差不太好计算。梯度提升算法依然采用拟合每一个训练数据,由于不是采用平方误差损失,之前用残差拟合下一棵树的方法就不适用了,此时提出梯度提升算法。
[***梯度提升算法*** \ 输入:训练数据集T={(x_1,y_1),(x_2,y_2), cdots, (x_N,y_N)}, x in mathcal{X} subseteq ext{R}^n, y in mathcal{Y} subseteq ext{R},损失函数L(y,f(x))\ 输出:回归树hat{f}(x)。\ (1)初始化。 displaystyle f_0(x)= mathop{arg min} limits_{c} sum_{i=1}^N L(y_i, c)\ (2)对m=1,2,cdots,M (a)对i=1,2,cdots,N,计算r_{mi}=-ig[frac{partial L(y_i, f(x_i))}{partial f(x_i)} ig]{f(x)=f_{m-1}(x)} \ (b)对r_{mi}拟合一个回归树,得到第m棵树的叶结点区域 ext{R}_{mj},j=1,2,cdots,J\ (c)对j=1,2,cdots,J,计算c_{mj}=mathop{arg min} limits_{c} sum_{x_i in ext{R}{mj}} L(y_i, f{m-1}(x_i) + c)\ (d)更新。displaystyle f_m(x)=f_{m-1}(x) + sum_{j=1}^J c_{mi} I(x in R_{mj})\ (3)得到回归树。hat{f}(x) = f_M(x)=sum_{m=1}^M sum_{j=1}^J c_{mj}I(x in R_{mj})\ **在算法中,依然是需要一个类似与残差的变量,该值(r_{mi})是用负梯度计算的,\r_{mi}是损失函数关于f(x)的负梯度,然后用r_{mi}拟合新的回归树,一般情况下是求解Theta_m,Theta_m包含两个部分:\空间上的划分 ext{R}_{mj},j=1,2,cdots,J和拟合值c_{mj}。
]
问题思考
1.在提升算法中,为什么可以用负梯度近似代替残差?
[答:假设L(y_i,f(x_i))=[y_i-f(x_i)]^2,则displaystyle -frac{partial L(y_i, f(x_i))}{partial f(x_i)} = -(-2[y_i-f(x_i)]) = 2[y_i-f(x_i)] = r_{mi},\推广用到的是一阶泰勒展开的近似,从平方损失的例子中可以看到,用负梯度确实可以代替残差。\但是在推导的过程中,可以看到前面有一个系数2,所以负梯度只是残差的代替,并不能等同于残差。\这也就是为什么在(c)步中要根据原始的y_i和f(x)的形式求解c
]
2.计算残差时,为什么只能通过残差求解Rmj,还需要重新计算吗?
[答:由于已经确定了每一个叶子结点区域 ext{R}_{mj},对于每一个叶子结点j,只需考虑该叶子结点,而不需要考虑\其他的叶子结点,当求这一个叶子结点(即求分到这个叶子结点的样本点x_i in ext{R}_{mj})中的样本点x_i,\求这些点的经验损失和( ext{R}_{mj}上对应样本点的经验风险),真实值为y_i,拟合值为f_{m-1}(x_i)再加第m步中得到的数,\此处只关心 ext{R}_{mj}区域中的叶子结点部分,对这个叶子结点,新得到的这个数(拟合值)为c,所以整体的拟合值为\f_{m-1}(x_i)+c。\ 通过经验风险最小,求得这个叶子结点上那棵新树对应的c值,f_m(x_i)+c表示为在 ext{R}_{mj}区域范围的样本点的\拟合值f_m(x_i)。所以对于一个新的回归树,已经求了J(第m棵树中叶子结点的个数)个这样的c,更新的形式为\displaystyle f_m(x)=f{m-1}(x)+ sum_{j=1}^J c_{mj} I(x in ext{R}_{mj}),对于每个样本点,只在其中的一个指示函数(indicator function)\中等于1,因为只能属于其中的一个 ext{R}_{mj},当I(x in ext{R}_{mj})=1时,累积求和。对于每一棵树f_m(x),都有一个c_m,\对每一棵树上,又划分了J个区域,所以拟合值为c_{mj}。对于每一个样本点,在每一棵树上,\都只有一个指示函数为1。虽然(3)步求和是M,J,但是最后求解时,只有M项的和。
]