scikit-learn Adaboost类库使用总结

一、Adaboost类库概述

    scikit-learn中Adaboost类库可分为AdaBoostClassifier和AdaBoostRegressor两个,从名字就可以看出AdaBoostClassifier用于分类,AdaBoostRegressor用于回归。

    AdaBoostClassifier使用了两种Adaboost分类算法的实现,SAMME和SAMME.R。而AdaBoostRegressor则使用Adaboost回归算法的实现,即Adaboost.R2。

    当我们对Adaboost调参时,主要是对两部分内容进行调参,第一部分是对Adaboost的框架进行调参, 第二部分则是对我们选择的弱分类器进行调参。两者相辅相成。下面就对Adaboost的两个类:AdaBoostClassifier和AdaBoostRegressor从这两部分做一个介绍。

二、AdaBoostClassifier和AdaBoostRegressor框架参数

    我们首先来看看AdaBoostClassifier和AdaBoostRegressor框架参数。两者大部分框架参数相同,下面我们一起讨论这些参数,两个类如果有不同点我们会指出。

  1. base_estimator: AdaBoostClassifier和AdaBoostRegressor都有,即我们的弱分类学习器或者弱回归学习器。理论上可以选择任何一个分类或者回归学习器,不过需要支持样本权重。我们常用的一般是CART决策树或者神经网络MLP。默认是决策树,即AdaBoostClassifier默认使用CART分类树DecisionTreeClassifier,而AdaBoostRegressor默认使用CART回归树DecisionTreeRegressor。
        另外有一个要注意的点是,如果我们选择的AdaBoostClassifier算法是SAMME.R,则我们的弱分类学习器还需要支持概率预测,也就是在scikit-learn中弱分类学习器对应的预测方法除了predict还需要有predict_proba。
  2. algorithm: 这个参数只有AdaBoostClassifier有。主要原因是scikit-learn实现了两种Adaboost分类算法,SAMME和SAMME.R。如果为“ SAMME.R”,则使用SAMME.R实际增强算法。 base_estimator必须支持类概率的计算。如果为“ SAMME”,则使用SAMME离散提升算法。SAMME.R算法通常比SAMME收敛更快,从而以更少的提升迭代次数实现了更低的测试误差。
        两者的主要区别是弱学习器权重的度量,SAMME使用了和我们的原理篇里二元分类Adaboost算法的扩展,即用对样本集分类效果作为弱学习器权重,而SAMME.R使用了对样本集分类的预测概率大小来作为弱学习器权重。由于SAMME.R使用了概率度量的连续值,迭代一般比SAMME快,因此AdaBoostClassifier的默认算法algorithm的值也是SAMME.R。我们一般使用默认的SAMME.R就够了,但是要注意的是使用了SAMME.R, 则弱分类学习器参数base_estimator必须限制使用支持概率预测的分类器。SAMME算法则没有这个限制。
  3. loss: 这个参数只有AdaBoostRegressor有,Adaboost.R2算法需要用到。有线性‘linear’, 平方‘square’和指数 ‘exponential’三种选择, 默认是线性,一般使用线性就足够了,除非你怀疑这个参数导致拟合程度不好。它对应了我们对第k个弱分类器的中第i个样本的误差的处理,即:如果是线性误差,则 e k i = ∣ y i − G k ( x i ) ∣ E k e_{ki}=\frac{|y_i-G_k(x_i)|}{E_k} eki=EkyiGk(xi);如果是平方误差,则 e k i = ( y i − G k ( x i ) ) 2 E k 2 e_{ki}=\frac{(y_i-G_k(x_i))^2}{E_k^2} eki=Ek2(yiGk(xi))2;如果是指数误差,则 e k i = 1 − e x p ( − y i + G k ( x i ) E k ) e_{ki}=1-exp(\frac{-y_i+G_k(x_i)}{E_k}) eki=1exp(Ekyi+Gk(xi)) E k E_k Ek 为训练集上的最大误差 E k = m a x ∣ y i − G k ( x i ) ∣ i = 1 , 2... , m E_k=max|y_i−G_k(x_i)|i=1,2...,m Ek=maxyiGk(xi)i=1,2...,m
  4. n_estimators: AdaBoostClassifier和AdaBoostRegressor都有,就是我们的弱学习器的最大迭代次数,或者说最大的弱学习器的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值。默认是50。在实际调参的过程中,我们常常将n_estimators和下面介绍的参数learning_rate一起考虑。
  5. learning_rate: AdaBoostClassifier和AdaBoostRegressor都有,“学习率” 缩小了每个分类器的贡献 learning_rate。learning_rate和之间需要权衡n_estimators。对于同样的训练集拟合效果,较小的 “学习率” 意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。所以这两个参数 n_estimators 和 learning_rate要一起调参。一般来说,可以从一个小一点的 “学习率” 开始调参,默认是1。

