概要
GBDTをベースにしたLightGBM。
ハイパーパラメータのチューニングにoptunaを試してみたのでまとめる。
LightGBMとは
決定木をベースにした手法。
正確には GBDT (Gradient Boosting Decision Tree) という仕組みで動いており、
決定木を直列に繋いで正解との誤差を小さくしていくように学習する。
決定木を使った手法はいろいろあるが、例えばランダムフォレストは決定木を並列に繋いでアンサンブルを取るという点でGBDTと異なる。
GBDTを利用した有名な手法としてXGBoostがある。
一方LightGBMは近年Kaggleなどでもよく使われる手法で、XGBoostとほぼ変わらない精度で軽量である点が優れている。
LightGBMの使い方
- 以下のようにハイパーパラメータを指定する
- ここではmecticsとしてmap@12を指定してるが、必要に応じて変える
import lightgbm as lgb
params = {
'objective': 'lambdarank',
'metric': 'map',
'map_eval_at': [12],
'num_leaves': 63, # default = 31,
'learning_rate': 0.01, # default = 0.1
'feature_fraction': 0.8, # default = 1.0
'bagging_freq': 1, # default = 0
'bagging_fraction': 0.8, # default = 1.0
'random_state': 0, # default = None
}
num_round = 100
- 以下のようにtrainのときにparameterを渡してあげる
- LightGBMの場合はquery_listを渡す必要がある(本記事では詳細は割愛)
- num_roundは決定木を直列に何本繋ぐかを表している
- 適当に決め打ちで指定してもいいが、この値を大きめに設定しておいてearly stoppingでいい感じのとこで打ち切るのがおすすめ
- 無論trainのメトリクスは学習を続ければ続けるほど良くなるが、これでは過学習に陥ってしまうので、early stoppingではvalidationのメトリクスが変化しなくなったタイミングで止める
lgb_train = lgb.Dataset(train_x, train_y, group=query_list_train)
lgb_eval = lgb.Dataset(valid_x, valid_y, group=query_list_valid)
# training
model = lgb.train(params, lgb_train,
num_boost_round=num_round,
valid_names=['train', 'valid'],
valid_sets=[lgb_train, lgb_eval],
early_stopping_rounds=20
)
# prediction
pred = model.predict(test, num_iteration=model.best_iteration)
Optunaを使ってみる
OptunaにはLightGBM Tunerという機能があり、これを使うと超簡単にハイパーパラメータの探索をやってくれる。
やり方は
import lightgbm as lgb
を
import optuna.integration.lightgbm as lgb
にするだけ。
あとはlgb.train()実行時に勝手にハイパーパラメータの探索を行ってくれる
探索後のパラメータはmodel.params
で取得できる
各種パラメータの意味
objective
- 回帰ならregression
- ランク学習ならlambdarank
- などなど
metric
- メトリクスとして何を使うか
- ndcg, mapなどを指定できる
ndcg/map_eval_at
- NDCG/MAP@kのkを設定する
- [12, 24]など複数指定も可能
num_leaves
- 決定木の最大の葉の数
- 大きいほど複雑なモデルを作れるが、過学習になりやすい
- default: 31
learning_rate
- 学習率
- 学習するたびにどれくらいその結果を強く反映させるか
- 小さいほど細かなチューニングができるが、時間がかかる
- default: 0.1
feature_fraction
- Scikit-Learn APIでの名前: colsample_bytree
- 決定木ごとにランダムに抽出される列の割合
- 値が大きいほど過学習になりやすい
- default: 1.0
bagging_freq
- 設定した値のイテレーション毎にバギング実施する
- 大きいほど過学習になりやすい - default: 0
bagging_fraction
- Scikit-Learn APIでの名前: subsample
- 決定木ごとにランダムに抽出される行(標本)の割合
- 値が大きいほど過学習になりやすい
- default: 1.0
random_state
- default: None