1. 程式人生 > >adaboost演算法原理及sklearn中使用辦法

adaboost演算法原理及sklearn中使用辦法

  轉自https://www.cnblogs.com/pinard/p/6136914.html,感謝作者

整合學習原理小結中,我們講到了整合學習按照個體學習器之間是否存在依賴關係可以分為兩類,第一個是個體學習器之間存在強依賴關係,另一類是個體學習器之間不存在強依賴關係。前者的代表演算法就是是boosting系列演算法。在boosting系列演算法中, Adaboost是最著名的演算法之一。Adaboost既可以用作分類,也可以用作迴歸。本文就對Adaboost演算法做一個總結。

1. 回顧boosting演算法的基本原理

    在整合學習原理小結中,我們已經講到了boosting算法系列的基本思想,如下圖:

    從圖中可以看出,Boosting演算法的工作機制是首先從訓練集用初始權重訓練出一個弱學習器1,根據弱學習的學習誤差率表現來更新訓練樣本的權重,使得之前弱學習器1學習誤差率高的訓練樣本點的權重變高,使得這些誤差率高的點在後面的弱學習器2中得到更多的重視。然後基於調整權重後的訓練集來訓練弱學習器2.,如此重複進行,直到弱學習器數達到事先指定的數目T,最終將這T個弱學習器通過集合策略進行整合,得到最終的強學習器。  

    不過有幾個具體的問題Boosting演算法沒有詳細說明。

    1)如何計算學習誤差率e?

    2) 如何得到弱學習器權重係數αα?

    3)如何更新樣本權重D?

    4) 使用何種結合策略?

    只要是boosting大家族的演算法,都要解決這4個問題。那麼Adaboost是怎麼解決的呢?

2. Adaboost演算法的基本思路

    我們這裡講解Adaboost是如何解決上一節這4個問題的。

    假設我們的訓練集樣本是

T={(x,y1),(x2,y2),...(xm,ym)}T={(x,y1),(x2,y2),...(xm,ym)}

    訓練集的在第k個弱學習器的輸出權重為

D(k)=(wk1,wk2,...wkm);w1i=1m;i=1,2...mD(k)=(wk1,wk2,...wkm);w1i=1m;i=1,2...m

    首先我們看看Adaboost的分類問題。

    分類問題的誤差率很好理解和計算。由於多元分類是二元分類的推廣,這裡假設我們是二元分類問題,輸出為{-1,1},則第k個弱分類器Gk(x)Gk(x)在訓練集上的加權誤差率為

ek=P(Gk(xi)≠yi)=∑i=1mwkiI(Gk(xi)≠yi)ek=P(Gk(xi)≠yi)=∑i=1mwkiI(Gk(xi)≠yi)

    接著我們看弱學習器權重係數,對於二元分類問題,第k個弱分類器Gk(x)Gk(x)的權重係數為

αk=12log1−ekekαk=12log1−ekek

    為什麼這樣計算弱學習器權重係數?從上式可以看出,如果分類誤差率ekek越大,則對應的弱分類器權重係數αkαk越小。也就是說,誤差率小的弱分類器權重係數越大。具體為什麼採用這個權重係數公式,我們在講Adaboost的損失函式優化時再講。

    第三個問題,更新更新樣本權重D。假設第k個弱分類器的樣本集權重係數為D(k)=(wk1,wk2,...wkm)D(k)=(wk1,wk2,...wkm),則對應的第k+1個弱分類器的樣本集權重係數為

wk+1,i=wkiZKexp(−αkyiGk(xi))wk+1,i=wkiZKexp(−αkyiGk(xi))

    這裡ZkZk是規範化因子

Zk=∑i=1mwkiexp(−αkyiGk(xi))Zk=∑i=1mwkiexp(−αkyiGk(xi))

    從wk+1,iwk+1,i計算公式可以看出,如果第i個樣本分類錯誤,則yiGk(xi)<0yiGk(xi)<0,導致樣本的權重在第k+1個弱分類器中增大,如果分類正確,則權重在第k+1個弱分類器中減少.具體為什麼採用樣本權重更新公式,我們在講Adaboost的損失函式優化時再講。

    最後一個問題是集合策略。Adaboost分類採用的是加權平均法,最終的強分類器為

