1. 程式人生 > >AdaBoost演算法詳解與python實現

AdaBoost演算法詳解與python實現

1. 概述

1.1 整合學習

目前存在各種各樣的機器學習演算法,例如SVM、決策樹、感知機等等。但是實際應用中,或者說在打比賽時,成績較好的隊伍幾乎都用了整合學習(ensemble learning)的方法。整合學習的思想,簡單來講,就是“三個臭皮匠頂個諸葛亮”。整合學習通過結合多個學習器(例如同種演算法但是引數不同,或者不同演算法),一般會獲得比任意單個學習器都要好的效能,尤其是在這些學習器都是"弱學習器"的時候提升效果會很明顯。

弱學習器指的是效能不太好的學習器,比如一個準確率略微超過50%的二分類器。

下面看看西瓜書對此做的一個簡單理論分析。
考慮一個二分類問題 、真實函式 以及 個相互獨立且犯錯概率均為

的個體學習器(或者稱基學習器) 。我們用簡單的投票進行整合學習,即分類結果取半數以上的基學習器的結果:

由Hoeffding不等式知,整合學習後的犯錯(即過半數基學習器犯錯)概率滿足

 

指出,當犯錯概率獨立的基學習器個數 很大時,整合後的犯錯概率接近0,這也很符合直觀想法: 大多數人同時犯錯的概率是比較低的。

就如上面加粗字型強調的,以上推論全部建立在基學習器犯錯相互獨立的情況下,但實際中這些學習器不可能相互獨立,而如何讓基學習器變得“相對獨立一些”,也即增加這些基學習器的多樣性,正是整合學習需要考慮的主要問題。

按照每個基學習器之間是否存在依賴關係可以將整合學習分為兩類:

  1. 基學習器之間存在強依賴關係,一系列基學習器需要序列生成,代表演算法是Boosting;
  2. 基學習器之間不存在強依賴關係,一系列基學習器可並行生成,代表演算法是Bagging和隨機森林。

Boosting系列演算法裡最著名演算法主要有AdaBoost和提升樹(Boosting tree)系列演算法,本文只介紹最具代表性的AdaBoost。提升樹、Bagging以及隨機森林不在本文介紹範圍內,有時間了再另外介紹。

1.2 Boosting

Boosting指的是一類整合方法,其主要思想就是將弱的基學習器提升(boost)為強學習器。具體步驟如下:

  1. 先用每個樣本權重相等的訓練集訓練一個初始的基學習器;
  2. 根據上輪得到的學習器對訓練集的預測表現情況調整訓練集中的樣本權重(例如提高被錯分類的樣本的權重使之在下輪訓練中得到更多的關注), 然後據此訓練一個新的基學習器;
  3. 重複2直到得到 個基學習器,最終的整合結果是 個基學習器的組合。

由此看出,Boosting演算法是一個序列的過程。

Boosting演算法簇中最著名的就是AdaBoost,下文將會詳細介紹。

2. AdaBoost原理

2.1 基本思想

對於1.2節所述的Boosting演算法步驟,需要回答兩個問題:

  1. 如何調整每一輪的訓練集中的樣本權重?
  2. 如何將得到的 個學習器組合成最終的學習器?

AdaBoost(Adaptive Boosting, 自適應增強)演算法採取的方法是:

  1. 提高上一輪被錯誤分類的樣本的權值,降低被正確分類的樣本的權值;
  2. 線性加權求和。誤差率小的基學習器擁有較大的權值,誤差率大的基學習器擁有較小的權值。

下面先給出AdaBoost演算法具體實現步驟,至於演算法解釋(為什麼要這樣做)將在下一大節闡述。

2.2 演算法步驟

考慮如下形式的二分類(標準AdaBoost演算法只適用於二分類任務)訓練資料集: 其中 是一個含有 個元素的列向量, 即 ; 是標量,

Adaboost演算法具體步驟如下:

  1. 初始化樣本的權重

  1. ,重複以下操作得到 個基學習器:
    (1) 按照樣本權重分佈 訓練資料得到第 個基學習器:

     (2) 計算 在加權訓練資料集上的分類誤差率:

上式中 是指示函式,考慮更加周全的AdaBoost演算法在這一步還應該判斷是否滿足基本條件(例如生成的基學習器是否比隨機猜測好), 如果不滿足,則當前基學習器被拋棄,學習過程提前終止。

   (3) 計算 的係數(即最終整合使用的的基學習器的權重):

(4) 更新訓練樣本的權重,其中 是規範化因子,目的是為了使 的所有元素和為1。

  1. 構建最終的分類器線性組合

   得到最終的分類器為

由式 知,當基學習器 的誤差率 時, ,並且 隨著 的減小而增大,即分類誤差率越小的基學習器在最終整合時佔比也越大。即AdaBoost能夠適應各個弱分類器的訓練誤差率,這也是它的名稱中"適應性(Adaptive)"的由來。

由式 知, 被基學習器 誤分類的樣本權值得以擴大,而被正確分類的樣本的權值被得以縮小。

需要注意的是式 中所有的 的和並不為1(因為沒有做一個softmax操作), 的符號決定了所預測的類,其絕對值代表了分類的確信度。

3. AdaBoost演算法解釋

有沒有想過為什麼AdaBoost演算法長上面這個樣子,例如為什麼 要用式 那樣計算?本節將探討這個問題。

3.1 前向分步演算法

在解釋AdaBoost演算法之前,先來看看前向分步演算法。就以AdaBoost演算法的最終模型表示式為例:

可以看到這是一個“加性模型(additive model)”。我們希望這個模型在訓練集上的經驗誤差最小,即

