ML:基礎技法學習
Package:scikit-learn
課程:
機器學習技法
簡介:第八講 Adaptive Boosting
Adaptive Boosting (AdaBoost) Algorithm
- for , 自行決定
- 從 得到 利用 最小化 -weighted 0/1 error
- 更新 為 ,藉由
- 計算
- 回傳
首先,先考慮四個 data 的情況
利用 bootsrap 重新取樣
如下圖, 可以有兩種表示方法
右邊是常見的,左邊則是加上 weighted,表示次數, 表示第幾輪
所以可將 bagging,視為在每一輪最小化 bootsrap-weighted error 並得到
重新寫下更廣義的 ,且 可為小數,依其權重給於 1, 0.5, 2 等
將此用在之前學過的演算法,SVM 的上限會改變如左圖, 即是
可參考
[ML] 機器學習技法:第四講 soft-margin SVM
logistic regression 若使用 SGD 取樣機率會被改變如右圖,記得 其實跟資料個數有關
所以當 變大,不就等同被抽到的機率增加
可參考
[ML] 機器學習基石:第十一講 Linear Models for Classification
當得到的 越不一樣時,那麼結合在一起時越好
那麼如何讓更新後的 與 不一樣呢?
換句話說,當 在 表現不好時,不就表示 與 不一樣
也就是說,當錯誤的比例跟隨機挑選沒啥兩樣時,等同 在這些資料上根本就無任何作用
因是二分法,所以隨機機率為
為何不選擇最大錯誤率呢?也就是 1,因為在二分法中全錯不就是等於全對嗎?加個負號就好
如下算式,何時可為 ?當
那麼如何讓 ?
若讓 & ,可達成兩者相同的要求
當然也可以是對錯比例 &
於是
故
當 時,則 時
所以理論上 應該都會 ,因這才表示比亂猜的好
但該如何決定 呢?
因為希望原來的無權重的 也要很好,所以令所有 都一樣
但如果令 ,因 ,更新時可能越來越大
故使
得到這些 ,該如何組成 呢?
uniform 不是個好選擇,由於演算法的刻意多樣性,所以 對原先的 表現會很差
linear or non-linear,兩者皆可
但若可以邊跑邊決定,也許是個更好的方法
越大的,表示 表現越好
所以從 下手,套入一個 monotonic function
選擇 的原因
- 在 很差的情況下,
- 在 很好的情況下,
- 在 還行的情況下,
現實意義
Adaptive Boosting = 弱弱的 base learning algorithm (學生)
+ 最佳化 re-weighting factor (老師)
+ magic linear aggregation (整個班級的結論)
當老師在教小學生如何辨認圖片有無蘋果時,於是收集了十張蘋果照和十張其他水果照
並詢問各位學生的意見
有學生說,蘋果是圓的,但可以看到有些錯誤
所以將做對的縮小,錯誤的放大一點進而強調
此時,有學生說,蘋果也是紅的,但仍有些錯誤
同樣的,所以將做對的縮小,錯誤的放大一點
此時,有學生說,蘋果有的是綠色的,但仍有些錯誤
同樣的,所以將做對的縮小,錯誤的放大一點
最後,有學生說,蘋果有梗,於是得到了蘋果的所有特徵
Theoretical Guarantee of AdaBoost
第一項,當 且 ,則可以令
第二項,因 有限,資料量 N 若夠多也可保證做得很小
AdaBoost-Stump
利用 decision stump,共有三個參數 (feature i, threshold , direction )
物理上的意義,即是切水平或垂直一刀
計算時間也不長,,即是搜尋所有組合,並找到其最佳解
大概做法,對 feature 做排序 (),再利用二分法 (),每個 feature 都做 ()
而且可用來挑選合適的 feature,畢竟每個 decision stump,其實就只有單個 feature,那麼得到的 自然是最佳 feature
這也是世界上第一個即時人臉辨識的程式所運用的演算法
程式碼
- import numpy as np
- import matplotlib.pyplot as plt
-
- from sklearn.ensemble import AdaBoostClassifier
- from sklearn.tree import DecisionTreeClassifier
- from sklearn.datasets import make_gaussian_quantiles
-
-
- # 建立資料,為高斯分佈
- X1, y1 = make_gaussian_quantiles(cov=2.,
- n_samples=200, n_features=2,
- n_classes=2, random_state=1)
- X2, y2 = make_gaussian_quantiles(mean=(3, 3), cov=1.5,
- n_samples=300, n_features=2,
- n_classes=2, random_state=1)
- X = np.concatenate((X1, X2))
- y = np.concatenate((y1, - y2 + 1))
-
- plot_colors = "br"
- plot_step = 0.02
- class_names = "AB"
-
- # 畫分界圖資料
- xx1_min, xx1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
- xx2_min, xx2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
- xx1, xx2 = np.meshgrid(np.arange(xx1_min, xx1_max, plot_step),
- np.arange(xx2_min, xx2_max, plot_step))
-
- N = 4
- f, axarr = plt.subplots(N//2, 2)
- for n in range(N):
- if n==0:
- T = 1
- else:
- T = (n+1) * 10
- # AdaBoosted decision stump
- bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=1, min_samples_leaf=1), n_estimators=T)
- # 訓練資料
- bdt.fit(X, y)
-
- # 畫分界圖
- Y = bdt.predict(np.c_[xx1.ravel(), xx2.ravel()])
- Y = Y.reshape(xx1.shape)
- axarr[n//2, n%2].contourf(xx1, xx2, Y, cmap=plt.cm.Paired)
-
- # 畫出訓練資料
- for i, l, c in zip(range(2), class_names, plot_colors):
- idx = np.where(y == i)
- axarr[n//2, n%2].scatter(X[idx, 0], X[idx, 1],
- c=c, cmap=plt.cm.Paired,
- label="Class %s" % l)
- # 設定座標軸上下限
- axarr[n//2, n%2].set_xlim(xx1_min, xx1_max)
- axarr[n//2, n%2].set_ylim(xx2_min, xx2_max)
-
- if n==0:
- # 畫出 legend
- axarr[n//2, n%2].legend(loc='upper left')
- # 設定 title
- axarr[n//2, n%2].set_title('T={}'.format(T))
-
- # 設定最上面的 title
- f.suptitle('AdaBoost-Stump')
- # 調整之間的空白高度
- plt.subplots_adjust(hspace=0.3)
- plt.show()
參考
sklearn.ensemble.AdaBoostClassifier
sklearn.ensemble.AdaBoostRegressor
留言
張貼留言