公號:碼農充電站pro
主頁:https://codeshellme.github.iohtml
在機器學習算法中,有一種算法叫作集成算法,AdaBoost 算法是集成算法的一種。咱們先來看下什麼是集成算法。node
一般,一個 Boss 在作一項決定以前,會聽取多個 Leader 的意見。集成算法就是這個意思,它的基本含義就是集衆算法之所長。python
前面已經介紹過許多算法,每種算法都有優缺點。那麼是否能夠將這些算法組合起來,共同作一項決定呢?答案是確定的。這就誕生了集成算法(Ensemble Methods)。git
集成算法的基本架構以下:github
算法的組合有多種形式,好比將不一樣的算法集成起來,或者將同一種算法以不一樣的形式集成起來。web
常見的集成算法有四大類:算法
多個算法以不一樣的方式能夠組合成集成算法,若是再深刻探究的話,不一樣的集成方法也能夠組合起來:shell
對於集成算法的集成,這裏再也不過多介紹。api
bagging和 boosting是兩個比較著名的集成算法。架構
bagging 算法
bagging 算法是將一個原始數據集隨機抽樣成 N 個新的數據集。而後將這N 個新的數據集做用於同一個機器學習算法,從而獲得 N 個模型,最終集成一個綜合模型。
在對新的數據進行預測時,須要通過這 N 個模型(每一個模型互不依賴干擾)的預測(投票),最終綜合 N 個投票結果,來造成最後的預測結果。
boosting 算法
boosting 算法的含義爲提高學習,它將多個弱分類器組合起來造成一個強分類器。
boosting 算法是將一個原始數據集使用同一個算法迭代學習 N 次,每次迭代會給數據集中的樣本分配不一樣的權重。
分類正確的樣本會在下一次迭代中下降權重,而分類錯誤的樣本會在下一次迭代中提升權重,這樣作的目的是,使得算法可以對其不擅長(分類錯誤)的數據不斷的增強提高學習,最終使得算法的成功率愈來愈高。
每次迭代都會訓練出一個新的帶有權重的模型,迭代到必定的次數或者最終模型的錯誤率足夠低時,迭代中止。最終集成一個強大的綜合模型。
在對新的數據進行預測時,須要通過這 N 個模型的預測,每一個模型的預測結果會帶有一個權重值,最終綜合 N 個模型結果,來造成最後的預測結果。
boosting 算法中每一個模型的權重是不相等的,而bagging 算法中每一個模型的權重是相等的。
AdaBoost 算法是很是流行的一種 boosting 算法,它的全稱爲 Adaptive Boosting,即自適應提高學習。
AdaBoost 算法由Freund 和 Schapire 於1995 年提出。這兩位做者寫了一篇關於AdaBoost 的簡介論文,這應該是關於AdaBoost 算法的最權威的資料了。爲了防止連接丟失,我將論文下載了,放在了這裏。
AdaBoost 算法 和 SVM 算法被不少人認爲是監督學習中最強大的兩種算法。
AdaBoost 算法的運行過程以下:
這個過程當中,咱們假設 x 爲樣本,Gi(x) 爲第 i 輪訓練出的模型,ai 爲 Gi(x) 的權重,一共迭代 n 輪,那麼最終模型 G(x) 的計算公式爲:
模型權重 ai 的計算公式以下,其中 ei 爲第 i 輪模型的錯誤率:
咱們用 Dk+1 表明第 k+1 輪的樣本的權重集合,用 Wk+1,1 表明第 k+1 輪中第1個樣本的權重, Wk+1,N 表明第 k+1 輪中第 N 個樣本的權重,用公式表示爲:
樣本權重 Wk+1,i 的計算公式爲:
其中:
下面咱們以一個二分類問題,來看一下AdaBoost 算法的計算過程。
假設咱們有10 個樣本數據,X 爲特徵集,Y 爲目標集,以下:
X | Y |
---|---|
0 | 1 |
1 | 1 |
2 | 1 |
3 | -1 |
4 | -1 |
5 | -1 |
6 | 1 |
7 | 1 |
8 | 1 |
9 | -1 |
假設有三個分類器,分別以2.5,5.5,8.5將數據分界:
簡單看下其分佈圖:
根據這三個分類器,咱們能夠算出每一個樣本對應的值:
X | Y | f1(x) | f2(x) | f3(x) |
---|---|---|---|---|
0 | 1 | 1 | -1 |
1 |
1 | 1 | 1 | -1 |
1 |
2 | 1 | 1 | -1 |
1 |
3 | -1 | -1 | -1 | 1 |
4 | -1 | -1 | -1 | 1 |
5 | -1 | -1 | -1 | 1 |
6 | 1 | -1 |
1 | 1 |
7 | 1 | -1 |
1 | 1 |
8 | 1 | -1 |
1 | 1 |
9 | -1 | -1 | 1 |
-1 |
上面表格中,對於每一個分類器分類錯誤的數據,我進行了標紅
。
第一輪
將每一個樣本的權重初始化爲0.1:
(0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1)
根據 D1 計算每一個分類器的錯誤率:
選擇錯誤率最小的分類器做爲第1輪的分類器,由於 f1(x)和 f3(x) 的錯誤率都是0.3,因此能夠任意選一個,好比咱們選 f1(x),因此 G1(x) = f1(x)。
計算 G1(x) 的權重 a1(x):
(1/2) * log((1-0.3)/0.3)
= 0.42這裏的
log
以e
爲底。
計算第2輪的樣本權重D2,首先須要根據Zk 的公式來計算 Z1,先計算 -a1yiG1(xi) ,以下:
序號 i | yi | G1(xi) | -a1yiG1(xi) |
---|---|---|---|
1 | 1 | 1 | -0.42 x 1 x 1 => -0.42 |
2 | 1 | 1 | -0.42 x 1 x 1 => -0.42 |
3 | 1 | 1 | -0.42 x 1 x 1 => -0.42 |
4 | -1 | -1 | -0.42 x -1 x -1 => -0.42 |
5 | -1 | -1 | -0.42 x -1 x -1 => -0.42 |
6 | -1 | -1 | -0.42 x -1 x -1 => -0.42 |
7 | 1 | -1 | -0.42 x 1 x -1 => 0.42 |
8 | 1 | -1 | -0.42 x 1 x -1 => 0.42 |
9 | 1 | -1 | -0.42 x 1 x -1 => 0.42 |
10 | -1 | -1 | -0.42 x -1 x -1 => -0.42 |
那麼 Z1 = 0.1 * (7 * e^-0.42 + 3 * e^0.42)
= 0.92
再根據樣本權重的計算公式能夠得出:
(0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.1666, 0.1666, 0.1666, 0.0715)
第二輪
根據 D2 計算每一個分類器的錯誤率:
選擇錯誤率最小的分類器做爲第2輪的分類器,因此 G2(x) = f3(x)。
計算 G2(x) 的權重 a2(x):
(1/2) * log((1-0.2145)/0.2145)
= 0.65計算第3輪每一個樣本的權重:
(0.0455,0.0455,0.0455,0.1667, 0.1667,0.01667,0.1060, 0.1060, 0.1060, 0.0455)
這裏省略了D3 的計算過程,其計算過程與D2 同樣。
第三輪
根據 D3 計算每一個分類器的錯誤率:
選擇錯誤率最小的分類器做爲第3輪的分類器,因此 G3(x) = f2(x)。
計算 G3(x) 的權重 a3(x):
(1/2) * log((1-0.182)/0.182)
= 0.75若是咱們只迭代三輪,那麼最終的模型 G(x) = 0.42G1(x) + 0.65G2(x) + 0.75G3(x)。
有了最終的模型G(x),咱們根據G(x) 來計算每一個樣本對應的值:
G0 = 0.42 + 0.65 - 0.75 = 0.32 => 1 G1 = 0.42 + 0.65 - 0.75 = 0.32 => 1 G2 = 0.42 + 0.65 - 0.75 = 0.32 => 1 G3 = -0.42 + 0.65 - 0.75 = -0.52 => -1 G4 = -0.42 + 0.65 - 0.75 = -0.52 => -1 G5 = -0.42 + 0.65 - 0.75 = -0.52 => -1 G6 = -0.42 + 0.65 + 0.75 = 0.98 => 1 G7 = -0.42 + 0.65 + 0.75 = 0.98 => 1 G8 = -0.42 + 0.65 + 0.75 = 0.98 => 1 G9 = -0.42 - 0.65 + 0.75 = -0.32 => -1
由於本例是一個二分類問題,因此對於值大於 0 均取 1,值小於 0 均取 -1。
最終能夠獲得以下表格:
X | Y | G(x) |
---|---|---|
0 | 1 | 1 |
1 | 1 | 1 |
2 | 1 | 1 |
3 | -1 | -1 |
4 | -1 | -1 |
5 | -1 | -1 |
6 | 1 | 1 |
7 | 1 | 1 |
8 | 1 | 1 |
9 | -1 | -1 |
能夠看到通過提高學習後的模型的準確率提升到了100%。
固然對於實際問題,準確率基本達不到100%。
以上就是一個簡化版的 AdaBoost 算法的計算過程。
本例的原型出自《統計學習方法 · 李航》
sklearn 庫的 ensemble 模塊實現了一系列的集成算法,對於集成方法的介紹,能夠參看這裏。
AdaBoost 算法便可用於分類問題,也可用於迴歸問題:
來看下 AdaBoostClassifier 類的原型:
AdaBoostClassifier( base_estimator=None, n_estimators=50, learning_rate=1.0, algorithm='SAMME.R', random_state=None)
其參數含義:
AdaBoostClassifier
默認使用的是 DecisionTreeClassifier(max_depth=1)
。AdaBoostRegressor
默認使用的是 DecisionTreeRegressor(max_depth=3)
。再來看下 AdaBoostRegressor 類的原型:
AdaBoostRegressor( base_estimator=None, n_estimators=50, learning_rate=1.0, loss='linear', random_state=None)
能夠看到,迴歸和分類的參數基本一致,而回歸算法裏沒有 algorithm 參數,但多了 loss 參數。
loss 參數表明損失函數,用於(每次迭代後)更新樣本的權重,其共有 3 種選擇,分別爲:
接下來,咱們看下如何用 AdaBoost 算法進行迴歸分析。
以前在文章《決策樹算法-實戰篇-鳶尾花及波士頓房價預測》中,咱們介紹過波士頓房價數據集,這裏再也不對數據自己進行過多介紹,下面咱們用 AdaBoost 算法來分析該數據集。
首先加載數據集:
from sklearn.datasets import load_boston boston = load_boston() features = boston.data # 特徵集 prices = boston.target # 目標集
將數據拆分紅訓練集和測試集:
from sklearn.model_selection import train_test_split train_x, test_x, train_y, test_y = train_test_split( features, prices, test_size=0.25, random_state=33)
構建 AdaBoost 迴歸模型:
from sklearn.ensemble import AdaBoostRegressor regressor = AdaBoostRegressor() # 均採用默認參數 regressor.fit(train_x, train_y) # 擬合模型
使用模型進行預測:
pred_y = regressor.predict(test_x)
評價模型準確率:
from sklearn.metrics import mean_squared_error mse = mean_squared_error(test_y, pred_y) print "AdaBoost 均方偏差 = ", round(mse, 2) # 18.57
base_estimator_
屬性是基學習器,也就是訓練以前的模型:
>>> regressor.base_estimator_ DecisionTreeRegressor(criterion='mse', max_depth=3, max_features=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, presort=False, random_state=None, splitter='best')
estimators_
屬性是通過訓練以後的全部弱學習器,有 50 個:
>>> len(regressor.estimators_) 50
feature_importances_
屬性中存儲了每一個特徵的重要性:
>>> regressor.feature_importances_ array([0.02104728, 0. , 0.00304314, 0. , 0.00891602, 0.2825294 , 0.00438134, 0.17308669, 0.00929782, 0.07457966, 0.02250937, 0.00592025, 0.39468902])
estimator_weights_
屬性是每一個弱學習器的權重:
>>> regressor.estimator_weights_ array([2.39259487, 2.02119506, 1.68364189, 0.71892012, 2.01966649, 1.03178435, 1.14573926, 2.15335207, 1.62996738, 1.39576421, 1.42582945, 0.55214963, 1.17953337, 0.20934333, 0.3022646 , 1.73484417, 1.36590071, 0.27471584, 0.97297267, 0.21729445, 1.97061649, 0.91072652, 1.95231025, 0.11764431, 1.19301792, 0.21629414, 1.57477075, 1.23626619, 1.21423494, 0.24063141, 0.08265621, 0.17198137, 0.58300858, 0.72722721, 2.07974547, 0.61855751, 1.98179632, 0.5886063 , 0.18646107, 0.38176832, 1.11993353, 1.81984396, 1.06785584, 0.45475221, 1.85522596, 0.29177236, 1.0699074 , 1.79358974, 1.37771849, 0.15698322])
estimator_errors_
屬性是每一個弱學習器的錯誤率:
>>> regressor.estimator_errors_ array([0.08373912, 0.11699548, 0.15661382, 0.32763082, 0.11715348, 0.26273832, 0.24126819, 0.1040184 , 0.16383483, 0.19848913, 0.19374934, 0.36536582, 0.23513611, 0.44785447, 0.42500398, 0.149969 , 0.20328296, 0.43174973, 0.27428838, 0.44588913, 0.12232269, 0.28685119, 0.12430167, 0.4706228 , 0.23271962, 0.44613629, 0.17153735, 0.22508658, 0.22895259, 0.44013076, 0.47934771, 0.45711032, 0.35824061, 0.32580349, 0.1110811 , 0.3501096 , 0.12112748, 0.3569547 , 0.45351932, 0.40570047, 0.24602361, 0.1394526 , 0.25581106, 0.38823148, 0.13526048, 0.42757002, 0.25542069, 0.14263317, 0.20137567, 0.46083459])
咱們將每一個弱學習器的權重和錯誤率使用 Matplotlib 畫出折線圖以下:
能夠看到弱學習器的錯誤率與權重成反比:
下面分別使用決策樹迴歸和KNN 迴歸來分析波士頓數據集,從而對比這三種算法的準確度。
使用決策樹迴歸
代碼以下
from sklearn.tree import DecisionTreeRegressor # 構建決策樹 dec_regressor = DecisionTreeRegressor() # 擬合決策樹 dec_regressor.fit(train_x, train_y) # 預測數據 pred_y = dec_regressor.predict(test_x) # 計算模型準確度 mse = mean_squared_error(test_y, pred_y) print "決策樹均方偏差 = ", round(mse, 2)
使用KNN 迴歸
代碼以下
from sklearn.neighbors import KNeighborsRegressor # 構建 KNN 模型 knn_regressor = KNeighborsRegressor() # 擬合模型 knn_regressor.fit(train_x, train_y) # 預測數據 pred_y = knn_regressor.predict(test_x) # 計算模型準確度 mse = mean_squared_error(test_y, pred_y) print "KNN 均方偏差 = ", round(mse, 2)
運行代碼得出的結果是:
咱們知道均方偏差越小,準確率越高,因此 AdaBoost 算法在這三種算法中表現最好。
理想狀況下,迭代次數越多,最終模型的錯誤率應該越低,下面咱們來探究一下是不是這樣?
sklearn 中的 make_hastie_10_2 函數用於生成二分類數據。
咱們用該函數生成12000 個數據,取前2000 個做爲測試集,其他爲訓練集:
from sklearn import datasets X, Y = datasets.make_hastie_10_2(n_samples=12000, random_state=1) train_x, train_y = X[2000:], Y[2000:] test_x, test_y = X[:2000], Y[:2000]
構建 AdaBoost 分類模型,迭代次數爲 500:
from sklearn.ensemble import AdaBoostClassifier IterationN = 500 ada = AdaBoostClassifier(n_estimators=IterationN) ada.fit(train_x, train_y)
對測試數據進行預測,並統計錯誤率:
from sklearn.metrics import zero_one_loss errs = [] for pred_y in ada.staged_predict(test_x): err = zero_one_loss(pred_y, test_y) errs.append(err)
staged_predict
方法用於預測每一輪迭代後輸入樣本的預測值,因此模型迭代了多少次,該方法就會返回多少次預測結果,其返回的就是分別迭代1,2,3...N 次的預測結果。
zero_one_loss 方法用於計算錯誤率。
errs
列表中存儲了每次迭代的錯誤率。
用 Matplotlib 畫出錯誤率折線圖:
import matplotlib.pyplot as plt plt.plot(range(1, IterationN+1), errs, label='AdaBoost Error Rate', color='orange') plt.legend(loc='upper right', fancybox=True) # 顯示圖例 plt.show()
經過上圖能夠看出:
建議:
在實際應用中,能夠經過畫這種折線圖的方式,來判斷模型應該迭代多少次。固然也要考慮時間成本,迭代次數越多,時間成本也會越高。
sklearn 官方文檔中也有一個這樣的例子,你能夠參考這裏。
須要注意的是,若是數據集不夠好的話,錯誤率在達到必定值後有可能會反彈,即迭代次數若是再增長,錯誤率可能會增高,這時候就是過擬合現象。
本篇文章主要介紹瞭如下內容:
(本節完。)
推薦閱讀:
歡迎關注做者公衆號,獲取更多技術乾貨。