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。git

    當咱們對Adaboost調參時,主要要對兩部份內容進行調參,第一部分是對咱們的Adaboost的框架進行調參, 第二部分是對咱們選擇的弱分類器進行調參。二者相輔相成。下面就對Adaboost的兩個類:AdaBoostClassifier和AdaBoostRegressor從這兩部分作一個介紹。github

2. 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使用了和咱們的原理篇裏二元分類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$dom

 

     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。post

 

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. AdaBoostClassifier實戰

    這裏咱們用一個具體的例子來說解AdaBoostClassifier的使用。

    完整代碼參見個人github: https://github.com/ljpzzz/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類庫使用的一個總結,但願能夠幫到朋友們。

 

(歡迎轉載,轉載請註明出處。歡迎溝通交流: liujianping-ok@163.com) 

相關文章
相關標籤/搜索