python, R, vimでデータマイニング

python, R, vim で疑問に思ったことなどを

xgboostを試してみる

xgboostで精度の高いモデルを構築できるらしい。
それから、fevalでモデル精度指標を指定できるところも良さそう。
xgboostを試してみたい。

まずは試してみる。

caretを使用すると色々なモデルが共通の文法で書けるので便利。

library(caret)
## Loading required package: lattice
## Loading required package: ggplot2
model1 <- train(
  Species ~ .,
  iris,
  method="xgbTree"
)
## Loading required package: xgboost
## Loading required package: plyr
model1
## eXtreme Gradient Boosting 
## 
## 150 samples
##   4 predictor
##   3 classes: 'setosa', 'versicolor', 'virginica' 
## 
## No pre-processing
## Resampling: Bootstrapped (25 reps) 
## Summary of sample sizes: 150, 150, 150, 150, 150, 150, ... 
## Resampling results across tuning parameters:
## 
##   max_depth  nrounds  Accuracy   Kappa      Accuracy SD  Kappa SD  
##   1           50      0.9485004  0.9220085  0.02628702   0.03960171
##   1          100      0.9463580  0.9187624  0.02515099   0.03790241
##   1          150      0.9455416  0.9174981  0.02573184   0.03884031
##   2           50      0.9468626  0.9194865  0.02621117   0.03952144
##   2          100      0.9475898  0.9206234  0.02740915   0.04130599
##   2          150      0.9475898  0.9206234  0.02740915   0.04130599
##   3           50      0.9506307  0.9251477  0.02432345   0.03674940
##   3          100      0.9513580  0.9262899  0.02443380   0.03685994
##   3          150      0.9512716  0.9261698  0.02402944   0.03625242
## 
## Tuning parameter 'eta' was held constant at a value of 0.3
## Accuracy was used to select the optimal model using  the largest value.
## The final values used for the model were nrounds = 100, max_depth = 3
##  and eta = 0.3.
summary(model1)
##             Length Class              Mode       
## handle          1  xgb.Booster.handle externalptr
## raw         90996  -none-             raw        
## xNames          4  -none-             character  
## problemType     1  -none-             character  
## tuneValue       3  data.frame         list       
## obsLevels       3  -none-             character

思ったよりも簡単にできた。

feval

fevalで独自の評価関数を指定したい。

マニュアルを確認する。
feval custimized evaluation function.
Returns list(metric=‘metric-name’, value=‘metric-value’)
with given prediction and dtrain.

caret:train で試してみる。
評価関数はrmspeを自作する。

rmspe <- function(prediction, dtrain) {
  .observed <- getinfo(dtrain, "label") 
  list(
    metric = "RMSPE",
      value = sqrt(mean(((.observed- prediction) / .observed) ^ 2))
  )
}

model2 <- train(
  Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width,
  iris,
  method = "xgbTree",
  feval = rmspe
)
model2
## eXtreme Gradient Boosting 
## 
## 150 samples
##   4 predictor
## 
## No pre-processing
## Resampling: Bootstrapped (25 reps) 
## Summary of sample sizes: 150, 150, 150, 150, 150, 150, ... 
## Resampling results across tuning parameters:
## 
##   max_depth  nrounds  RMSE       Rsquared   RMSE SD     Rsquared SD
##   1           50      0.3583983  0.8086825  0.02845745  0.04300446 
##   1          100      0.3592624  0.8085968  0.02550611  0.04302866 
##   1          150      0.3633599  0.8053671  0.02583143  0.04393736 
##   2           50      0.3638931  0.8022369  0.03145324  0.04766807 
##   2          100      0.3780569  0.7881979  0.03225296  0.05362911 
##   2          150      0.3892047  0.7772812  0.03294389  0.05639148 
##   3           50      0.3745153  0.7923352  0.02861350  0.04923131 
##   3          100      0.3925762  0.7754515  0.03001914  0.05058433 
##   3          150      0.4014436  0.7671566  0.03145388  0.05187344 
## 
## Tuning parameter 'eta' was held constant at a value of 0.3
## RMSE was used to select the optimal model using  the smallest value.
## The final values used for the model were nrounds = 50, max_depth = 1
##  and eta = 0.3.

だめ。RMSEが評価指標として採用されている。 私の知識ではcaret:trainでfevalを指定できない。

feval xgboost:xgb.train でfevalを指定

caretを使用しないと新しい文法をマニュアルなどで調べないといけないので嫌だが、とにかく試してみる。

watchlist

目的変数やクロスバリデーション用のデータはwatchlistに指定するらしい。
また、xgb.DMatrix 形式にする必要があるらしい?

.feature <- data.matrix(iris[, 2:4])
.watchlist <- list(
  val = xgb.DMatrix(data = .feature, label = iris$Sepal.Length),
  train = xgb.DMatrix(data = .feature, label = iris$Sepal.Length)
)

xgb.train で試してみる。

model.3 <- xgb.train(
  data = xgb.DMatrix(data = .feature, label = iris$Sepal.Length),
  nround = 10,
  watchlist = .watchlist,
  feval=rmspe
)
## [0]  val-RMSPE:0.641076263296985 train-RMSPE:0.641076263296985
## [1]  val-RMSPE:0.450932635857561 train-RMSPE:0.450932635857561
## [2]  val-RMSPE:0.318373538117156 train-RMSPE:0.318373538117156
## [3]  val-RMSPE:0.227032609122525 train-RMSPE:0.227032609122525
## [4]  val-RMSPE:0.164214553125964 train-RMSPE:0.164214553125964
## [5]  val-RMSPE:0.120398490746834 train-RMSPE:0.120398490746834
## [6]  val-RMSPE:0.0907635245058501    train-RMSPE:0.0907635245058501
## [7]  val-RMSPE:0.0706479694183348    train-RMSPE:0.0706479694183348
## [8]  val-RMSPE:0.0571393392305592    train-RMSPE:0.0571393392305592
## [9]  val-RMSPE:0.0484302684656021    train-RMSPE:0.0484302684656021
summary(model.3)
##        Length Class              Mode       
## handle    1   xgb.Booster.handle externalptr
## raw    7312   -none-             raw

なんかできた。