バギング、ブースティングの概要とRでのXGboost実行例
XGboostを実務で使う機会がありそうなので勉強しているのですが、そもそもブースティングがどのような手法なのか、同じアンサンブル学習のバギングとの違いは何かといったことが気になったため調べた内容をまとめました。
目次
- アンサンブル法
- バギング
- ブートストラップサンプル
- ブースティング
- アダブースト (Adaptive Boosting: AdaBoost)
- 勾配ブースティング (Gradient Boosting)
- GBDT (Gradient Boosting Decision Tree)
- XGboost (eXtreme Gradient boosting)
- RでのXGboost実行例
- 参考文献
アンサンブル法
- 様々な分類器を1つのメタ分類器として組み合わせ、分類器を個別に使用するよりも汎化性能高くする手法
バギング
- アンサンブル法の1つであり、学習データのブートストラップサンプル(後述)を用いて複数のデータを学習させ、新しい入力データのクラスはそれらの識別器の多数決で決める手法
- 個々の識別器の性能は弱い(ランダム識別器より少し良い程度)ため弱識別器と呼ばれる
- 例えば、決定木は学習データの少しの変化で識別器の性能が大きく変化してしまうので不安定な識別器であり、弱識別器の代表例
- 識別性能面で欠点があるが、バギングの欠点を補う手法としてブースティング(バギングとは異なる手法)やランダムフォレスト(バギングの一形態)がある
- バギングの1種であるランダムフォレストでは、個々の決定木(弱識別器)の学習において特徴量をランダムに抽出することで性能を改善している
《メリット》
- ブートストラップサンプルによる学習を行うため、個々の識別器の学習は独立に並列的に行うことができる
《デメリット》
- 識別器が持つばらつきにはブートストラップサンプルのばらつきが反映されるのみであり、弱識別器間の性能が似かより、十分に性能強化ができない可能性がある
ブートストラップサンプル
- N個のデータからN回復元抽出を行って作ったサンプルのこと
- ブートストラップ法(再代入誤り率のバイアス補正に使われる手法)などで用いられている
ブースティング
- アンサンブル法の1つであり、「分類の難しい学習データに焦点を当てており、個々の識別器の学習が直列的に行われる」点でバギングと異なる
- 「分類の難しい学習データに焦点を当ている」つまり、具体的には誤分類された学習データを重点的に後の弱識別器で学習することで性能を向上させている
- バギングでは学習にブートストラップサンプルを用いていたのに対し、ブースティングでは学習データからランダムに非復元抽出された学習データのサブセットを使用する
- ブースティングを用いた手法に「アダブースト (Adaptive Boosting: AdaBoost)」「勾配ブースティング (Gradient Boosting)」「GBDT (Gradient Boosting Decision Tree)」「XGboost (eXtreme Gradient boosting)」などがある
《メリット》
- バギングより性能が良い
《デメリット》
- ブースティングアルゴリズムはバリアンスが高いことで知られており、学習データを過学習する傾向にある
アダブースト (Adaptive Boosting: AdaBoost)
- ブースティングの1種で、学習データ全体を使って弱識別器をトレーニングする点でブースティング(原型)と異なっている
- ブースティング同様、誤った学習データに対する重みを大きくし、正しく識別された学習データに対する重みを小さくすることで後に学習する識別器ほど誤りの多い学習データに集中して学習する手法である
勾配ブースティング (Gradient Boosting)
- 各ステップのパラメタ最適化に用いる評価関数に勾配降下法を用いたブースティング
GBDT (Gradient Boosting Decision Tree)
- 勾配ブースティングの1種で、弱識別器に決定木を用いたもの
- アダブーストでは各ステップを更新する際学習データ全体を使っていた一方、GBDTではランダムに抽出したサンプルのみを用いている
XGboost (eXtreme Gradient boosting)
- C++によって勾配ブースティングを高速化したもの
- (ブースティング全般に言えることかもしれませんが)パラメタが多くチューニングが大変
- Rで実行するためのパッケージとして{xgboost}、{caret}、{catboost}の3種類が提供されている
データアナリストの知り合いに聞いたところ、XGboostはパラメタが多くチューニングが大変ですが、その分チューニングによる精度向上が期待できる手法だそうです。なお、XGboostのパラメータチューニングに関しては以下のブログに詳細が載っていました。 XGBoostやパラメータチューニングの仕方に関する調査 | かものはしの分析ブログ
RでのXGboost実行例
RでXGboostを実行する際のパッケージとして{xgboost}、{caret}、{catboost}の3種類が提供されていますが(私の知る限り)、ひとまず{XGboost}で実行してみました。XGboostを実行する際の関数であるxgboostは引数としてdgCMatrix型のデータを受け取るため、学習データをdgCMatrix型に変換する必要があり、以下の実行例ではdata.table型に変換→dgCMatrix型に変換という方法でデータ処理しています。
library(xgboost) library(Matrix) # dgCMatrixへ変換するために必要 library(data.table) library(GGally) library(tidyverse) #サンプルデータの作成 set.seed(5) n <- 1000 x1 <- runif(n, min=0, max=10) + rnorm(n, sd=10) x2 <- runif(n, min=0, max=10) + rnorm(n, sd=10) x3 <- runif(n, min=0, max=10) + rnorm(n, sd=10) x4 <- runif(n, min=0, max=10) + 0.3*x3 + rnorm(n, sd=10) #弱い相関 x5 <- runif(n, min=0, max=10) + rnorm(n, sd=10) x6 <- runif(n, min=0, max=10) + x5 + rnorm(n, sd=10) #強い相関 #データ結合 df <- data.frame(x1=x1, x2=x2, x3=x3, x4=x4, x5=x5, x6=x6) #相関係数行列を確認 ggpairs(df)
やや見づらいですが、各特徴量の相関が確認できます。
#目的変数の作成 e <- rnorm(n, sd=50) y <- 1 + 1*x1 + 2*x2 + 3*x3 + 4*x4 + 5*x5 + 6*x6 + e #データ統合 df <- data.frame(x1=x1, x2=x2, x3=x3, x4=x4, x5=x5, x6=x6, y=y) #目的変数を2値にする #ひとまず、平均以上か否かで2値に分類 y.mean <- mean(df$y) df <- df %>% dplyr::mutate(y=ifelse(y >= y.mean, 1, 0)) #データを標準化しておく df.tmp <- df %>% dplyr::select(x1:x6) %>% scale() %>% data.frame() df.scaled <- df.tmp %>% dplyr::bind_cols(df %>% select(y))
モデル作成と推定
#入力データは一度data.table形式に変換し、更にdgCMatrix形式へ再変換する必要がある df <- data.table(df.scaled, keep.rownames = F) #dgCMatrix形式に変換 sparse_matrix <- sparse.model.matrix(y ~. -1, data=df.scaled) # 正解データ output_vector <- df.scaled$y # 多クラス分類 bst <- xgboost(data = sparse_matrix, label = output_vector, max.depth = 4, eta = 1, nthread = 2, nround = 5, objective = "binary:logistic") #2値分類なので"binary:logistic"を指定,多クラス分類であれば(objective="multi:softmax")を指定 # 推定結果 prds <- predict(bst, sparse_matrix) #教師データと同じデータを推定 df.scaled$predict <- prds df.scaled <- df.scaled %>% dplyr::mutate(predict=ifelse(prds >= 0.5, 1, 0)) # クロス集計 (tab <- table(df.scaled$predict, df.scaled$y)) # 0 1 # 0 469 28 # 1 34 469 # accuracy (sum(diag(tab))/sum(tab)) #[1] 0.938 # feature importanceの確認 importance_matrix <- xgb.importance(model = bst) print(importance_matrix) # Feature Gain Cover Frequency # 1: x6 0.56556564 0.30329810 0.24137931 # 2: x4 0.17036548 0.24960335 0.24137931 # 3: x5 0.14000350 0.22072380 0.15517241 # 4: x3 0.08885910 0.14576602 0.20689655 # 5: x2 0.02351642 0.06294260 0.12068966 # 6: x1 0.01168987 0.01766612 0.03448276 # feature importanceをプロット xgb.plot.importance(importance_matrix = importance_matrix)
以下はfeature importanceをプロットした結果
簡単にXGboostの概要とRでの実行方法を確認しただけですが、公式ドキュメントを見る限りやはりパラメータが多いので実務で使う前に更に勉強しておく必要がありそうです。
参考文献、ブログなど
Python機械学習プログラミング
はじめてのパターン認識
XGBoostやパラメータチューニングの仕方に関する調査 | かものはしの分析ブログ
勾配ブースティングについてざっくりと説明する - About connecting the dots.
Boosting(ブースティング)について調べたのでまとめる:AdaBoost / Gradient Boosting / XGBoostなど - St_Hakky’s blog
アンサンブル学習のブースティングとバギングの違いについて | データ分析とインテリジェンス
パッケージユーザーのための機械学習(12):Xgboost (eXtreme Gradient Boosting) - 六本木で働くデータサイエンティストのブログ
XGBoostの実装(R編)