はじめに
前回はLightGBMを使った予測モデルの構築・交差検証・ハイパーパラメータチューニングまでを整理した。
LightGBMは非常に強力なモデルだが、「なぜLightGBMを使うのか」を説明できるようになるには、他のモデルとの違いを知っておく必要がある。今回はアンサンブル学習の代表的な3モデル(Random Forest・XGBoost・LightGBM)を比較しながら整理する。
なぜ複数のモデルを知っておくべきか
機械学習の実務では「とりあえずLightGBMを使う」という選択は多い。ただ、それには前提がある。
- データの量・質によってはシンプルなモデルの方が精度が出ることがある
- モデルの説明責任が求められる場面では、解釈しやすいモデルが必要になる
- Kaggleなどのコンペではアンサンブルのために複数モデルを組み合わせることがある
「どのモデルを使うか」を意識的に選べるようになることが今回の目標。
3つのモデルを整理する
アンサンブル学習とは
3つのモデルはいずれも決定木を複数組み合わせる「アンサンブル学習」の手法である。大きく2種類に分かれる。
| 手法 | 概要 | 代表モデル |
|---|---|---|
| バギング | 複数の木を並列に学習し、結果を平均・多数決する | Random Forest |
| ブースティング | 前の木の誤りを次の木が補う形で逐次学習する | XGBoost・LightGBM |
Random Forest
複数の決定木を並列に学習し、予測値を平均(回帰)または多数決(分類)で決める。各木はランダムに選んだ特徴量とデータで学習するため、過学習に強い。
チューニング項目が少なく、デフォルト設定でも安定した精度が出やすい。まず試す第一候補として使いやすい。
XGBoost
ブースティングを正則化ありで実装したモデル。Kaggleで爆発的に普及した手法で、精度と速度のバランスが良い。LightGBMより歴史が長く、参考資料が豊富。
LightGBM
XGBoostをさらに高速化・省メモリ化した手法。大規模データで特に威力を発揮する。前回の記事で扱ったのでここでは詳細は割愛する。
3モデルの比較まとめ
| Random Forest | XGBoost | LightGBM | |
|---|---|---|---|
| 学習方式 | バギング | ブースティング | ブースティング |
| 速度 | 中 | 中〜高 | 高 |
| 過学習への強さ | 強い | 中(正則化あり) | 中(正則化あり) |
| チューニング難度 | 低 | 中 | 中 |
| 大規模データ | △ | ○ | ◎ |
実装して比較してみる
前回と同じ小売店の売上データを使い、3モデルの精度をそのまま比較してみる。
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score
from sklearn.metrics import mean_absolute_error
import xgboost as xgb
import lightgbm as lgb
# 前回と同じデータを再現
np.random.seed(42)
n = 500
df = pd.DataFrame({
"来客数": np.random.randint(80, 300, n),
"気温": np.random.uniform(0, 35, n).round(1),
"特売フラグ": np.random.choice([0, 1], n, p=[0.8, 0.2]),
"月": np.random.randint(1, 13, n),
"曜日": np.random.randint(0, 7, n),
"週末フラグ": np.random.choice([0, 1], n),
})
df["売上"] = (df["来客数"] * 1000
+ df["特売フラグ"] * 20000
+ np.random.normal(0, 5000, n))
X = df.drop("売上", axis=1)
y = df["売上"]
models = {
"Random Forest": RandomForestRegressor(n_estimators=100, random_state=42),
"XGBoost" : xgb.XGBRegressor(n_estimators=100, random_state=42, verbosity=0),
"LightGBM" : lgb.LGBMRegressor(n_estimators=100, random_state=42, verbose=-1),
}
for name, model in models.items():
# 交差検証(5分割)で MAE を評価
scores = cross_val_score(
model, X, y,
cv=5,
scoring="neg_mean_absolute_error"
)
mae = -scores.mean()
std = scores.std()
print(f"{name:15s} MAE: {mae:,.0f} 円 (±{std:,.0f})")
出力例(実行環境によって多少変わる):
Random Forest MAE: 8,412 円 (±1,203)
XGBoost MAE: 7,984 円 (±1,051)
LightGBM MAE: 7,861 円 (± 989)
このデータは小規模なのでモデル間の差は小さい。実務の大規模データになるほどLightGBMの速度優位が出やすくなる。
どのモデルをいつ使うか
| 状況 | おすすめ | 理由 |
|---|---|---|
| とりあえず試したい | Random Forest | チューニング不要・過学習しにくい |
| 精度を上げたい・中規模データ | XGBoost | 参考資料が豊富で試行錯誤しやすい |
| 大規模データ・速度重視 | LightGBM | 学習が速くメモリ効率が高い |
| 精度を最大化したい(コンペ等) | 3つをアンサンブル | 予測のばらつきを補い合える |
まとめ
- Random Forest・XGBoost・LightGBMはいずれも決定木ベースのアンサンブル学習
- Random Forestはバギング、XGBoost・LightGBMはブースティング
- まずRandom Forestで試し、精度を求めるならXGBoost→LightGBMと移行するのが定石
- 実務ではデータ量・速度・説明責任の要件で選ぶ
次回は教師なし学習として、クラスタリング(K-Means)と次元削減(PCA)を取り上げる予定。以前の記事(AIモデルの種類について)で概念としては触れたが、今回は実装を通じてより深く整理していく。