[ML] 機器學習技法:第八講 Adaptive Boosting

ML:基礎技法學習
Package:scikit-learn
課程:機器學習技法
簡介:第八講 Adaptive Boosting

Adaptive Boosting (AdaBoost) Algorithm

  • u(1)=[1N,1N,,1N]
  • for t=1,2,,TT 自行決定
    1. A(D,u(t)) 得到 gt 利用 A 最小化 u(t)-weighted 0/1 error
      gtargminhH(n=1Nun(t)[ynh(xn)])
    2. 更新 u(t) 為 u(t+1),藉由
      (incorrect examples) [yngt(xn)]:un(t+1)un(t)t(correct examples) [yn=gt(xn)]:un(t+1)un(t) / tt=1ϵtϵt and ϵt=n=1Nun(t)[yngt(xn)]n=1Nun(t) 
    3. 計算 αt=ln(t)
  • 回傳 G(x)=sign(t=1Tαtgt(x))
首先,先考慮四個 data 的情況
D={(x1,y1),(x2,y2),(x3,y3),(x4,y4)} 利用 bootsrap 重新取樣
D~={(x1,y1),(x1,y1),(x2,y2),(x4,y4)} 如下圖,Ein 可以有兩種表示方法
右邊是常見的,左邊則是加上 weighted,表示次數,(t) 表示第幾輪
所以可將 bagging,視為在每一輪最小化 bootsrap-weighted error 並得到 gt
重新寫下更廣義的 Ein,且 un 可為小數,依其權重給於 1, 0.5, 2 等
Einu(h)=1Nn=1Nunerr(yn,h(xn)) 將此用在之前學過的演算法,SVM 的上限會改變如左圖,ξn 即是 err^SVM
可參考 [ML] 機器學習技法:第四講 soft-margin SVM
logistic regression 若使用 SGD 取樣機率會被改變如右圖,記得 un 其實跟資料個數有關
所以當 un 變大,不就等同被抽到的機率增加
可參考 [ML] 機器學習基石:第十一講 Linear Models for Classification
當得到的 gt 越不一樣時,那麼結合在一起時越好
那麼如何讓更新後的 gt+1gt 不一樣呢? gtargminhH(n=1Nun(t)[ynh(xn)])gt+1argminhH(n=1Nun(t+1)[ynh(xn)]) 換句話說,當 gtun(t+1) 表現不好時,不就表示 gt+1gt 不一樣
也就是說,當錯誤的比例跟隨機挑選沒啥兩樣時,等同 gt 在這些資料上根本就無任何作用
因是二分法,所以隨機機率為 12
為何不選擇最大錯誤率呢?也就是 1,因為在二分法中全錯不就是等於全對嗎?加個負號就好
如下算式,何時可為 12?當 t+1=t+1
n=1Nun(t+1)[yngt(xn)]n=1Nun(t+1)=t+1t+1+t+1=12t+1=n=1Nun(t+1)[yngt(xn)]t+1=n=1Nun(t+1)[yn=gt(xn)] 那麼如何讓 t+1=t+1
t+1=t+1n=1Nun(t+1)[yngt(xn)]=n=1Nun(t+1)[yn=gt(xn)]n=1Nαun(t)[yngt(xn)]=n=1Nβun(t)[yn=gt(xn)]αn=1Nun(t)[yngt(xn)]=βn=1Nun(t)[yn=gt(xn)]αt=βt 若讓 β=t & α=t,可達成兩者相同的要求
當然也可以是對錯比例 β=tt+t & α=tt+t
於是
ϵt=β=tt+t=n=1Nun(t)[yngt(xn)]n=1Nun(t)[yngt(xn)]+n=1Nun(t)[yn=gt(xn)]=n=1Nun(t)[yngt(xn)]n=1Nun(t)α=1β=1ϵtαt=βt(1ϵt)t=ϵtt1ϵtϵt(1ϵt)t=ϵtϵt(1ϵt)t1ϵtϵtt=ϵt1ϵtt1ϵtϵtt=ϵt1ϵttt=1ϵtϵttt=1tttn=1Nun(t)[yngt(xn)]=1tn=1Nun(t)[yn=gt(xn)]n=1Ntun(t)[yngt(xn)]=n=1N1tun(t)[yn=gt(xn)]n=1Nun(t+1)[yngt(xn)]=n=1Nun(t+1)[yn=gt(xn)]t+1=t+1
(incorrect examples ) [yngt(xn)]:un(t+1)un(t)t(correct examples ) [yn=gt(xn)]:un(t+1)un(t) / tϵt12 時,則 t1
所以理論上 t 應該都會 1,因這才表示比亂猜的好

