scikit-learn Adaboost類庫使用小結



本文系轉載,原文鏈接爲   http://www.cnblogs.com/pinard/p/6136914.html


  在集成學習之Adaboost算法原理小結中,我們對Adaboost的算法原理做了一個總結。這裏我們就從實用的角度對scikit-learn中Adaboost類庫的使用做一個小結,重點對調參的注意事項做一個總結。

1. Adaboost類庫概述

    scikit-learn中Adaboost類庫比較直接,就是AdaBoostClassifier和AdaBoostRegressor兩個,從名字就可以看出AdaBoostClassifier用於分類,AdaBoostRegressor用於迴歸。

    AdaBoostClassifier使用了兩種Adaboost分類算法的實現,SAMME和SAMME.R。而AdaBoostRegressor則使用了我們原理篇裏講到的Adaboost迴歸算法的實現,即Adaboost.R2。

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

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個樣本的誤差的處理,即:如果是線性誤差,則            eki=|yi−Gk(xi)|Ek;如果是平方誤差,則               eki=(yi−Gk(xi))2Ek2,如果是指數誤差,則            eki=1−exp(−yi+Gk(xi))Ek)   Ek爲訓練集上的最大誤差         Ek=max|yi−Gk(xi)|i=1,2...m

 

     4) n_estimators: AdaBoostClassifier和AdaBoostRegressor都有,就是我們的弱學習器的最大迭代次數,或者說最大的弱學習器的個數。一般來說n_estimators太小,容易欠擬合,n_estimators太大,又容易過擬合,一般選擇一個適中的數值。默認是50。在實際調參的過程中,我們常常將n_estimators和下面介紹的參數learning_rate一起考慮。

 

    5) learning_rate:  AdaBoostClassifier和AdaBoostRegressor都有,即每個弱學習器的權重縮減係數 ν,在原理篇的正則化章節我們也講到了,加上了正則化項,我們的強學習器的迭代公式爲         fk(x)=fk−1(x)+ναkGk(x) ν的取值範圍爲 0<ν≤1。對於同樣的訓練集擬合效果,較小的 ν意味着我們需要更多的弱學習器的迭代次數。通常我們用步長和迭代最大次數一起來決定算法的擬合效果。所以這兩個參數n_estimators和learning_rate要一起調參。一般來說,可以從一個小一點的 ν開始調參,默認是1。

 

3. AdaBoostClassifier和AdaBoostRegressor弱學習器參數

    這裏我們再討論下AdaBoostClassifier和AdaBoostRegressor弱學習器參數,由於使用不同的弱學習器,則對應的弱學習器參數各不相同。這裏我們僅僅討論默認的決策樹弱學習器的參數。即CART分類樹DecisionTreeClassifier和CART迴歸樹DecisionTreeRegressor。

    DecisionTreeClassifier和DecisionTreeRegressor的參數基本類似,在scikit-learn決策樹算法類庫使用小結這篇文章中我們對這兩個類的參數做了詳細的解釋。這裏我們只拿出調參數時需要尤其注意的最重要幾個的參數再拿出來說一遍:

    1) 劃分時考慮的最大特徵數max_features: 可以使用很多種類型的值,默認是"None",意味着劃分時考慮所有的特徵數;如果是"log2"意味着劃分時最多考慮   log2N個特徵;如果是"sqrt"或者"auto"意味着劃分時最多考慮      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的使用。

    首先我們載入需要的類庫:

複製代碼
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類庫使用的一個總結,希望可以幫到朋友們。

 

發佈了4 篇原創文章 · 獲贊 13 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章