通常這是一個複雜的優化問題。前向分步演算法求解這一優化問題的思想就是: 因為最終模型是一個加性模型,如果能從前往後,每一步只學習一個基學習器 及其權重 , 不斷迭代得到最終的模型,那麼就可以簡化問題複雜度。具體的,當我們經過 輪迭代得到了最優模型 時,因為

所以此輪優化目標就為 求解上式即可得到第 個基分類器 及其權重
這樣,前向分步演算法就通過不斷迭代求得了從 的所有基分類器及其權重,問題得到了解決。

3.2 AdaBoost演算法證明

上一小結介紹的前向分步演算法逐一學習基學習器,這一過程也即AdaBoost演算法逐一學習基學習器的過程。本節就證明前向分步演算法的損失函式是指數損失函式(exponential loss function)時,AdaBoost學習的具體步驟就如2.2節所示。

指數損失函式即 ,指數損失函式是分類任務原本0/1損失函式的一致(consistent)替代損失函式(損失函式的上界,優化指數損失函式,等價於優化AdaBoost的損失函式)。由於指數損失函式有更好的數學性質,例如處處可微,所以我們用它替代0/1損失作為優化目標。

將指數損失函式代入式 ,優化目標就為 因為 與優化變數 無關,如果令

這個 其實就是2.2節中歸一化之前的權重 ,那麼式 等價於

我們分兩步來求解式 所示的優化問題的最優解 :

  • 對任意的 , 求 上式將指數函式換成指示函式是因為前面說的指數損失函式和0/1損失函式是一致等價的。

式子 所示的優化問題其實就是AdaBoost演算法的基學習器的學習過程,即2.2節的步驟2(1),得到的 是使第 輪加權訓練資料分類誤差最小的基分類器。

  • 求解

將式子 中的目標函式展開 注:為了簡潔,上式子中的 被略去了 被略去了下標 ,下同;將上式對 求導並令導數為0,即 解得 其中, 是分類誤差率: 如果式子 中的 歸一化成和為1的話那麼式 也就和2.2節式 一模一樣了,進一步地也有上面的 也就是2.2節的
最後來看看每一輪樣本權值的更新,由 可得 如果將上式進行歸一化成和為1的話就和與2.2節中 完全相同了。

如果某個樣本被正確分類,那麼ωm+1,im,iexp(-αm)/sum(ωm,iexp(-αm)),錯誤則為ωm+1,im,iexp(αm)/sum(ωm,iexp(αm))。

由此可見,2.2節所述的AdaBoost演算法步驟是可以經過嚴密推導得來的。總結一下,本節推導有如下關鍵點:

  • AdaBoost演算法是一個加性模型,將其簡化成前向分步演算法求解;
  • 將0/1損失函式用數學性質更好的指數損失函式替代(這裡可以替換的原因是,(1/N)∑i=1...Nexp(yiƒ(xi)是損失函式(1/N)∑i=1...NI(yi!=G(xi))的上界,當G(xi)≠yi時,yi*f(xi)<0,因而exp(-yi*f(xi))≥1,可以用指數損失函式來代替原來的函式,便於運算。

 

一個例子

(下面的例子與解法來源於李航的《統計學習方法》)

例 給定如下表所示訓練資料。假設個體學習器由x(輸入)和y(輸出)產生,其閾值v(判定正反例的分界線)使該分類器在訓練資料集上分類誤差率最低。(y=1為正例,y=-1為反例)

第一個個體學習器:

我們首先認為 (i=1,2,…,10)的權重是一樣的,即每一個數據同等重要。(權重是用來計算誤差的)



 

(a)在權值分佈為 的訓練資料上,閾值v取2.5(紅線)時分類誤差率最低(此時x=6,7,8的資料被錯分為反例,誤差為它們的權重之和 =0.1+0.1+0.1=0.3,誤差率小於 才有意義),故個體學習器為

 

(b)根據誤差 計算係數 =0.4236(公式: ,可以發現只有當 < 時, >0,這樣個體學習器才是有意義的)

 

(c)更新訓練資料的權值分佈(公式: , 是為了保證每次權值總和為1)

 

(通過指數損失函式 調整權重,分類正確的降低權重( 同號則 ),分類錯誤的增加權重):

(權重之和始終為1)

 

 

可以看到x=6,7,8的資料的權重變大了,而其他資料的權重降低了,這是希望能把之前經常分類錯誤(經常分類錯誤會出現權重不斷變大)的資料能在下一個個體學習器分類正確(記住:權重是用來計算誤差的,為了降低誤差,選擇閾值時會傾向把權重大的分類正確)

 


整合學習器 (第一次整合,只有一個個體學習器)在訓練資料集上有3個誤分類點

 

第二個個體學習器:



(a)在權值分佈為 的訓練資料上,閾值v取8.5時分類誤差率最低(此時x=3,4,5的資料被錯分為正例,誤差為它們的權重之和 =0.07143+0.07143+0.07143=0.2143,誤差率降低了!),故個體學習器為

(b)根據誤差 計算係數

(c)更新訓練資料的權值分佈(在 的基礎上調整 ,分類正確的降低權重,分類錯誤的增加權重):


對比 可以看到x=3,4,5的資料的權重變大了,而其他權重降低了。


(注意:x<2.5時,也<8.5)

分類器 在訓練資料集上有3個誤分類點

 

第三個個體學習器:



(a)在權值分佈為 的訓練資料上,閾值v取5.5時分類誤差率最低( =0.1820,誤差率又降低了!x=0,1,2,9被分類錯誤),故個體學習器為

 

(b)根據誤差 計算係數

(c)更新訓練資料的權值分佈:



(自己算一算吧)

最終結果:

分類器 在訓練資料集上有0個誤分類點(amazing!)

 

程式碼稍後提