但該如何決定 u1 呢?
因為希望原來的無權重的 Ein 也要很好,所以令所有 un1 都一樣
但如果令 un1=1,因 t1,更新時可能越來越大
故使 un1=1N

得到這些 gt,該如何組成 G(x) 呢?
uniform 不是個好選擇,由於演算法的刻意多樣性,所以 g2 對原先的 Ein 表現會很差
linear or non-linear,兩者皆可
但若可以邊跑邊決定,也許是個更好的方法
t 越大的,表示 gt 表現越好
所以從 t 下手,套入一個 monotonic function
αt=ln(t)G(x)=t=1T=sign(t=1Tαtgt(x)) 選擇 ln(t) 的原因
  • gt 很差的情況下,ϵt=12t=1αt=0
  • gt 很好的情況下,ϵt=0t=αt=
  • gt 還行的情況下,ϵt<12t>1αt>0

現實意義

Adaptive Boosting = 弱弱的 base learning algorithm A (學生)
                              + 最佳化 re-weighting factor t (老師)
                              + magic linear aggregation αt (整個班級的結論)
當老師在教小學生如何辨認圖片有無蘋果時,於是收集了十張蘋果照和十張其他水果照
並詢問各位學生的意見
有學生說,蘋果是圓的,但可以看到有些錯誤
所以將做對的縮小,錯誤的放大一點進而強調
此時,有學生說,蘋果也是紅的,但仍有些錯誤
同樣的,所以將做對的縮小,錯誤的放大一點
此時,有學生說,蘋果有的是綠色的,但仍有些錯誤
同樣的,所以將做對的縮小,錯誤的放大一點
最後,有學生說,蘋果有梗,於是得到了蘋果的所有特徵

Theoretical Guarantee of AdaBoost

Eout(G)Ein(G)+O(O(dVC(H)TlogT)dVC of all possible GlogNN) 第一項,當 T=O(logN)ϵtϵ<12,則可以令 Ein=0
第二項,因 T=O(logN) 有限,資料量 N 若夠多也可保證做得很小
最佳化原理可參考 [ML] 機器學習技法:第十一講 Gradient Boosted Decision Tree

