前言:我们讲到了集成学习按照个体学习器之间是否存在依赖关系可以分为两类,第一个是个体学习器之间不存在强依赖关系,另一类是个体学习器之间存在强依赖关系。后者的代表算法就是是boosting系列算法。本文就对boosting以及对其各种延伸算法做详细的推导。
注:这篇文章由于有很多数学公式,编辑起来很费力,所以很多会采取截图的方式来撰写,大部分来源于李航老师的《统计学习方法》。
1、boosting的原理
Boosting每一次训练的时候都更加关心上一次分类错误的样例,给这些分类错误的样例更大的权重,下一次训练的目标就是能够更容易辨别出上一次分类错误的样例,最终将多次迭代训练得到的弱分类器进行加权相加得到最终的强分类器。
Boosting算法的工作机制是首先从训练集用初始权重训练出一个弱学习器1,根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器2中得到更多的重视。然后基于调整权重后的训练集来训练弱学习器2.,如此重复进行,直到弱学习器数达到事先指定的数目T,最终将这T个弱学习器通过集合策略进行整合,得到最终的强学习器。
2、前向分布算法
在介绍各种boosting算法的变种时,我们先来看看前向分布算法,这回对我们理解boosting算法有很大的帮助。
在boost算法中,至少在我们即将要讲的Adaboost算法中,我们的最终目的是通过构建弱分类器的线性组合:
来得到最终分类器。
我们在看看加法模型:
其中,为基函数,
是基函数的参数,
为基函数的系数。显然式8.6是一个加法模型。
对于加法模型,在给定训练数据及损失函数L(y, f(x))的条件下,学习加法模型f(x)就成为经验风险极小化损失函数极小化问题:
但这是一个复杂的优化问题。
前向分布算法(forward stagewise algorithm)求解这一优化问题的想法是:
因为学习的是加法模型,那如果能够从前向后,每一步只学习一个基函数及其系数,在前一轮的基础上,然后逐步逼近优化目标式8.14,那么就可以简化优化的复杂度。
具体的,每步只需优化如下损失函数:
于是,前向分布算法总结如下:
输入:训练数据集T =;损失函数
;基函数集
;
输出:加法模型
1,初始化
2,对m = 1, 2,.., M
a,极小化损失函数
得到参数
b,更新
3,得到加法模型
这样,前向分布算法将同时求解从m=1到M的所有参数的优化问题简化为逐次求解各个
的优化问题。
3、Adaboost算法
摘自《李航统计学习方法》
对于提升方法来说,有两个问题需要回答:一是在每一轮如何改变训练数据的权值获概率分布;二是如何将弱分类器组合成一个强分类器。关于第一个问题,Adaboost的做法是:提高那些被前一轮错误分类样本的权值,而降低那些被正确分类的数据,至于第二个问题,即弱分类器的组合,Adaboost采取加权多数表决的方法。具体的,加大分类误差率小的弱分类器的权值,使其在表决中七较大的作用,减小分类误差率的弱分类器的 权值,使其在表决中起较小的作用。
回顾boosting算法的基本原理,有几个具体的问题Boosting算法没有详细说明。
- 如何计算学习误差率e?
- 如何得到弱学习器权重系数α?
- 如何更新样本权重D?
- 使用何种结合策略?
只要是boosting大家族的算法,都要解决这4个问题。那么Adaboost是怎么解决的呢?
3.1、Adaboost的分类问题
对上面的步骤做一些说明:
-
表示第m轮中第i个实例的权值,且:
-
在加权的训练数据集上的分类误差率是被
误分类样本的权值之和,由此可以看出数据权值分布
与弱分类器
的分类误差率的关系
- 更新训练数据的权值分布为下一轮做准备。式8.4可以写成:
-
- 被弱分类器
误分类样本的权值得以扩大,而被正确分类样本的权值却得以缩小。从8.4可以看出,两相比较,误分类样本的权值被放大
倍,因此,误分类样本在下一轮学习中起更大的作用。
- 系数am表示了弱分类器Gm(x)的重要性,这里,所有am之和并不为1。f(x)的符号决定实例x的类,f(x)的绝对值表示分类的确信度。“利用弱分类器的线性组合构建最终分类器”是Adaboost的另一个特点。
小结:
Adaboost算法是前向分布加法算法的特例,这时模型是由基本分类器组成的加法模型,损失函数是指数函数。这是一个定理(已经被证明过)。
3.2、回归问题的提升算法
注意,这里使用的树都是CART,一定注意这是二叉树。
3.3、Adaboost算法的正则化
为了防止Adaboost过拟合,我们通常也会加入正则化项,这个正则化项我们通常称为步长(learning rate)。定义为,对于前面的弱学习器的迭代
如果我们加上了正则化项,则有
的取值范围为
。对于同样的训练集学习效果,较小的
意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。
4、GBDT算法
GBDT在BAT大厂中也有广泛的应用,假如要选择3个最重要的机器学习算法的话,个人认为GBDT应该占一席之地。(借鉴刘老师的看法)
GBDT也是集成学习Boosting家族的成员,但是却和传统的Adaboost有很大的不同。回顾下Adaboost,我们是利用前一轮迭代弱学习器的误差率来更新训练集的权重,这样一轮轮的迭代下去。GBDT也是迭代,使用了前向分布算法,但是弱学习器限定了只能使用CART回归树模型,同时迭代思路和Adaboost也有所不同。
4.1、GBDT的负梯度拟合
在上一小节中,我们看出了提升方法的树回归问题中,每一次的迭代都是上一次的残差,但是没有解决损失函数拟合方法的问题。针对这个问题,大牛Freidman提出了用损失函数的负梯度来拟合本轮损失的近似值(可以想象一下高等数学中导数),进而拟合一个CART回归树。第t轮的第i个样本的损失函数的负梯度表示为:
4.2、GBDT的正则化
和Adaboost一样,我们也需要对GBDT进行正则化,防止过拟合。GBDT的正则化主要有三种方式。
1) 第一种是和Adaboost类似的正则化项,即步长(learning rate)。定义为,对于前面的弱学习器的迭代
如果我们加上了正则化项,则有
的取值范围为
。对于同样的训练集学习效果,较小的
意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。
2)第二种是对于弱学习器即CART回归树进行正则化剪枝。在决策树原理篇里我们已经讲过,这里就不重复了。
3) 第三种正则化的方式是通过子采样比例(subsample)。取值为(0,1]。注意这里的子采样和随机森林不一样,随机森林使用的是放回抽样,而这里是不放回抽样。如果取值为1,则全部样本都使用,等于没有使用子采样。如果取值小于1,则只有一部分样本会去做GBDT的决策树拟合。选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。推荐在[0.5, 0.8]之间。
5、Adaboost、GBDT框架参数
5.1、Adaboost框架参数
scikit-learn中Adaboost类库比较直接,就是AdaBoostClassifier和AdaBoostRegressor两个
class sklearn.ensemble.AdaBoostClassifier(base_estimator=None, n_estimators=50, learning_rate=1.0, algorithm=’SAMME.R’, random_state=None)[source]¶(官网参数)
先看boosting框架参数:
- n_estimators: AdaBoostClassifier和AdaBoostRegressor都有,就是我们的弱学习器的最大迭代次数,或者说最大的弱学习器的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,默认是50。在实际调参的过程中,我们常常将n_estimators和下面介绍的参数learning_rate一起考虑。
-
learning_rate: AdaBoostClassifier和AdaBoostRegressor都有,即每个弱学习器的权重缩减系数
,在原理篇的正则化章节我们也讲到了,加上了正则化项,我们的强学习器的迭代公式为
。
的取值范围为
。对于同样的训练集拟合效果,较小的
意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。所以这两个参数n_estimators和learning_rate要一起调参。一般来说,可以从一个小一点的
开始调参,默认是1。
- algorithm:这个参数只有AdaBoostClassifier有。主要原因是scikit-learn实现了两种Adaboost分类算法,SAMME和SAMME.R。两者的主要区别是弱学习器权重的度量,SAMME使用了和我们的原理篇里二元分类Adaboost算法的扩展,即用对样本集分类效果作为弱学习器权重,而SAMME.R使用了对样本集分类的预测概率大小来作为弱学习器权重。由于SAMME.R使用了概率度量的连续值,迭代一般比SAMME快,因此AdaBoostClassifier的默认算法algorithm的值也是SAMME.R。我们一般使用默认的SAMME.R就够了,但是要注意的是使用了SAMME.R, 则弱分类学习器参数base_estimator必须限制使用支持概率预测的分类器。SAMME算法则没有这个限制。
再看弱分类器的框架参数
- base_estimator:AdaBoostClassifier和AdaBoostRegressor都有,即我们的弱分类学习器或者弱回归学习器。理论上可以选择任何一个分类或者回归学习器,不过需要支持样本权重。我们常用的一般是CART决策树或者神经网络MLP。默认是决策树,即AdaBoostClassifier默认使用CART分类树DecisionTreeClassifier,而AdaBoostRegressor默认使用CART回归树DecisionTreeRegressor。另外有一个要注意的点是,如果我们选择的AdaBoostClassifier算法是SAMME.R,则我们的弱分类学习器还需要支持概率预测,也就是在scikit-learn中弱分类学习器对应的预测方法除了predict还需要有predict_proba。
- loss:这个参数只有AdaBoostRegressor有,Adaboost.R2算法需要用到。有线性‘linear’, 平方‘square’和指数 ‘exponential’三种选择, 默认是线性,一般使用线性就足够了,除非你怀疑这个参数导致拟合程度不好。这个值的意义,它对应了我们对第k个弱分类器的中第i个样本的误差的处理
- 如果是使用CART作为弱分类器,其参数在决策树原理篇讲过,这里不阐述。
5.2、GBDT框架参数
class sklearn.ensemble.GradientBoostingClassifier(loss=’deviance’, learning_rate=0.1, n_estimators=100, subsample=1.0, criterion=’friedman_mse’, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3, min_impurity_decrease=0.0, min_impurity_split=None, init=None, random_state=None, max_features=None, verbose=0, max_leaf_nodes=None, warm_start=False, presort=’auto’)[source]¶(官网参数)
先看boosting框架参数:
- n_estimators: 也就是弱学习器的最大迭代次数,或者说最大的弱学习器的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值。默认是100。在实际调参的过程中,我们常常将n_estimators和下面介绍的参数learning_rate一起考虑。
-
learning_rate: 即每个弱学习器的权重缩减系数
,也称作步长,在原理篇的正则化章节我们也讲到了,加上了正则化项,我们的强学习器的迭代公式为
。
的取值范围为
。对于同样的训练集拟合效果,较小的
意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。所以这两个参数n_estimators和learning_rate要一起调参。一般来说,可以从一个小一点的
开始调参,默认是1。
- subsample: 即我们在原理篇的正则化章节讲到的子采样,取值为(0,1]。注意这里的子采样和随机森林不一样,随机森林使用的是放回抽样,而这里是不放回抽样。如果取值为1,则全部样本都使用,等于没有使用子采样。如果取值小于1,则只有一部分样本会去做GBDT的决策树拟合。选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。推荐在[0.5, 0.8]之间,默认是1.0,即不使用子采样。
-
init: 即我们的初始化的时候的弱学习器,拟合对应原理篇里面的
,如果不输入,则用训练集样本来做样本集的初始化分类回归预测。否则用init参数提供的学习器做初始化分类回归预测。一般用在我们对数据有先验知识,或者之前做过一些拟合的时候,如果没有的话就不用管这个参数了。
- loss: 即我们GBDT算法中的损失函数。分类模型和回归模型的损失函数是不一样的。对于分类模型,有对数似然损失函数"deviance"和指数损失函数"exponential"两者输入选择。默认是对数似然损失函数"deviance"。一般来说,推荐使用默认的"deviance"。它对二元分离和多元分类各自都有比较好的优化。而指数损失函数等于把我们带到了Adaboost算法。对于回归模型,有均方差"ls", 绝对损失"lad", Huber损失"huber"和分位数损失“quantile”。默认是均方差"ls"。一般来说,如果数据的噪音点不多,用默认的均方差"ls"比较好。如果是噪音点较多,则推荐用抗噪音的损失函数"huber"。而如果我们需要对训练集进行分段预测的时候,则采用“quantile”。
- alpha:这个参数只有GradientBoostingRegressor有,当我们使用Huber损失"huber"和分位数损失“quantile”时,需要指定分位数的值。默认是0.9,如果噪音点较多,可以适当降低这个分位数的值。
6、总结
由于GBDT的卓越性能,只要是研究机器学习都应该掌握这个算法,包括背后的原理和应用调参方法。目前GBDT的算法比较好的库是xgboost。当然scikit-learn也可以。
优点
- 很好的利用了弱分类器进行级联。
- 可以将不同的分类算法作为弱分类器。
- AdaBoost具有很高的精度,不容易过拟合。
- 相对于bagging/Random Forest算法,AdaBoost充分考虑的每个分类器的权重。
- 能处理非线性数据,能做回归和分类。。。(决策树算法的特点)
- 精度高(Boosting的共同特点)
缺点
- AdaBoost迭代次数也就是弱分类器数目不太好设定。
- 训练比较长
- 预测效果依赖于弱分类器的选择(Adaboost只是一个算法框架)
- 计算复杂度大,耗时(Boosting的共性缺点)
参考资料:
https://blog.csdn.net/xueyingxue001/article/details/51304490
https://www.cnblogs.com/pinard/p/6133937.html