scikit-learn Adaboost类库使用小结

集成学习之Adaboost算法原理小结中,咱们对Adaboost的算法原理作了一个总结。这里咱们就从实用的角度对scikit-learn中Adaboost类库的使用作一个小结,重点对调参的注意事项作一个总结。html

1、Adaboost类库概述

    scikit-learn中Adaboost类库比较直接,就是AdaBoostClassifier和AdaBoostRegressor两个,从名字就能够看出AdaBoostClassifier用于分类,AdaBoostRegressor用于回归。node

    AdaBoostClassifier使用了两种Adaboost分类算法的实现,SAMME和SAMME.R。而AdaBoostRegressor则使用了咱们原理篇里讲到的Adaboost回归算法的实现,即Adaboost.R2。python

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

2、AdaBoostClassifier和AdaBoostRegressor框架参数

    咱们首先来看看AdaBoostClassifier和AdaBoostRegressor框架参数。二者大部分框架参数相同,下面咱们一块儿讨论这些参数,两个类若是有不一样点咱们会指出。github

 

    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使用了和咱们的原理篇里二元分类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_{ki}= \frac{|y_i - G_k(x_i)|}{E_k}\);若是是平方偏差,则\(e_{ki}= \frac{(y_i - G_k(x_i))^2}{E_k^2}\),若是是指数偏差,则\(e_{ki}= 1 - exp(\frac{-y_i + G_k(x_i))}{E_k})\)\(E_k\)为训练集上的最大偏差\(E_k= max|y_i - G_k(x_i)|\;i=1,2...m\)网络

 

     4) n_estimators: AdaBoostClassifier和AdaBoostRegressor都有,就是咱们的弱学习器的最大迭代次数,或者说最大的弱学习器的个数。通常来讲n_estimators过小,容易欠拟合,n_estimators太大,又容易过拟合,通常选择一个适中的数值。默认是50。在实际调参的过程当中,咱们经常将n_estimators和下面介绍的参数learning_rate一块儿考虑。框架

 

    5) learning_rate:  AdaBoostClassifier和AdaBoostRegressor都有,即每一个弱学习器的权重缩减系数\(\nu\),在原理篇的正则化章节咱们也讲到了,加上了正则化项,咱们的强学习器的迭代公式为\(f_{k}(x) = f_{k-1}(x) + \nu\alpha_kG_k(x) \)\(\nu\)的取值范围为$0 <; \nu \leq 1 \(。对于一样的训练集拟合效果,较小的\)\nu\(意味着咱们须要更多的弱学习器的迭代次数。一般咱们用步长和迭代最大次数一块儿来决定算法的拟合效果。因此这两个参数n_estimators和learning_rate要一块儿调参。通常来讲,能够从一个小一点的\)\nu$开始调参,默认是1。dom

 

3、AdaBoostClassifier和AdaBoostRegressor弱学习器参数

    这里咱们再讨论下AdaBoostClassifier和AdaBoostRegressor弱学习器参数,因为使用不一样的弱学习器,则对应的弱学习器参数各不相同。这里咱们仅仅讨论默认的决策树弱学习器的参数。即CART分类树DecisionTreeClassifier和CART回归树DecisionTreeRegressor。

    DecisionTreeClassifier和DecisionTreeRegressor的参数基本相似,在scikit-learn决策树算法类库使用小结这篇文章中咱们对这两个类的参数作了详细的解释。这里咱们只拿出调参数时须要尤为注意的最重要几个的参数再拿出来讲一遍:

    1) 划分时考虑的最大特征数max_features: 可使用不少种类型的值,默认是"None",意味着划分时考虑全部的特征数;若是是"log2"意味着划分时最多考虑\(log_2N\)个特征;若是是"sqrt"或者"auto"意味着划分时最多考虑\(\sqrt{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”,即不限制最大的叶子节点数。若是加了限制,算法会创建在最大叶子节点数内最优的决策树。若是特征很少,能够不考虑这个值,可是若是特征分红多的话,能够加以限制,具体的值能够经过交叉验证获得。

 

4、4. AdaBoostClassifier实战

    这里咱们用一个具体的例子来说解AdaBoostClassifier的使用。

    完整代码参见个人github: https://github.com/nickchen121/machinelearning/blob/master/ensemble-learning/adaboost-classifier.ipynb

    首先咱们载入须要的类库:

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)

    输出为:

Score: 0.913333333333
    也就是说拟合训练集数据的分数还不错。固然分数高并不必定好,由于可能过拟合。

    如今咱们将最大弱分离器个数从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)

    此时的输出为:

Score: 0.962222222222
    这印证了咱们前面讲的,弱分离器个数越多,则拟合程度越好,固然也越容易过拟合。

    如今咱们下降步长,将步长从上面的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)

    此时的输出为:

Score: 0.894444444444
    可见在一样的弱分类器的个数状况下,若是减小步长,拟合效果会降低。

    最后咱们看看当弱分类器个数为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)

    此时的输出为:

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

 

    以上就是scikit-learn Adaboost类库使用的一个总结,但愿能够帮到朋友们。

 

(欢迎转载,转载请注明出处。欢迎沟通交流: 微信:nickchen121)

相关文章
相关标签/搜索