三、AdaBoostClassifier和AdaBoostRegressor弱学习器参数

    由于使用不同的弱学习器,则对应的弱学习器参数各不相同,因此我们只讨论默认的决策树弱学习器的参数。即CART分类树DecisionTreeClassifier和CART回归树DecisionTreeRegressor。

    这里我们只拿出调参数时需要尤其注意的最重要几个的参数再拿出来说:

  1. max_features: 划分时考虑的最大特征数,可以使用很多种类型的值,默认是"None",意味着划分时考虑所有的特征数;如果是"log2"意味着划分时最多考虑 log ⁡ 2 N \log_2 N log2N个特征;如果是"sqrt"或者"auto"意味着划分时最多考虑 N \sqrt{N} N 个特征。如果是整数,代表考虑的特征绝对数。如果是浮点数,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数。其中N为样本总特征数。一般来说,如果样本特征数不多,比如小于50,我们用默认的"None"就可以了,如果特征数非常多,我们可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。
  2. max_depth: 决策树最大深,默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间。
  3. min_samples_split: 内部节点再划分所需最小样本数, 这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。 默认是2.如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。
  4. min_samples_leaf: 叶子节点最少样本数,这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。
  5. min_weight_fraction_leaf: 叶子节点最小的样本权重和,这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 默认是0,就是不考虑权重问题。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。
  6. max_leaf_nodes: 最大叶子节点数,通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。

四、AdaBoostClassifier举例

    先加载库

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_gaussian_quantiles

    接着我们生成一些随机数据来做二元分类,如果对如何产生随机数据不熟悉,在另一篇文章机器学习随机数生成中有比较详细的介绍。

# 生成2维正态分布,生成的数据按分位数分为两类,500个样本,2个样本特征,协方差系数为2
X1, y1 = make_gaussian_quantiles(cov=2.0,n_samples=500, n_features=2,n_classes=2, random_state=1)
# 生成2维正态分布,生成的数据按分位数分为两类,400个样本,2个样本特征均值都为3,协方差系数为2
X2, y2 = make_gaussian_quantiles(mean=(3, 3), cov=1.5,n_samples=400, n_features=2, n_classes=2, random_state=1)
#讲两组数据合成一组数据
X = np.concatenate((X1, X2))
y = np.concatenate((y1, - y2 + 1))

    通过可视化看看分类数据,它有两个特征,两个输出类别,用颜色区别。

plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)

    输出为下图:
在这里插入图片描述

    上图显示数据有些混杂,我们现在用基于决策树的Adaboost来做分类拟合。

bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
                         algorithm="SAMME",
                         n_estimators=200, learning_rate=0.8)
bdt.fit(X, y)

    输出为下图:

在这里插入图片描述

    这里我们选择了SAMME算法,最多200个弱分类器,步长0.8,在实际运用中你可能需要通过交叉验证调参而选择最好的参数。拟合完了后,我们用网格图来看看它拟合的区域。

x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
                     np.arange(y_min, y_max, 0.02))

Z = bdt.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
cs = plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)
plt.show()

    输出为下图:
在这里插入图片描述
    从图中可以看出,Adaboost的拟合效果还是不错的,现在我们看看拟合分数:

print("Score:", bdt.score(X,y))

    输出为下图:
在这里插入图片描述
    此时,拟合训练集数据的分数还不错。当然分数高并不一定好,因为可能过拟合。现在我们将最大弱分离器个数从200增加到300。再来看看拟合分数。

bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
                         algorithm="SAMME",
                         n_estimators=300, learning_rate=0.8)
bdt.fit(X, y)
print("Score:", bdt.score(X,y))

    输出为下图:
在这里插入图片描述
    这印证了我们前面讲的,弱分离器个数越多,则拟合程度越好,当然也越容易过拟合。

    现在我们降低步长,将步长从上面的0.8减少到0.5,再来看看拟合分数。

bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
                         algorithm="SAMME",
                         n_estimators=300, learning_rate=0.5)
bdt.fit(X, y)
print("Score:", bdt.score(X,y))

    输出为下图:
在这里插入图片描述
    可见在同样的弱分类器的个数情况下,如果减少步长,拟合效果会下降。

    最后我们看看当弱分类器个数为700,步长为0.7时候的情况:

bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
                         algorithm="SAMME",
                         n_estimators=600, learning_rate=0.7)
bdt.fit(X, y)
print("Score:", bdt.score(X,y))

    输出为下图:
在这里插入图片描述

    此时的拟合分数和我们最初的300弱分类器,0.8步长的拟合程度相当。也就是说,在我们这个例子中,如果步长从0.8降到0.7,则弱分类器个数要从300增加到700才能达到类似的拟合效果。

     以上就是scikit-learn Adaboost类库使用的一个总结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值