用R建立整合學習模型(boosting、bagging、stacking)
整合學習能夠提升準確率,而本文將會介紹如何用R建立三種高效的整合學習模型。
本次案例研究將手把手地教你實現bagging、boosting、stacking,以及展示如何繼續提高模型的準確率。
讓我們開始吧!
提高模型的準確率
給特定的資料集找到效能優秀的機器學習演算法頗為費時,因為應用機器學習演算法本身所具有的實驗和錯誤屬性。
如果你已經有了準確性較高的一些演算法,可以調整每一個演算法,從中得到最佳效能的演算法。
或者綜合利用多個演算法預測結果,用以提高準確率。
這就是所謂的整合學習。
Combine Model Predictions Into Ensemble Predictions (怎麼翻譯?)
三種最流行的方法如下:
- Bagging 從訓練集中有放回抽取不同子集,建立多個模型(通常是同一個模型)
- Boosting 訓練多個模型(通常是同一個模型),每個模型學習修正上一個模型錯判的樣本
- Stacking 訓練多個模型(通常是不同模型),學習如何把各個模型組合達到最優效能
本文假設你已經相當熟悉相關演算法,並不打算解釋每一個演算法的含義。重點關注如何用R實現整合學習演算法。
用R實現整合學習
你能夠用R實現三個主要整合學習技術:Bagging、Boosting、Stacking。在這部分,我們將輪流講解。
開始之前,先確認我們的測試計劃。
測試資料集
測試資料集為ionosphere 。可以從
先載入資料集和和相關包
# Load libraries
library(mlbench)
library(caret)
library(caretEnsemble)
# Load the dataset
data(Ionosphere)
dataset <- Ionosphere
dataset <- dataset[,-2]
dataset$V1 <- as.numeric(as .character(dataset$V1))
注意第一個特徵是因子型,需要轉換為數值型,以便和其他數值型特徵保持一致。還要注意第二個特徵是一個常量,需要刪去。
下面是資料集前幾行的情況:
> head(dataset)
V1 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15
1 1 0.99539 -0.05889 0.85243 0.02306 0.83398 -0.37708 1.00000 0.03760 0.85243 -0.17755 0.59755 -0.44945 0.60536
2 1 1.00000 -0.18829 0.93035 -0.36156 -0.10868 -0.93597 1.00000 -0.04549 0.50874 -0.67743 0.34432 -0.69707 -0.51685
3 1 1.00000 -0.03365 1.00000 0.00485 1.00000 -0.12062 0.88965 0.01198 0.73082 0.05346 0.85443 0.00827 0.54591
4 1 1.00000 -0.45161 1.00000 1.00000 0.71216 -1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 -1.00000
5 1 1.00000 -0.02401 0.94140 0.06531 0.92106 -0.23255 0.77152 -0.16399 0.52798 -0.20275 0.56409 -0.00712 0.34395
6 1 0.02337 -0.00592 -0.09924 -0.11949 -0.00763 -0.11824 0.14706 0.06637 0.03786 -0.06302 0.00000 0.00000 -0.04572
V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28
1 -0.38223 0.84356 -0.38542 0.58212 -0.32192 0.56971 -0.29674 0.36946 -0.47357 0.56811 -0.51171 0.41078 -0.46168
2 -0.97515 0.05499 -0.62237 0.33109 -1.00000 -0.13151 -0.45300 -0.18056 -0.35734 -0.20332 -0.26569 -0.20468 -0.18401
3 0.00299 0.83775 -0.13644 0.75535 -0.08540 0.70887 -0.27502 0.43385 -0.12062 0.57528 -0.40220 0.58984 -0.22145
4 0.14516 0.54094 -0.39330 -1.00000 -0.54467 -0.69975 1.00000 0.00000 0.00000 1.00000 0.90695 0.51613 1.00000
5 -0.27457 0.52940 -0.21780 0.45107 -0.17813 0.05982 -0.35575 0.02309 -0.52879 0.03286 -0.65158 0.13290 -0.53206
6 -0.15540 -0.00343 -0.10196 -0.11575 -0.05414 0.01838 0.03669 0.01519 0.00888 0.03513 -0.01535 -0.03240 0.09223
V29 V30 V31 V32 V33 V34 Class
1 0.21266 -0.34090 0.42267 -0.54487 0.18641 -0.45300 good
2 -0.19040 -0.11593 -0.16626 -0.06288 -0.13738 -0.02447 bad
3 0.43100 -0.17365 0.60436 -0.24180 0.56045 -0.38238 good
4 1.00000 -0.20099 0.25682 1.00000 -0.32382 1.00000 bad
5 0.02431 -0.62197 -0.05707 -0.59573 -0.04608 -0.65697 good
6 -0.07859 0.00732 0.00000 0.00000 -0.00039 0.12011 bad
1、Boosting Algprithms
有以下兩個最受歡迎的Boosting演算法:
- C5.0
- Stochastic Gradient Boosting
下面是兩種演算法的實現,都採用預設引數,沒有進行調參。
# Example of Boosting Algorithms
control <- trainControl(method="repeatedcv", number=10, repeats=3)
seed <- 7
metric <- "Accuracy"
# C5.0
set.seed(seed)
fit.c50 <- train(Class~., data=dataset, method="C5.0", metric=metric, trControl=control)
# Stochastic Gradient Boosting
set.seed(seed)
fit.gbm <- train(Class~., data=dataset, method="gbm", metric=metric, trControl=control, verbose=FALSE)
# summarize results
boosting_results <- resamples(list(c5.0=fit.c50, gbm=fit.gbm))
summary(boosting_results)
dotplot(boosting_results)
C5.0演算法的準確率更高,為94.58%
Models: c5.0, gbm
Number of resamples: 30
Accuracy
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
c5.0 0.8824 0.9143 0.9437 0.9458 0.9714 1 0
gbm 0.8824 0.9143 0.9429 0.9402 0.9641 1 0
2、Bagging Algorithms
有以下兩個最受歡迎的Bagging 演算法:
- Bagged CART
- Random Forest
下面是兩種演算法的實現,都採用預設引數,沒有進行調參。
# Example of Bagging algorithms
## method重抽樣方法
## number交叉驗證折數or重抽樣迭代次數
## repeats交叉驗證引數,貌似是參與計算的資料集個數?
## 比如下面的10折,但是隨機選取3個子集建模??不清楚呀
control <- trainControl(method="repeatedcv", number=10, repeats=3)
seed <- 7
metric <- "Accuracy"
# Bagged CART
set.seed(seed)
fit.treebag <- train(Class~., data=dataset, method="treebag", metric=metric, trControl=control)
# Random Forest
set.seed(seed)
fit.rf <- train(Class~., data=dataset, method="rf", metric=metric, trControl=control)
# summarize results
bagging_results <- resamples(list(treebag=fit.treebag, rf=fit.rf))
summary(bagging_results)
dotplot(bagging_results)
隨即森林準確率更高,達到93.25%
3、Stacking Algorithms
caretEnsemble包能夠組合多種caret模型的預測結果。
給定一系列caret模型,caretStack函式能夠指定高階模型(即元分類器)學習怎樣組合基學習器,以達到最佳效能。
首先為資料集ionosphere 構建5個子模型(基學習器),詳細如下:
- Linear Discriminate Analysis (LDA) [線性分類器,類似的QDA]
- Classification and Regression Trees (CART)
- Logistic Regression (via Generalized Linear Model or GLM)
- k-Nearest Neighbors (kNN)
- Support Vector Machine with a Radial Basis Kernel Function (SVM)
下面的例子建立了5個子模型,注意由caretEnsemble包提供的caretList()函式,用於建立一系列標準的caret模型
# Example of Stacking algorithms
# create submodels
control <- trainControl(method="repeatedcv", number=10, repeats=3, savePredictions=TRUE, classProbs=TRUE)
algorithmList <- c('lda', 'rpart', 'glm', 'knn', 'svmRadial')
set.seed(seed)
models <- caretList(Class~., data=dataset, trControl=control, methodList=algorithmList)
results <- resamples(models)
summary(results)
dotplot(results)
SVM準確率最高,達到94.66%。[結果貌似不能復現啊?]
當使用stacking組合不同分類器時,我們希望不同分類器之間是弱相關的。這表明子模型不僅需要高效還得存在差異。(This would suggest that the models are skillful but in different ways, allowing a new classifier to figure out how to get the best from each model for an improved score.不會翻譯咯)
如果模型相關性大於0.75,那麼這些模型預測結果很可能類似或者相同,從而減弱組合模型帶來的準確率上的提升。
# correlation between results
modelCor(results)
splom(results)
上面的程式碼可以計算不同模型的相關性。所有模型的相關性都比較低。其中LR和KNN相關性最高,0.517,但仍小於0.75
用簡單線性模型組合子模型的預測結果
# stack using glm
stackControl <- trainControl(method="repeatedcv", number=10, repeats=3, savePredictions=TRUE, classProbs=TRUE)
set.seed(seed)
stack.glm <- caretStack(models, method="glm", metric="Accuracy", trControl=stackControl)
print(stack.glm)
準確率提升到94.99%,略優於svm單模型。也比上文提高的隨機森林高。
A glm ensemble of 2 base models: lda, rpart, glm, knn, svmRadial
Ensemble results:
Generalized Linear Model
1053 samples
5 predictor
2 classes: 'bad', 'good'
No pre-processing
Resampling: Cross-Validated (10 fold, repeated 3 times)
Summary of sample sizes: 948, 947, 948, 947, 949, 948, ...
Resampling results
Accuracy Kappa Accuracy SD Kappa SD
0.949996 0.891494 0.02121303 0.04600482
當最好使用不同演算法時,我們也可以使用更加複雜的演算法進行組合預測。下面的列子使用隨機森林組合預測。(應該指的是元分類器為隨機森林)
# stack using random forest
set.seed(seed)
stack.rf <- caretStack(models, method="rf", metric="Accuracy", trControl=stackControl)
print(stack.rf)
此時準確率提升到96.26%。
A rf ensemble of 2 base models: lda, rpart, glm, knn, svmRadial
Ensemble results:
Random Forest
1053 samples
5 predictor
2 classes: 'bad', 'good'
No pre-processing
Resampling: Cross-Validated (10 fold, repeated 3 times)
Summary of sample sizes: 948, 947, 948, 947, 949, 948, ...
Resampling results across tuning parameters:
mtry Accuracy Kappa Accuracy SD Kappa SD
2 0.9626439 0.9179410 0.01777927 0.03936882
3 0.9623205 0.9172689 0.01858314 0.04115226
5 0.9591459 0.9106736 0.01938769 0.04260672
Accuracy was used to select the optimal model using the largest value.
The final value used for the model was mtry = 2.
你可以用R建立整合學習模型
你不必是R程式設計師。只需copy相關程式碼,查詢幫助文件。
你不必是機器學習專家。從頭構建整合學習系統十分複雜,而caret和caretEnsemble包可以輕鬆進行模型建立和實驗,即使你對模型如何執行並沒有深刻的認知。熟悉每一種型別的整合學習方法,以後更好的使用這些演算法。
你不必自己寫整合學習的程式碼。許多強大的演算法R都能夠提供,直接使用就好。現在就開始學習本文中的案例。你總能夠調整這些演算法以適應特定的資料集或者用自定義的程式碼實驗新的想法
總結
在本文,你能夠發現使用整合學習演算法能夠提高模型的準確率。
在R中能夠構建三種整合學習演算法:
1. Bagging
2. Boosting
3. Stacking
你可以使用案例中的程式碼作為機器學習專案的參考樣本。
下一步
你是否已經完成案例研究?
1. 啟動R
2. copy程式碼
3. 通過幫助文件,花時間理解每部分的程式碼
有問題可以留言,我會盡力回答~
翻後感
1、基分類器or子模型是否可以調整引數?怎麼調整?
2、元分類器or二級模型是否可以調整引數?怎麼調整?
3、基本演算法的理論細節還是要掌握,不然都不能愉快地調參咯!
遇到的坑
- 目標變數貌似必須是字串,因子型。否則會報錯
- stacking是的模型對資料集有要求,比如lda要求特徵中沒有常量,這應該和模型的背景有關吧
- 似乎stacking並沒有什麼效果喲~或者我調引數調的還是不行嗎?