上節課我們主要開始介紹Aggregation Models,目的是將不同的hypothesis得到的g_t集合起來,利用集體智慧得到更好的預測模型G。首先我們介紹了Blending,blending是將已存在的所有g_t結合起來,可以是uniformly,linearly,或者non-linearly組合形式。然後,我們討論了在沒有那麼多g_t的情況下,使用bootstrap方式,從已有資料集中得到新的類似的資料集,從而得到不同的g_t。這種做法稱為bagging。本節課將繼續從這些概念出發,介紹一種新的演演算法。
1. Motivation of Boosting
我們先來看一個簡單的識別蘋果的例子,老師展示20張圖片,讓6歲孩子們通過觀察,判斷其中哪些圖片的內容是蘋果。從判斷的過程中推導如何解決二元分類問題的方法。
顯然這是一個監督式學習,20張圖片包括它的標籤都是已知的。首先,學生Michael回答說:所有的蘋果應該是圓形的。根據Michael的判斷,對應到20張圖片中去,大部分蘋果能被識別出來,但也有錯誤。其中錯誤包括有的蘋果不是圓形,而且圓形的水果也不一定是蘋果。如下圖所示:
上圖中藍色區域的圖片代表分類錯誤。顯然,只用“蘋果是圓形的”這一個條件不能保證分類效果很好。我們把藍色區域(分類錯誤的圖片)放大,分類正確的圖片縮小,這樣在接下來的分類中就會更加註重這些錯誤樣本。
然後,學生Tina觀察被放大的錯誤樣本和上一輪被縮小的正確樣本,回答說:蘋果應該是紅色的。根據Tina的判斷,得到的結果如下圖所示:
上圖中藍色區域的圖片一樣代表分類錯誤,即根據這個蘋果是紅色的條件,使得青蘋果和草莓、西紅柿都出現了判斷錯誤。那麼結果就是把這些分類錯誤的樣本放大化,其它正確的樣本縮小化。同樣,這樣在接下來的分類中就會更加註重這些錯誤樣本。
接著,學生Joey經過觀察又說:蘋果也可能是綠色的。根據Joey的判斷,得到的結果如下圖所示:
上圖中藍色區域的圖片一樣代表分類錯誤,根據蘋果是綠色的條件,使得圖中藍色區域都出現了判斷錯誤。同樣把這些分類錯誤的樣本放大化,其它正確的樣本縮小化,在下一輪判斷繼續對其修正。
後來,學生Jessica又發現:上面有梗的才是蘋果。得到如下結果:
經過這幾個同學的推論,蘋果被定義為:圓的,紅色的,也可能是綠色的,上面有梗。從一個一個的推導過程中,我們似乎得到一個較為準確的蘋果的定義。雖然可能不是非常準確,但是要比單一的條件要好得多。也就是說把所有學生對蘋果的定義融合起來,最終得到一個比較好的對蘋果的總體定義。這種做法就是我們本節課將要討論的演演算法。這些學生代表的就是簡單的hypotheses g_t,將所有g_t融合,得到很好的預測模型G。例如,二維平面上簡單的hypotheses(水平線和垂直線),這些簡單g_t最終組成的較複雜的分類線能夠較好地將正負樣本完全分開,即得到了好的預測模型。
所以,上個蘋果的例子中,不同的學生代表不同的hypotheses g_t;最終得到的蘋果總體定義就代表hypothesis G;而老師就代表演演算法A,指導學生的注意力集中到關鍵的例子中(錯誤樣本),從而得到更好的蘋果定義。其中的數學原理,我們下一部分詳細介紹。
2. Diversity by Re-weighting
在介紹這個演演算法之前,我們先來講一下上節課就介紹過的bagging。Bagging的核心是bootstrapping,通過對原始資料集D不斷進行bootstrap的抽樣動作,得到與D類似的資料集\hat{D}_t,每組\hat{D}_t都能得到相應的g_t,從而進行aggregation的操作。現在,假如包含四個樣本的D經過bootstrap,得到新的\hat{D}_t如下:
那麼,對於新的\hat{D}_t,把它交給base algorithm,找出E_{in}最小時對應的g_t,如下圖右邊所示。
E_{in}^{0/1}(h)=\frac14\sum_{n=1}^4[y\neq h(x)]
由於\hat{D}_t完全是D經過bootstrap得到的,其中樣本(x_1,y_1)出現2次,(x_2,y_2)出現1次,(x_3,y_3)出現0次,(x_4,y_4)出現1次。引入一個引數u_i來表示原D中第i個樣本在\hat{D}_t中出現的次數,如下圖左邊所示。
E_{in}^u(h)=\frac14\sum_{n=1}^4u_n^{(t)}\cdot [y_n\neq h(x)]
引數u相當於是權重因子,當\hat{D}_t中第i個樣本出現的次數越多的時候,那麼對應的u_i越大,表示在error function中對該樣本的懲罰越多。所以,從另外一個角度來看bagging,它其實就是通過bootstrap的方式,來得到這些u_i值,作為犯錯樣本的權重因子,再用base algorithn最小化包含u_i的error function,得到不同的g_t。這個error function被稱為bootstrap-weighted error。
這種演算法叫做Weightd Base Algorithm,目的就是最小化bootstrap-weighted error。
其實,這種weightd base algorithm我們之前就介紹過類似的演算法形式。例如在soft-margin SVM中,我們引入允許犯錯的項,同樣可以將每個點的error乘以權重因子u_n。加上該項前的引數C,經過QP,最終得到0\leq \alpha_n\leq Cu_n,有別於之前介紹的0\leq \alpha_n\leq C。這裡的u_n相當於每個犯錯的樣本的懲罰因子,並會反映到\alpha_n的範圍限定上。
同樣在logistic regression中,同樣可以對每個犯錯誤的樣本乘以相應的u_n,作為懲罰因子。u_n表示該錯誤點出現的次數,u_n越大,則對應的懲罰因子越大,則在最小化error時就應該更加重視這些點。
其實這種example-weighted learning,我們在機器學習基石課程第8次筆記中就介紹過class-weighted的思想。二者道理是相通的。
知道了u的概念後,我們知道不同的u組合經過base algorithm得到不同的g_t。那麼如何選取u,使得到的g_t之間有很大的不同呢?之所以要讓所有的g_t差別很大,是因為上節課aggregation中,我們介紹過g_t越不一樣,其aggregation的效果越好,即每個人的意見越不相同,越能運用集體的智慧,得到好的預測模型。
為了得到不同的g_t,我們先來看看g_t和g_{t+1}是怎麼得到的:
如上所示,g_t是由u_n^{t}得到的,g_{t+1}是由u_n^{(t+1)}得到的。如果g_t這個模型在使用u_n^{(t+1)}的時候得到的error很大,即預測效果非常不好,那就表示由u_n^{(t+1)}計算的g_{t+1}會與g_t有很大不同。而g_{t+1}與g_t差異性大正是我們希望看到的。
怎麼做呢?方法是利用g_t在使用u_n^{(t+1)}的時候表現很差的條件,越差越好。如果在g_t作用下,u_n^{(t+1)}中的表現(即error)近似為0.5的時候,表明g_t對u_n^{(t+1)}的預測分類沒有什麼作用,就像拋硬幣一樣,是隨機選擇的。這樣的做法就能最大限度地保證g_{t+1}會與g_t有較大的差異性。其數學表示式如下所示:
乍看上面這個式子,似乎不好求解。但是,我們對它做一些等價處理,其中分式中分子可以看成g_t作用下犯錯誤的點,而分母可以看成犯錯的點和沒有犯錯誤的點的集合,即所有樣本點。其中犯錯誤的點和沒有犯錯誤的點分別用橘色方塊和綠色圓圈表示:
要讓分式等於0.5,顯然只要將犯錯誤的點和沒有犯錯誤的點的數量調成一樣就可以了。也就是說,在g_t作用下,讓犯錯的u_n^{(t+1)}數量和沒有犯錯的u_n^{(t+1)}數量一致就行(包含權重u_n^{t+1})。一種簡單的方法就是利用放大和縮小的思想(本節課開始引入識別蘋果的例子中提到的放大圖片和縮小圖片就是這個目的),將犯錯誤的u_n^{t}和沒有犯錯誤的u_n^{t}做相應的乘積操作,使得二者值變成相等。例如u_n^{t} of incorrect為1126,u_n^{t} of correct為6211,要讓u_n^{(t+1)}中錯誤比例正好是0.5,可以這樣做,對於incorrect u_n^{(t+1)}:
u_n^{(t+1)}\leftarrow u_n^{(t)}\cdot 6211
對於correct u_n^{(t+1)}:
u_n^{(t+1)}\leftarrow u_n^{(t)}\cdot 1126
或者利用犯錯的比例來做,令weighted incorrect rate和weighted correct rate分別設為\frac{1126}{7337}和\frac{6211}{7337}。一般求解方式是令犯錯率為\epsilon_t,在計算u_n^{(t+1)}的時候,u_n^{t}分別乘以(1-\epsilon_t)和\epsilon_t。
3. Adaptive Boosting Algorithm
上一部分,我們介紹了在計算u_n^{(t+1)}的時候,u_n^{t}分別乘以(1-\epsilon_t)和\epsilon_t。下面將構造一個新的尺度因子:
\diamond t=\sqrt{\frac{1-\epsilon_t}{\epsilon_t}}
那麼引入這個新的尺度因子之後,對於錯誤的u_n^{t},將它乘以\diamond t;對於正確的u_n^{t},將它除以\diamond t。這種操作跟之前介紹的分別乘以(1-\epsilon_t)和\epsilon_t的效果是一樣的。之所以引入\diamond t是因為它告訴我們更多的物理意義。因為如果\epsilon_t\leq\frac12,得到\diamond t\geq1,那麼接下來錯誤的u_n^{t}與\diamond t的乘積就相當於把錯誤點放大了,而正確的u_n^{t}與\diamond t的相除就相當於把正確點縮小了。這種scale up incorrect和scale down correct的做法與本節課開始介紹的學生識別蘋果的例子中放大錯誤的圖片和縮小正確的圖片是一個原理,讓學生能夠將注意力更多地放在犯錯誤的點上。通過這種scaling-up incorrect的操作,能夠保證得到不同於g_t的g_{t+1}。
值得注意的是上述的結論是建立在\epsilon_t\leq\frac12的基礎上,如果\epsilon_t\geq\frac12,那麼就做相反的推論即可。關於\epsilon_t\geq\frac12的情況,我們稍後會進行說明。
從這個概念出發,我們可以得到一個初步的演演算法。其核心步驟是每次迭代時,利用\diamond t=\sqrt{\frac{1-\epsilon_t}{\epsilon_t}}把u_t更新為u_{t+1}。具體迭代步驟如下:
但是,上述步驟還有兩個問題沒有解決,第一個問題是初始的u^{(1)}應為多少呢?一般來說,為了保證第一次E_{in}最小的話,設u^{(1)}=\frac1N即可。這樣最開始的g_1就能由此推導。第二個問題,最終的G(x)應該怎麼求?是將所有的g(t)合併uniform在一起嗎?一般來說並不是這樣直接uniform求解,因為g_{t+1}是通過g_t得來的,二者在E_{in}上的表現差別比較大。所以,一般是對所有的g(t)進行linear或者non-linear組合來得到G(t)。
接下來的內容,我們將對上面的第二個問題進行探討,研究一種演算法,將所有的g(t)進行linear組合。方法是計算g(t)的同時,就能計算得到其線性組合係數\alpha_t,即aggregate linearly on the fly。這種演算法使最終求得g_{t+1}的時候,所有g_t的線性組合係數\alpha也求得了,不用再重新計算\alpha了。這種Linear Aggregation on the Fly演算法流程為:
如何在每次迭代的時候計算\alpha_t呢?我們知道\alpha_t與\epsilon_t是相關的:\epsilon_t越小,對應的\alpha_t應該越大,\epsilon_t越大,對應的\alpha_t應該越小。又因為\diamond t與\epsilon_t是正相關的,所以,\alpha_t應該是\diamond t的單調函式。我們構造\alpha_t為:
\alpha_t=ln(\diamond t)
\alpha_t這樣取值是有物理意義的,例如當\epsilon_t=\frac12時,error很大,跟擲骰子這樣的隨機過程沒什麼兩樣,此時對應的\diamond t=1,\alpha_t=0,即此g_t對G沒有什麼貢獻,權重應該設為零。而當\epsilon_t=0時,沒有error,表示該g_t預測非常準,此時對應的\diamond t=\infty,\alpha_t=\infty,即此g_t對G貢獻非常大,權重應該設為無窮大。
這種演算法被稱為Adaptive Boosting。它由三部分構成:base learning algorithm A,re-weighting factor \diamond t和linear aggregation \alpha_t。這三部分分別對應於我們在本節課開始介紹的例子中的Student,Teacher和Class。
綜上所述,完整的adaptive boosting(AdaBoost)Algorithm流程如下:
從我們之前介紹過的VC bound角度來看,AdaBoost演算法理論上滿足:
上式中,E_{out}(G)的上界由兩部分組成,一項是E_{in}(G),另一項是模型複雜度O(*)。模型複雜度中d_{vc}(H)是g_t的VC Dimension,T是迭代次數,可以證明G的d_{vc}服從O(d_{vc}(H)\cdot Tlog\ T)。
對這個VC bound中的第一項E_{in}(G)來說,有一個很好的性質:如果滿足\epsilon_t\leq \epsilon,則經過T=O(log\ N)次迭代之後,E_{in}(G)能減小到等於零的程度。而當N很大的時候,其中第二項也能變得很小。因為這兩項都能變得很小,那麼整個E_{out}(G)就能被限定在一個有限的上界中。
其實,這種性質也正是AdaBoost演算法的精髓所在。只要每次的\epsilon_t\leq \epsilon,即所選擇的矩g比亂猜的表現好一點點,那麼經過每次迭代之後,矩g的表現都會比原來更好一些,逐漸變強,最終得到E_{in}=0且E_{out}很小。
4. Adaptive Boosting in Action
上一小節我們已經介紹了選擇一個“弱弱”的演算法A(\epsilon_t\leq \epsilon,比亂猜好就行),就能經過多次迭代得到E_{in}=0。我們稱這種形式為decision stump模型。下面介紹一個例子,來看看AdaBoost是如何使用decision stump解決實際問題的。
如下圖所示,二維平面上分佈一些正負樣本點,利用decision stump來做切割。
第一步:
第二步:
第三步:
第四步:
第五步:
可以看到,經過5次迭代之後,所有的正負點已經被完全分開了,則最終得到的分類線為:
另外一個例子,對於一個相對比較複雜的資料集,如下圖所示。它的分界線從視覺上看應該是一個sin波的形式。如果我們再使用AdaBoost演算法,通過decision stump來做切割。在迭代切割100次後,得到的分界線如下所示。
可以看出,AdaBoost-Stump這種非線性模型得到的分界線對正負樣本有較好的分離效果。
課程中還介紹了一個AdaBoost-Stump在人臉識別方面的應用:
5. 總結
本節課主要介紹了Adaptive Boosting。首先通過講一個老師教小學生識別蘋果的例子,來引入Boosting的思想,即把許多“弱弱”的hypotheses合併起來,變成很強的預測模型。然後重點介紹這種演算法如何實現,關鍵在於每次迭代時,給予樣本不同的係數u,宗旨是放大錯誤樣本,縮小正確樣本,得到不同的小矩g。並且在每次迭代時根據錯誤\epsilon值的大小,給予不同g_t不同的權重。最終由不同的g_t進行組合得到整體的預測模型G。實際證明,Adaptive Boosting能夠得到有效的預測模型。
註明:
文章中所有的圖片均來自臺灣大學林軒田《機器學習技法》課程
更多AI資源請關注公眾號:AI有道(ID:redstonewill)