f(x)=sign(∑k=1KαkGk(x))f(x)=sign(∑k=1KαkGk(x))

    接著我們看看Adaboost的迴歸問題。由於Adaboost的迴歸問題有很多變種,這裡我們以Adaboost R2演算法為準。

    我們先看看回歸問題的誤差率的問題,對於第k個弱學習器,計算他在訓練集上的最大誤差

Ek=max|yi−Gk(xi)|i=1,2...mEk=max|yi−Gk(xi)|i=1,2...m

    然後計算每個樣本的相對誤差

eki=|yi−Gk(xi)|Ekeki=|yi−Gk(xi)|Ek

    這裡是誤差損失為線性時的情況,如果我們用平方誤差,則eki=(yi−Gk(xi))2E2keki=(yi−Gk(xi))2Ek2,如果我們用的是指數誤差,則eki=1−exp(−yi+Gk(xi))Ek)eki=1−exp(−yi+Gk(xi))Ek)

    最終得到第k個弱學習器的 誤差率

ek=∑i=1mwkiekiek=∑i=1mwkieki

    我們再來看看如何得到弱學習器權重係數αα。這裡有:

αk=ek1−ekαk=ek1−ek

    對於更新更新樣本權重D,第k+1個弱學習器的樣本集權重係數為

wk+1,i=wkiZkα1−ekikwk+1,i=wkiZkαk1−eki

    這裡ZkZk是規範化因子

Zk=∑i=1mwkiα1−ekikZk=∑i=1mwkiαk1−eki

    最後是結合策略,和分類問題一樣,採用的也是加權平均法,最終的強迴歸器為

f(x)=∑k=1K(ln1αk)Gk(x)f(x)=∑k=1K(ln1αk)Gk(x)

3. AdaBoost分類問題的損失函式優化

    剛才上一節我們講到了分類Adaboost的弱學習器權重係數公式和樣本權重更新公式。但是沒有解釋選擇這個公式的原因,讓人覺得是魔法公式一樣。其實它可以從Adaboost的損失函式推匯出來。

    從另一個角度講, Adaboost是模型為加法模型,學習演算法為前向分步學習演算法,損失函式為指數函式的分類問題。

    模型為加法模型好理解,我們的最終的強分類器是若干個弱分類器加權平均而得到的。

    前向分步學習演算法也好理解,我們的演算法是通過一輪輪的弱學習器學習,利用前一個弱學習器的結果來更新後一個弱學習器的訓練集權重。也就是說,第k-1輪的強學習器為

fk−1(x)=∑i=1k−1αiGi(x)fk−1(x)=∑i=1k−1αiGi(x)

    而第k輪的強學習器為

fk(x)=∑i=1kαiGi(x)fk(x)=∑i=1kαiGi(x)

    上兩式一比較可以得到

fk(x)=fk−1(x)+αkGk(x)fk(x)=fk−1(x)+αkGk(x)

    可見強學習器的確是通過前向分步學習演算法一步步而得到的。

    Adaboost損失函式為指數函式,即定義損失函式為

argminα,G∑i=1mexp(−yifk(x))argmin⏟α,G∑i=1mexp(−yifk(x))

    利用前向分步學習演算法的關係可以得到損失函式為

(αk,Gk(x))=argminα,G∑i=1mexp[(−yi)(fk−1(x)+αG(x))](αk,Gk(x))=argmin⏟α,G∑i=1mexp[(−yi)(fk−1(x)+αG(x))]

    令w′ki=exp(−yifk−1(x))wki′=exp(−yifk−1(x)), 它的值不依賴於α,Gα,G,因此與最小化無關,僅僅依賴於fk−1(x)fk−1(x),隨著每一輪迭代而改變。

    將這個式子帶入損失函式,損失函式轉化為

(αk,Gk(x))=argminα,G∑i=1mw′kiexp[−yiαG(x)](αk,Gk(x))=argmin⏟α,G∑i=1mwki′exp[−yiαG(x)]

    首先,我們求Gk(x)Gk(x).,可以得到

