【解説】XGBoostとは?〜eXtremeなGBDT〜

解説

XGBoost(eXtreme Gradient Boosting)は、GBDT(Gradient Boosting Decision Tree)の基本枠組みを採用しつつ、さまざまな改良を加えた手法です。ここでは、まずGBDTの基本的な考え方を簡単におさらいし、続いてXGBoostがどのように改良され、実務やコンペティションで高い評価を受けているのかを詳しく解説します。さらに、XGBoostには大きく分けて2種類のAPI(train API と sklearn 風 API)が存在するため、それぞれの実装例も合わせて紹介します。


GBDTのおさらい

GBDTの基本概念

GBDTは、勾配ブースティングの枠組みの中で複数の決定木を順次学習させることで、予測誤差を段階的に補正していく手法です。以下のような流れでモデルが構築されます。

  1. 初期モデルの設定
    例えば、回帰問題では全体の平均値を初期予測とする: $F_0(x) = \bar{y}$​
  2. 残差の計算と木の学習
    各ステップで、現在のモデル $F_{m-1}(x)$ に対する残差(誤差)を計算し、その残差を補正するための決定木 $h_m(x)$ を学習します。
  3. 更新
    学習した決定木をスケーリングして加算します: $$F_m(x) = F_{m-1}(x) + \gamma h_m(x)$$ ここで、$\gamma$ は学習率となります。

GBDTの課題

GBDTは高い予測精度を誇りますが、以下のような課題も抱えています。

  • 計算速度の問題
    各ステップで逐次的に木を構築するため、大規模データでは学習時間が長くなりがちです。
  • 並列化の難しさ
    各ステップが前の木の残差に依存するため、並列処理が難しい面があります。
  • 過学習のリスク
    深い木を使うと、訓練データに対して過度に適合しやすい傾向があります。

XGBoost:GBDTの拡張・改良版

XGBoostは、GBDTの枠組みを基盤としながら、以下の点で大幅な改良が加えられています。

正則化の導入による汎化性能の向上

XGBoostでは、損失関数に正則化項を加えることでモデルの複雑さを抑え、過学習を防ぐ工夫がなされています。目的関数は以下のように表現されます。$$\mathcal{L} = \sum_{i=1}^{n} l(y_i, \hat{y}_i) + \sum_{t=1}^{T} \Omega(f_t)$$

ここで、正則化項は$$\Omega(f) = \gamma T + \frac{1}{2} \lambda \sum w_j^2$$

と定義され、各決定木の構造にペナルティを課すことで、過剰な複雑さを抑制します。

二階微分(Newton法)による最適化の高速化

一般的なGBDTは一階微分(勾配)のみを利用して更新を行いますが、XGBoostでは二階微分(ヘッセ行列の対角成分)も利用することで、以下のような二次近似による更新が可能となっています。$$g_i = \frac{\partial l(y_i, \hat{y}_i)}{\partial \hat{y}_i}, \quad h_i = \frac{\partial^2 l(y_i, \hat{y}_i)}{\partial \hat{y}_i^2}$$

これにより、各分岐での最適な分割がより精度高く求められ、更新の収束速度が向上します。

計算最適化と並列化の実現

XGBoostでは、以下の手法で計算効率と並列化を実現しています。

  • ヒストグラムベースの特徴量分割
    連続値の特徴量をあらかじめビン分割し、各ビンごとに統計情報を計算することで、分岐点の探索を高速化。
  • ブロック単位のデータ処理
    大規模データに対して、データをチャンク(ブロック)単位で処理することで、マルチスレッド環境での並列計算が容易に行えるようになっています。

欠損値の自動処理

XGBoostは、入力データに欠損値が含まれる場合でも、最適な分岐を自動的に推定する仕組みを備えており、事前のデータ前処理を簡略化します。


XGBoostの実装例

XGBoostには、主に2種類のAPIが用意されています。以下にそれぞれのコード例を示します。

train API を用いた実装例

import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston

# データの準備(例としてBostonデータセット)
boston = load_boston()
X_train, X_test, y_train, y_test = train_test_split(boston.data, boston.target, test_size=0.2, random_state=42)

# XGBoost用のDMatrixに変換
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)

# ハイパーパラメータの設定
params = {
'objective': 'reg:squarederror',
'eval_metric': 'rmse',
'max_depth': 4,
'eta': 0.1
}

# モデルの学習
bst = xgb.train(params, dtrain, num_boost_round=100)

# 予測
y_pred = bst.predict(dtest)

sklearn 風 API を用いた実装例

from xgboost import XGBRegressor
from sklearn.metrics import mean_squared_error

# モデルの作成
xgb_model = XGBRegressor(
objective='reg:squarederror',
n_estimators=100,
max_depth=4,
learning_rate=0.1
)

# モデルの学習
xgb_model.fit(X_train, y_train)

# 予測
y_pred = xgb_model.predict(X_test)

# 評価
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse:.4f}")

まとめ

この記事では、まずGBDTの基本概念をおさらいし、その上でXGBoostがGBDTの枠組みをベースに以下の点で改良・拡張されていることを解説いたしました。

  • 正則化項の導入による過学習の抑制
  • 一階・二階微分情報を利用した二次近似による最適化
  • ヒストグラム分割やデータブロック処理による計算効率の向上と並列化
  • 欠損値の自動処理

コメント

タイトルとURLをコピーしました