機器學習經典算法之AdaBoost

1、引言html

在數據挖掘中,分類算法能夠說是核心算法,其中 AdaBoost 算法與隨機森林算法同樣都屬於分類算法中的集成算法。算法

/*請尊重做者勞動成果,轉載請標明原文連接:*/框架

/* https://www.cnblogs.com/jpcflyer/p/11268859.html * /dom

集成的含義就是集思廣益,博取衆長,當咱們作決定的時候,咱們先聽取多個專家的意見,再作決定。集成算法一般有兩種方式,分別是投票選舉(bagging)和再學習(boosting)。投票選舉的場景相似把專家召集到一個會議桌前,當作一個決定的時候,讓 K 個專家(K 個模型)分別進行分類,而後選擇出現次數最多的那個類做爲最終的分類結果。再學習至關於把 K 個專家(K 個分類器)進行加權融合,造成一個新的超級專家(強分類器),讓這個超級專家作判斷。函數

因此你能看出來,投票選舉和再學習仍是有區別的。Boosting 的含義是提高,它的做用是每一次訓練的時候都對上一次的訓練進行改進提高,在訓練的過程當中這 K 個「專家」之間是有依賴性的,當引入第 K 個「專家」(第 K 個分類器)的時候,其實是對前 K-1 個專家的優化。而 bagging 在作投票選舉的時候能夠並行計算,也就是 K 個「專家」在作判斷的時候是相互獨立的,不存在依賴性。工具

 

2、 AdaBoost 的工做原理學習

AdaBoost 的英文全稱是 Adaptive Boosting,中文含義是自適應提高算法。它由 Freund 等人於 1995 年提出,是對 Boosting 算法的一種實現。測試

什麼是 Boosting 算法呢?Boosting 算法是集成算法中的一種,同時也是一類算法的總稱。這類算法經過訓練多個弱分類器,將它們組合成一個強分類器,也就是咱們俗話說的「三個臭皮匠,頂個諸葛亮」。爲何要這麼作呢?由於臭皮匠好訓練,諸葛亮卻很差求。所以要打造一個諸葛亮,最好的方式就是訓練多個臭皮匠,而後讓這些臭皮匠組合起來,這樣每每能夠獲得很好的效果。這就是 Boosting 算法的原理。優化

 

 

我能夠用上面的圖來表示最終獲得的強分類器,你能看出它是經過一系列的弱分類器根據不一樣的權重組合而成的。spa

假設弱分類器爲 G_{i}(x) ,它在強分類器中的權重 α_{i} ,那麼就能夠得出強分類器 f(x):

有了這個公式,爲了求解強分類器,你會關注兩個問題:

1.如何獲得弱分類器,也就是在每次迭代訓練的過程當中,如何獲得最優弱分類器?

2.每一個弱分類器在強分類器中的權重是如何計算的?

咱們先來看下第二個問題。實際上在一個由 K 個弱分類器中組成的強分類器中,若是弱分類器的分類效果好,那麼權重應該比較大,若是弱分類器的分類效果通常,權重應該下降。因此咱們須要基於這個弱分類器對樣本的分類錯誤率來決定它的權重,用公式表示就是:

其中 e_{i} 表明第 i 個分類器的分類錯誤率。

而後咱們再來看下第一個問題,如何在每次訓練迭代的過程當中選擇最優的弱分類器?

實際上,AdaBoost 算法是經過改變樣本的數據分佈來實現的。AdaBoost 會判斷每次訓練的樣本是否正確分類,對於正確分類的樣本,下降它的權重,對於被錯誤分類的樣本,增長它的權重。再基於上一次獲得的分類準確率,來肯定此次訓練樣本中每一個樣本的權重。而後將修改過權重的新數據集傳遞給下一層的分類器進行訓練。這樣作的好處就是,經過每一輪訓練樣本的動態權重,可讓訓練的焦點集中到難分類的樣本上,最終獲得的弱分類器的組合更容易獲得更高的分類準確率。

咱們能夠用 D_{k+1} 表明第 k+1 輪訓練中,樣本的權重集合,其中 W_{k+1,1} 表明第 k+1 輪中第一個樣本的權重,以此類推 W_{k+1,N} 表明第 k+1 輪中第 N 個樣本的權重,所以用公式表示爲:

第 k+1 輪中的樣本權重,是根據該樣本在第 k 輪的權重以及第 k 個分類器的準確率而定,具體的公式爲:

 

3、 AdaBoost 算法示例

瞭解 AdaBoost 的工做原理以後,咱們看一個例子,假設我有 10 個訓練樣本,以下所示:

如今我但願經過 AdaBoost 構建一個強分類器。

該怎麼作呢?按照上面的 AdaBoost 工做原理,咱們來模擬一下。

首先在第一輪訓練中,咱們獲得 10 個樣本的權重爲 1/10,即初始的 10 個樣本權重一致,D1=(0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1)。

假設我有 3 個基礎分類器:

咱們能夠知道分類器 f1 的錯誤率爲 0.3,也就是 x 取值 六、七、8 時分類錯誤;分類器 f2 的錯誤率爲 0.4,即 x 取值 0、一、二、9 時分類錯誤;分類器 f3 的錯誤率爲 0.3,即 x 取值爲 三、四、5 時分類錯誤。

這 3 個分類器中,f一、f3 分類器的錯誤率最低,所以咱們選擇 f1 或 f3 做爲最優分類器,假設咱們選 f1 分類器做爲最優分類器,即第一輪訓練獲得:

根據分類器權重公式獲得:

而後咱們對下一輪的樣本更新求權重值,代入 W_{k+1,i} 和 D_{k+1} 的公式,能夠獲得新的權重矩陣:D2=(0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.1666, 0.1666, 0.1666, 0.0715)。

在這 3 個分類器中,f3 分類器的錯誤率最低,所以咱們選擇 f3 做爲第二輪訓練的最優分類器,即:

根據分類器權重公式獲得:

一樣,咱們對下一輪的樣本更新求權重值,代入 W_{k+1,i} 和 D_{k+1} 的公式,能夠獲得 D3=(0.0455,0.0455,0.0455,0.1667, 0.1667,0.01667,0.1060, 0.1060, 0.1060, 0.0455)。

在第三輪訓練中,咱們繼續統計三個分類器的準確率,能夠獲得分類器 f1 的錯誤率爲 0.1060*3,也就是 x 取值 六、七、8 時分類錯誤。分類器 f2 的錯誤率爲 0.0455*4,即 x 取值爲 0、一、二、9 時分類錯誤。分類器 f3 的錯誤率爲 0.1667*3,即 x 取值 三、四、5 時分類錯誤。

在這 3 個分類器中,f2 分類器的錯誤率最低,所以咱們選擇 f2 做爲第三輪訓練的最優分類器,即:

咱們根據分類器權重公式獲得:

假設咱們只進行 3 輪的訓練,選擇 3 個弱分類器,組合成一個強分類器,那麼最終的強分類器 G(x) = 0.4236G1(x) + 0.6496G2(x)+0.7514G3(x)。

實際上 AdaBoost 算法是一個框架,你能夠指定任意的分類器,一般咱們能夠採用 CART 分類器做爲弱分類器。經過上面這個示例的運算,你體會一下 AdaBoost 的計算流程便可。

 

4、 如何使用 AdaBoost 工具

咱們能夠直接在 sklearn 中使用 AdaBoost。若是咱們要用 AdaBoost 進行分類,須要在使用前引用代碼:

1 from sklearn.ensemble import AdaBoostClassifier

咱們以前講到過,若是你看到了 Classifier 這個類,通常都會對應着 Regressor 類。AdaBoost 也不例外,迴歸工具包的引用代碼以下:

1 from sklearn.ensemble import AdaBoostRegressor

咱們先看下如何在 sklearn 中建立 AdaBoost 分類器。

咱們須要使用 AdaBoostClassifier(base_estimator=None, n_estimators=50, learning_rate=1.0, algorithm=’SAMME.R’, random_state=None) 這個函數,其中有幾個比較主要的參數,我分別來說解下:

1. base_estimator:表明的是弱分類器。在 AdaBoost 的分類器和迴歸器中都有這個參數,在 AdaBoost 中默認使用的是決策樹,通常咱們不須要修改這個參數,固然你也能夠指定具體的分類器。

2. n_estimators:算法的最大迭代次數,也是分類器的個數,每一次迭代都會引入一個新的弱分類器來增長原有的分類器的組合能力。默認是 50。

3. learning_rate:表明學習率,取值在 0-1 之間,默認是 1.0。若是學習率較小,就須要比較多的迭代次數才能收斂,也就是說學習率和迭代次數是有相關性的。當你調整 learning_rate 的時候,每每也須要調整 n_estimators 這個參數。

4. algorithm:表明咱們要採用哪一種 boosting 算法,一共有兩種選擇:SAMME 和 SAMME.R。默認是 SAMME.R。這二者之間的區別在於對弱分類權重的計算方式不一樣。

5. random_state:表明隨機數種子的設置,默認是 None。隨機種子是用來控制隨機模式的,當隨機種子取了一個值,也就肯定了一種隨機規則,其餘人取這個值能夠獲得一樣的結果。若是不設置隨機種子,每次獲得的隨機數也就不一樣。

那麼如何建立 AdaBoost 迴歸呢?

咱們可使用 AdaBoostRegressor(base_estimator=None, n_estimators=50, learning_rate=1.0, loss=‘linear’, random_state=None) 這個函數。

你能看出來迴歸和分類的參數基本是一致的,不一樣點在於迴歸算法裏沒有 algorithm 這個參數,但多了一個 loss 參數。

loss 表明損失函數的設置,一共有 3 種選擇,分別爲 linear、square 和 exponential,它們的含義分別是線性、平方和指數。默認是線性。通常採用線性就能夠獲得不錯的效果。

建立好 AdaBoost 分類器或迴歸器以後,咱們就能夠輸入訓練集對它進行訓練。咱們使用 fit 函數,傳入訓練集中的樣本特徵值 train_X 和結果 train_y,模型會自動擬合。使用 predict 函數進行預測,傳入測試集中的樣本特徵值 test_X,而後就能夠獲得預測結果。

 

5、 如何用 AdaBoost 對房價進行預測

瞭解了 AdaBoost 工具包以後,咱們看下 sklearn 中自帶的波士頓房價數據集。 這個數據集一共包括了 506 條房屋信息數據,每一條數據都包括了 13 個指標,以及一個房屋價位。

13 個指標的含義,能夠參考下面的表格:

這些指標分析得仍是挺細的,但實際上,咱們不用關心具體的含義,要作的就是如何經過這 13 個指標推導出最終的房價結果。

首先加載數據,將數據分割成訓練集和測試集,而後建立 AdaBoost 迴歸模型,傳入訓練集數據進行擬合,再傳入測試集數據進行預測,就能夠獲得預測結果。最後將預測的結果與實際結果進行對比,獲得二者之間的偏差。具體代碼以下:

 1 from sklearn.model_selection import train_test_split
 2 
 3 from sklearn.metrics import mean_squared_error
 4 
 5 from sklearn.datasets import load_boston
 6 
 7 from sklearn.ensemble import AdaBoostRegressor
 8 
 9 # 加載數據
10 
11 data=load_boston()
12 
13 # 分割數據
14 
15 train_x, test_x, train_y, test_y = train_test_split(data.data, data.target, test_size=0.25, random_state=33)
16 
17 # 使用 AdaBoost 迴歸模型
18 
19 regressor=AdaBoostRegressor()
20 
21 regressor.fit(train_x,train_y)
22 
23 pred_y = regressor.predict(test_x)
24 
25 mse = mean_squared_error(test_y, pred_y)
26 
27 print(" 房價預測結果 ", pred_y)
28 
29 print(" 均方偏差 = ",round(mse,2))

運行結果:

 1 房價預測結果  [20.2        10.4137931  14.63820225 17.80322581 24.58931298 21.25076923
 2 
 3 27.52222222 17.8372093  31.79642857 20.86428571 27.87431694 31.09142857
 4 
 5 12.81666667 24.13131313 12.81666667 24.58931298 17.80322581 17.66333333
 6 
 7 27.83       24.58931298 17.66333333 20.90823529 20.10555556 20.90823529
 8 
 9 28.20877193 20.10555556 21.16882129 24.58931298 13.27619048 31.09142857
10 
11 17.08095238 26.19217391  9.975      21.03404255 26.74583333 31.09142857
12 
13 25.83960396 11.859375   13.38235294 24.58931298 14.97931034 14.46699029
14 
15 30.12777778 17.66333333 26.19217391 20.10206186 17.70540541 18.45909091
16 
17 26.19217391 20.10555556 17.66333333 33.31025641 14.97931034 17.70540541
18 
19 24.64421053 20.90823529 25.83960396 17.08095238 24.58931298 21.43571429
20 
21 19.31617647 16.33733333 46.04888889 21.25076923 17.08095238 25.83960396
22 
23 24.64421053 11.81470588 17.80322581 27.63636364 23.59731183 17.94444444
24 
25 17.66333333 27.7253886  20.21465517 46.04888889 14.97931034  9.975
26 
27 17.08095238 24.13131313 21.03404255 13.4        11.859375   26.19214286
28 
29 21.25076923 21.03404255 47.11395349 16.33733333 43.21111111 31.65730337
30 
31 30.12777778 20.10555556 17.8372093  18.40833333 14.97931034 33.31025641
32 
33 24.58931298 22.88813559 18.27179487 17.80322581 14.63820225 21.16882129
34 
35 26.91538462 24.64421053 13.05       14.97931034  9.975      26.19217391
36 
37 12.81666667 26.19214286 49.46511628 13.27619048 17.70540541 25.83960396
38 
39 31.09142857 24.13131313 21.25076923 21.03404255 26.91538462 21.03404255
40 
41 21.16882129 17.8372093  12.81666667 21.03404255 21.03404255 17.08095238
42 
43 45.16666667]
44 
45 均方偏差 =  18.05

這個數據集是比較規範的,咱們並不須要在數據清洗,數據規範化上花太多精力,代碼編寫起來比較簡單。

一樣,咱們可使用不一樣的迴歸分析模型分析這個數據集,好比使用決策樹迴歸和 KNN 迴歸。

編寫代碼以下:

 1 # 使用決策樹迴歸模型
 2 
 3 dec_regressor=DecisionTreeRegressor()
 4 
 5 dec_regressor.fit(train_x,train_y)
 6 
 7 pred_y = dec_regressor.predict(test_x)
 8 
 9 mse = mean_squared_error(test_y, pred_y)
10 
11 print(" 決策樹均方偏差 = ",round(mse,2))
12 
13 # 使用 KNN 迴歸模型
14 
15 knn_regressor=KNeighborsRegressor()
16 
17 knn_regressor.fit(train_x,train_y)
18 
19 pred_y = knn_regressor.predict(test_x)
20 
21 mse = mean_squared_error(test_y, pred_y)
22 
23 print("KNN 均方偏差 = ",round(mse,2))

運行結果:

1 決策樹均方偏差 =  23.84
2 
3 KNN 均方偏差 =  27.87

你能看到相比之下,AdaBoost 的均方偏差更小,也就是結果更優。雖然 AdaBoost 使用了弱分類器,可是經過 50 個甚至更多的弱分類器組合起來而造成的強分類器,在不少狀況下結果都優於其餘算法。所以 AdaBoost 也是經常使用的分類和迴歸算法之一。

相關文章
相關標籤/搜索