Gk(x)=argminG∑i=1mw′kiI(yi≠G(xi))Gk(x)=argmin⏟G∑i=1mwki′I(yi≠G(xi))

    將Gk(x)Gk(x)帶入損失函式,並對αα求導,使其等於0,則就得到了

αk=12log1−ekekαk=12log1−ekek

    其中,ekek即為我們前面的分類誤差率。

ek=∑i=1mw′kiI(yi≠G(xi))∑i=1mw′ki=∑i=1mwkiI(yi≠G(xi))ek=∑i=1mwki′I(yi≠G(xi))∑i=1mwki′=∑i=1mwkiI(yi≠G(xi))

    最後看樣本權重的更新。利用fk(x)=fk−1(x)+αkGk(x)fk(x)=fk−1(x)+αkGk(x)和w′ki=exp(−yifk−1(x))wki′=exp(−yifk−1(x)),即可得:

w′k+1,i=w′kiexp[−yiαkGk(x)]wk+1,i′=wki′exp[−yiαkGk(x)]

    這樣就得到了我們第二節的樣本權重更新公式。

4. AdaBoost二元分類問題演算法流程

    這裡我們對AdaBoost二元分類問題演算法流程做一個總結。

    輸入為樣本集T={(x,y1),(x2,y2),...(xm,ym)}T={(x,y1),(x2,y2),...(xm,ym)},輸出為{-1, +1},弱分類器演算法, 弱分類器迭代次數K。

    輸出為最終的強分類器f(x)f(x)

    1) 初始化樣本集權重為

D(1)=(w11,w12,...w1m);w1i=1m;i=1,2...mD(1)=(w11,w12,...w1m);w1i=1m;i=1,2...m

    2) 對於k=1,2,...K:

      a) 使用具有權重DkDk的樣本集來訓練資料,得到弱分類器Gk(x)Gk(x)

      b)計算Gk(x)Gk(x)的分類誤差率

ek=P(Gk(xi)≠yi)=∑i=1mwkiI(Gk(xi)≠yi)ek=P(Gk(xi)≠yi)=∑i=1mwkiI(Gk(xi)≠yi)

      c) 計算弱分類器的係數

αk=12log1−ekekαk=12log1−ekek

      d) 更新樣本集的權重分佈

wk+1,i=wkiZKexp(−αkyiGk(xi))i=1,2,...mwk+1,i=wkiZKexp(−αkyiGk(xi))i=1,2,...m

        這裡ZkZk是規範化因子

Zk=∑i=1mwkiexp(−αkyiGk(xi))Zk=∑i=1mwkiexp(−αkyiGk(xi))

    3) 構建最終分類器為:

f(x)=sign(∑k=1KαkGk(x))f(x)=sign(∑k=1KαkGk(x))

    對於Adaboost多元分類演算法,其實原理和二元分類類似,最主要區別在弱分類器的係數上。比如Adaboost SAMME演算法,它的弱分類器的係數

αk=12log1−ekek+log(R−1)αk=12log1−ekek+log(R−1)

    其中R為類別數。從上式可以看出,如果是二元分類,R=2,則上式和我們的二元分類演算法中的弱分類器的係數一致。

5. Adaboost迴歸問題的演算法流程

    這裡我們對AdaBoost迴歸問題演算法流程做一個總結。AdaBoost迴歸演算法變種很多,下面的演算法為Adaboost R2迴歸演算法過程。

    輸入為樣本集T={(x,y1),(x2,y2),...(xm,ym)}T={(x,y1),(x2,y2),...(xm,ym)},,弱學習器演算法, 弱學習器迭代次數K。

    輸出為最終的強學習器f(x)f(x)

    1) 初始化樣本集權重為

D(1)=(w11,w12,...w1m);w1i=1m;i=1,2...mD(1)=(w11,w12,...w1m);w1i=1m;i=1,2...m

    2) 對於k=1,2,...K:

      a) 使用具有權重DkDk的樣本集來訓練資料,得到弱學習器Gk(x)Gk(x)

      b) 計算訓練集上的最大誤差

