關卡 1

Boosting是一個利用較簡單的模型(例如:decisiontree),重複學習很多次來加強學習效果的機器學習演算法。GradientBoosting則是Friedmanetal.(1999)在更進一步把Boosting的概念擴展到functionspace上的最佳化問題。把這個概念和decisiontree結合,就是近年來在機器學習競賽上火熱的GDBT演算法。

關卡 2

R有一個很優秀的GDBT實作的套件:gbm。但是近年來又竄起一個在多個機器學習競賽拿到冠軍的實作套件:xgboost。

關卡 3

請同學安裝xgboost套件。

check_then_install("xgboost", "0.4.2")

關卡 4

請同學載入xgboost套件

library(xgboost)

關卡 5

請同學找找看xgboost的vignette。

vignette(package = "xgboost")

關卡 6

請同學打開名為“xgboost”的vignette

vignette("xgboost", package = "xgboost")

關卡 7

xgboost的使用非常簡單。請同學從xgboost套件先載入範例的資料集:agaricus.train。請輸入:data(agaricus.train,package="xgboost")

data(agaricus.train, package = "xgboost")

關卡 8

讓我們利用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)

關卡 9

如果要對xgboost的GDBT學習方法做調整,例如調整樹的深度、Boosting的次數、在函數空間上的learningrate,請同學參考?xgboost的文件。讓我們輸入?xgboost一起看看說明文件。

?xgboost

關卡 10

請問同學,這些Boosting的迭代的最大次數,要用哪一個xgboost的參數調整呢?

nrounds

關卡 11

請問同學,樹的深度,要用哪一個xgboost的參數調整呢?

params

關卡 12

更進一步,這個params參數應該要用什麼型態傳給它呢?(請回憶rpart的經驗)

list

關卡 13

至於在函數空間上的learningrate,是params底下的eta

關卡 14

一般來說,最後模型的準確度可以透過nroundsparams底下的etamax.depth來控制。nrounds越大,學的越慢,也越準。但是當太大的時候,模型會學過頭(overfit),導致結果變差。eta越小,學到最好的模型通常就需要越多的nrounds,但是因為每次調整的幅度比較小,所以考量(overfit)的效應後,得到的最好模型,也會比較好。max.depth越大,每次學的時間就比較長,而且比較可以抓到變數之間的交互作用。以上是我對xgboost的理解。

關卡 15

接著讓我們載入測試的資料集。請同學輸入:data(agaricus.test,package="xgboost")

data(agaricus.test, package = "xgboost")

關卡 16

讓我們利用bst對agricus.test做預測。請同學輸入:predict(bst,agaricus.test$data)

predict(bst, agaricus.test$data)

關卡 17

如果同學想要查詢更多predict的參數呢?由於xgboost套件使用的是R的S4物件導向系統,所以要查詢的話需要使用以下的方式。

關卡 18

請同學先輸入showMethods(predict)

showMethods(predict)

關卡 19

同學是不是看到R列出一連串有Function有object的文字呢?我們從下往上看。object="xgb.Booster.handle"代表當predict的第一個參數,或是名稱為object的參數的型態(class)如果為"xgb.Booster.handle"時,會有一個針對這樣型態的函數來處理。

關卡 20

接著請同學輸入:getMethod(predict,"xgb.Booster.handle")

getMethod(predict, "xgb.Booster.handle")

關卡 21

運用這種方式,R就可以把predict遇到"xgb.Booster.handle"物件時會執行的動作展現給我們看了。

關卡 22

但是直接看說明文件可能是更方便的。請同學輸入:?predict

?predict

關卡 23

同學應該會看到R對predict的說明文件,但是幫助不大,因為我們想要看的是針對xgboost的GDBT模型做預測時的使用說明文件。這個文件的左上角:predict{stats}告訴我們,這是stats這個基本套件底下的predict的說明文件。如果我們想要看針對xgboost的GDBT模型的predict說明文件,要輸入:help("predict,xgb.Booster-method")。請同學先試試看。

help("predict,xgb.Booster-method")

關卡 24

這裡是因為xgboost採用的是R的S4系統,所以查閱predict需要這麼饒口。而且和rpart套件使用的S3系統也不同。

關卡 25

一般來說,我們可以利用library(help=xgboost)來打開所有xgboost套件作者有撰寫的說明文件內容。我也是用這個方式才知道上一題的答案的。請同學試試看。

library(help=xgboost)

關卡 26

我們對xgboost的介紹就到這邊了。

關卡 27

最後我們使用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
  }))
}