未整理
Computer Science 511 Theoretical Machine Learning
Ein COS 511: Theoretical Machine Learning
Eout COS 511: Theoretical Machine Learning
A Short Introduction to Boosting
Adaboost通論上課版
Ein(G)=1Nn=1N[G(xi)yi]=1Nn=1N[sign(t=1Tαtgt(xi))yi][f(xi)=t=1Tαtgt(xi)]=1Nn=1N[sign(f(xi))yi][yif(xi)0eyif(xi)1]  1Nxi[G(x)yi]eyif(xi)=1Nxi[G(x)yi]eyit=1Tαtgt(xi)=1Nxi[G(x)yi]et=1Tyiαtgt(xi)=1Nxi[G(x)yi]t=1Teyiαtgt(xi)=xi[G(x)yi]1Nt=1Teyiαtgt(xi)=xi[G(x)yi]1Neyiα1g1(xi)t=2Teyiαtgt(xi)[1N=ui(1) and eyiαtgt(xi)={t gt(xi)yi1tgt(xi)=yi]=xi[G(x)yi]ui(2)t=2Teyiαtgt(xi)=xi[G(x)yi]ui(2)eyiα2g2(xi)t=3Teyiαtgt(xi)=xi[G(x)yi]ui(3)t=3Teyiαtgt(xi)=       =xi[G(x)yi]ui(T+1)[t0] n=1Nui(T+1)[iff ui(t) normalized] =1 VC dimension 可參考此篇[ML] 機器學習基石:第七講 The VC Dimension

AdaBoost-Stump

利用 decision stump,共有三個參數 (feature i, threshold θ, direction s)
hs,i,θ(x)=ssign(xiθ)
物理上的意義,即是切水平或垂直一刀
計算時間也不長,O(dNlogN),即是搜尋所有組合,並找到其最佳解
大概做法,對 feature 做排序 (N),再利用二分法 (logN),每個 feature 都做 (d)
而且可用來挑選合適的 feature,畢竟每個 decision stump,其實就只有單個 feature,那麼得到的 gt 自然是最佳 feature
這也是世界上第一個即時人臉辨識的程式所運用的演算法

程式碼

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3.  
  4. from sklearn.ensemble import AdaBoostClassifier
  5. from sklearn.tree import DecisionTreeClassifier
  6. from sklearn.datasets import make_gaussian_quantiles
  7.  
  8.  
  9. # 建立資料,為高斯分佈
  10. X1, y1 = make_gaussian_quantiles(cov=2.,
  11. n_samples=200, n_features=2,
  12. n_classes=2, random_state=1)
  13. X2, y2 = make_gaussian_quantiles(mean=(3, 3), cov=1.5,
  14. n_samples=300, n_features=2,
  15. n_classes=2, random_state=1)
  16. X = np.concatenate((X1, X2))
  17. y = np.concatenate((y1, - y2 + 1))
  18.  
  19. plot_colors = "br"
  20. plot_step = 0.02
  21. class_names = "AB"
  22.  
  23. # 畫分界圖資料
  24. xx1_min, xx1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
  25. xx2_min, xx2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
  26. xx1, xx2 = np.meshgrid(np.arange(xx1_min, xx1_max, plot_step),
  27. np.arange(xx2_min, xx2_max, plot_step))
  28.  
  29. N = 4
  30. f, axarr = plt.subplots(N//2, 2)
  31. for n in range(N):
  32. if n==0:
  33. T = 1
  34. else:
  35. T = (n+1) * 10
  36. # AdaBoosted decision stump
  37. bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=1, min_samples_leaf=1), n_estimators=T)
  38. # 訓練資料
  39. bdt.fit(X, y)
  40. # 畫分界圖
  41. Y = bdt.predict(np.c_[xx1.ravel(), xx2.ravel()])
  42. Y = Y.reshape(xx1.shape)
  43. axarr[n//2, n%2].contourf(xx1, xx2, Y, cmap=plt.cm.Paired)
  44.  
  45. # 畫出訓練資料
  46. for i, l, c in zip(range(2), class_names, plot_colors):
  47. idx = np.where(y == i)
  48. axarr[n//2, n%2].scatter(X[idx, 0], X[idx, 1],
  49. c=c, cmap=plt.cm.Paired,
  50. label="Class %s" % l)
  51. # 設定座標軸上下限
  52. axarr[n//2, n%2].set_xlim(xx1_min, xx1_max)
  53. axarr[n//2, n%2].set_ylim(xx2_min, xx2_max)
  54. if n==0:
  55. # 畫出 legend
  56. axarr[n//2, n%2].legend(loc='upper left')
  57. # 設定 title
  58. axarr[n//2, n%2].set_title('T={}'.format(T))
  59.  
  60. # 設定最上面的 title
  61. f.suptitle('AdaBoost-Stump')
  62. # 調整之間的空白高度
  63. plt.subplots_adjust(hspace=0.3)
  64. plt.show()

參考

sklearn.ensemble.AdaBoostClassifier
sklearn.ensemble.AdaBoostRegressor

留言