Ek=max|yi−Gk(xi)|i=1,2...mEk=max|yi−Gk(xi)|i=1,2...m

      c) 計算每個樣本的相對誤差:

        如果是線性誤差,則eki=|yi−Gk(xi)|Ekeki=|yi−Gk(xi)|Ek;

        如果是平方誤差,則eki=(yi−Gk(xi))2E2keki=(yi−Gk(xi))2Ek2

        如果是指數誤差,則eki=1−exp(−yi+Gk(xi))Ek)eki=1−exp(−yi+Gk(xi))Ek)        

      d) 計算迴歸誤差率

ek=∑i=1mwkiekiek=∑i=1mwkieki

      c) 計算弱學習器的係數

αk=ek1−ekαk=ek1−ek

      d) 更新樣本集的權重分佈為

wk+1,i=wkiZkα1−ekikwk+1,i=wkiZkαk1−eki

        這裡ZkZk是規範化因子

Zk=∑i=1mwkiα1−ekikZk=∑i=1mwkiαk1−eki

    3) 構建最終強學習器為:

f(x)=∑k=1K(ln1αk)Gk(x)f(x)=∑k=1K(ln1αk)Gk(x)

6. Adaboost演算法的正則化

    為了防止Adaboost過擬合,我們通常也會加入正則化項,這個正則化項我們通常稱為步長(learning rate)。定義為νν,對於前面的弱學習器的迭代

fk(x)=fk−1(x)+αkGk(x)fk(x)=fk−1(x)+αkGk(x)

    如果我們加上了正則化項,則有

fk(x)=fk−1(x)+ναkGk(x)fk(x)=fk−1(x)+ναkGk(x)

    νν的取值範圍為0<ν≤10<ν≤1。對於同樣的訓練集學習效果,較小的νν意味著我們需要更多的弱學習器的迭代次數。通常我們用步長和迭代最大次數一起來決定演算法的擬合效果。

7. Adaboost小結

    到這裡Adaboost就寫完了,前面有一個沒有提到,就是弱學習器的型別。理論上任何學習器都可以用於Adaboost.但一般來說,使用最廣泛的Adaboost弱學習器是決策樹和神經網路。對於決策樹,Adaboost分類用了CART分類樹,而Adaboost迴歸用了CART迴歸樹。

    這裡對Adaboost演算法的優缺點做一個總結。

    Adaboost的主要優點有:

    1)Adaboost作為分類器時,分類精度很高

    2)在Adaboost的框架下,可以使用各種迴歸分類模型來構建弱學習器,非常靈活。

    3)作為簡單的二元分類器時,構造簡單,結果可理解。

    4)不容易發生過擬合

    Adaboost的主要缺點有:

    1)對異常樣本敏感,異常樣本在迭代中可能會獲得較高的權重,影響最終的強學習器的預測準確性。

 在整合學習之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)|Ekeki=|yi−Gk(xi)|Ek;如果是平方誤差,則eki=(yi−Gk(xi))2E2keki=(yi−Gk(xi))2Ek2,如果是指數誤差,則eki=1−exp(−yi+Gk(xi))Ek)eki=1−exp(−yi+Gk(xi))Ek),EkEk為訓練集上的最大誤差Ek=max|yi−Gk(xi)|i=1,2...mEk=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)fk(x)=fk−1(x)+ναkGk(x)。νν的取值範圍為0<ν≤10<ν≤1。對於同樣的訓練集擬合效果,較小的νν意味著我們需要更多的弱學習器的迭代次數。通常我們用步長和迭代最大次數一起來決定演算法的擬合效果。所以這兩個引數n_estimators和learning_rate要一起調參。一般來說,可以從一個小一點的νν開始調參,預設是1。

3. AdaBoostClassifier和AdaBoostRegressor弱學習器引數

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

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

    1) 劃分時考慮的最大特徵數max_features: 可以使用很多種型別的值,預設是"None",意味著劃分時考慮所有的特徵數;如果是"log2"意味著劃分時最多考慮log2Nlog2N個特徵;如果是"sqrt"或者"auto"意味著劃分時最多考慮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”,即不限制最大的葉子節點數。如果加了限制,演算法會建立在最大葉子節點數內最優的決策樹。如果特徵不多,可以不考慮這個值,但是如果特徵分成多的話,可以加以限制,具體的值可以通過交叉驗證得到。

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才能達到類似的擬合效果。