Boosting是一個利用較簡單的模型(例如:decisiontree),重複學習很多次來加強學習效果的機器學習演算法。GradientBoosting則是Friedmanetal.(1999)在更進一步把Boosting的概念擴展到functionspace上的最佳化問題。把這個概念和decisiontree結合,就是近年來在機器學習競賽上火熱的GDBT演算法。
R有一個很優秀的GDBT實作的套件:gbm。但是近年來又竄起一個在多個機器學習競賽拿到冠軍的實作套件:xgboost。
請同學安裝xgboost套件。
check_then_install("xgboost", "0.4.2")
請同學載入xgboost套件
library(xgboost)
請同學找找看xgboost的vignette。
vignette(package = "xgboost")
請同學打開名為“xgboost”的vignette
vignette("xgboost", package = "xgboost")
xgboost的使用非常簡單。請同學從xgboost套件先載入範例的資料集:agaricus.train
。請輸入:data(agaricus.train,package="xgboost")
data(agaricus.train, package = "xgboost")
讓我們利用xgboost學一個GDBT模型。請同學輸入:bst<-xgboost(data=agaricus.train$data,label=agaricus.train$label,objective="binary:logistic",nrounds=10)
bst <- xgboost(data = agaricus.train$data, label = agaricus.train$label, objective = "binary:logistic", nrounds = 10)
如果要對xgboost的GDBT學習方法做調整,例如調整樹的深度、Boosting的次數、在函數空間上的learningrate,請同學參考?xgboost
的文件。讓我們輸入?xgboost
一起看看說明文件。
?xgboost
請問同學,這些Boosting的迭代的最大次數,要用哪一個xgboost
的參數調整呢?
nrounds
請問同學,樹的深度,要用哪一個xgboost
的參數調整呢?
params
更進一步,這個params參數應該要用什麼型態傳給它呢?(請回憶rpart的經驗)
list
至於在函數空間上的learningrate,是params
底下的eta
。
一般來說,最後模型的準確度可以透過nrounds
和params
底下的eta
、max.depth
來控制。nrounds
越大,學的越慢,也越準。但是當太大的時候,模型會學過頭(overfit),導致結果變差。eta
越小,學到最好的模型通常就需要越多的nrounds
,但是因為每次調整的幅度比較小,所以考量(overfit)的效應後,得到的最好模型,也會比較好。max.depth
越大,每次學的時間就比較長,而且比較可以抓到變數之間的交互作用。以上是我對xgboost的理解。
接著讓我們載入測試的資料集。請同學輸入:data(agaricus.test,package="xgboost")
data(agaricus.test, package = "xgboost")
讓我們利用bst對agricus.test
做預測。請同學輸入:predict(bst,agaricus.test$data)
。
predict(bst, agaricus.test$data)
如果同學想要查詢更多predict
的參數呢?由於xgboost套件使用的是R的S4物件導向系統,所以要查詢的話需要使用以下的方式。
請同學先輸入showMethods(predict)
showMethods(predict)
同學是不是看到R列出一連串有Function有object的文字呢?我們從下往上看。object="xgb.Booster.handle"
代表當predict的第一個參數,或是名稱為object的參數的型態(class)如果為"xgb.Booster.handle"
時,會有一個針對這樣型態的函數來處理。
接著請同學輸入:getMethod(predict,"xgb.Booster.handle")
getMethod(predict, "xgb.Booster.handle")
運用這種方式,R就可以把predict遇到"xgb.Booster.handle"
物件時會執行的動作展現給我們看了。
但是直接看說明文件可能是更方便的。請同學輸入:?predict
?predict
同學應該會看到R對predict
的說明文件,但是幫助不大,因為我們想要看的是針對xgboost的GDBT模型做預測時的使用說明文件。這個文件的左上角:predict{stats}
告訴我們,這是stats這個基本套件底下的predict的說明文件。如果我們想要看針對xgboost的GDBT模型的predict說明文件,要輸入:help("predict,xgb.Booster-method")
。請同學先試試看。
help("predict,xgb.Booster-method")
這裡是因為xgboost採用的是R的S4系統,所以查閱predict
需要這麼饒口。而且和rpart
套件使用的S3系統也不同。
一般來說,我們可以利用library(help=xgboost)
來打開所有xgboost套件作者有撰寫的說明文件內容。我也是用這個方式才知道上一題的答案的。請同學試試看。
library(help=xgboost)
我們對xgboost的介紹就到這邊了。
最後我們使用xgboost來再次挑戰mlbench的Ionosphere資料
check_then_install("mlbench", "2.1.1")
library(mlbench)
# 方便起見,同學可以使用這個函數計算 Logarithmic Loss
logloss <- function(y, p, tol = 1e-4) {
# tol 的用途是避免對0取log所導致的數值問題
p[p < tol] <- tol
-sum(y * log(p) + (1 - y) * log(1-p))
}
data(Ionosphere)
test.i <- c(4L, 6L, 9L, 13L, 14L, 22L, 31L, 33L, 50L, 52L, 61L, 63L, 68L,
79L, 91L, 99L, 119L, 135L, 154L, 155L, 160L, 162L, 166L, 194L,
200L, 219L, 233L, 236L, 237L, 242L, 244L, 248L, 250L, 257L, 261L,
276L, 278L, 283L, 292L, 310L, 312L, 315L, 319L, 323L, 325L, 327L,
335L, 337L, 338L, 344L)
df.test <- Ionosphere[test.i,-2] # remove V2
train.i <- setdiff(seq_len(nrow(Ionosphere)), test.i)
df.train <- Ionosphere[train.i,-2]
# X 是等等要放到的x參數的值
X.train <- model.matrix(Class ~ ., df.train)[,-1]
X.test <- model.matrix(Class ~ ., df.test)[,-1]
# y 是等等要放到glmnet的y參數的值
y.train <- df.train$Class == "good"
y.test <- df.test$Class == "good"
# 請利用xgboost,從df.train上學出一個模型
# 該模型在df.test上的logloss需要小於3
answer_06 <- local({
NULL
# 請修改下列的程式碼
# xgboost(X.train, y.train, nround = ?, eta = ?, objective = "binary:logistic")
xgboost(X.train, y.train, nround = 100, eta = 0.1, objective = "binary:logistic")
})
stopifnot(class(answer_06) == "xgb.Booster")
if (interactive()) {
stopifnot(local({
p <- predict(answer_06, X.test)
logloss(y.test, p) < 3
}))
}