lightGBMについて(ざっくり)
- 回帰・クラス分類手法の一つ(XGBoostと並んでKaggleでもよく使われる人気の手法)
- 決定木ベースの勾配ブースティング手法(Gradient Boosting Dicision Tree)
- アンサンブル学習(複数のモデルの多数決で出力を決める手法)が使われている。
- XGBoostとLightGBMは、大枠はほとんど同じフレームワークと考えてOK
- LightGBMは計算量をヒストグラムとして扱うため高速に計算を実行できる。(これはXGBoostのパラメータ tree_method=histとした場合と同様)
技術的な内容の詳細は「LightGBM 徹底入門」が分かりやすい。
勾配ブースティングとは
- ブースティング :今までに学習したモデルの情報を使って、新たのモデルを構築することでデータの学習を進める方法
(クラス分類で誤分類されたサンプルや、回帰モデルで誤差の大きかったサンプルを改善するように新たなモデルが構築される) - 勾配:ブースティングにおいて、前回の学習したモデルの目的関数(損失関数)の勾配(Gradient)を用いて新たなモデルを構築する。
lightGBM のハイパーパラメータについて
Training APIとscikit-learn API のどちらを使用するかでパラメータの名前が異なる。
パラメータとモデルの性質についてのまとめ
よく調整するもの
パラメータ名 (Training API) | パラメータ名 (Scikit-learn API) | 説明 | 因数 |
---|---|---|---|
lambda_l1 | reg_alpha | L1正則化項の係数 | 0~ (float|log) デフォルト:0 |
lambda_l2 | reg_lambda | L2正則化項の係数 | 0~ (float|log) デフォルト:0 |
num_leaves | num_leaves | 1本の木の最大葉枚数 | 0~131072(int) デフォルト:31 |
feature_fraction | colsample _bytree | 各決定木においてランダムに抽出される列の割合 | 0~1(float) デフォルト:1.0 |
bagging_fraction | subsample | 各決定木においてランダムに抽出される標本の割合 | 0~1(int) デフォルト:1.0 |
bagging_freq | subsample_freq | ここで指定したイテレーション毎にバギング実施 | 0~(int) デフォルト:0 |
min_data_in_leaf | min_child_samples | 1枚の葉に含まれる最小データ数 | 0~ (int) デフォルト:20 |
各パラメータの大小と過剰適合の関係
小 <<<<< | パラメータ名 | <<<<< 大 |
---|---|---|
過剰適合 | lambda_l1 (reg_alpha) | 保守的 |
過剰適合 | lambda_l2 (reg_lambda) | 保守的 |
保守的 | num_leaves | 過剰適合 |
保守的 | feature_fraction (colsample _bytree) | 過剰適合 |
保守的 | bagging_fraction (subsample) | 過剰適合 |
保守的 | bagging_freq (subsample_freq) | 過剰適合 |
過剰適合 | min_data_in_leaf (min_child_samples) | 保守的 |
その他のパラメータ
パラメータ名 | 説明 | 引数 |
---|---|---|
verbosity | 学習途中の情報を表示するかどうか | >1:Debug 1:Info 0:Error(Warning) -1:Fatal デフォルト:1 |
n_estimators | ブースティングのラウンド数 | 0~ (int) デフォルト:100 |
random_state | 乱数シードの値 | int |
n_jobs | LightGBM に使用するスレッド数 | 0:デフォルトの数 -1:最大数で指定(おそらく) デフォルト:0 |
コード
準備
lightGBMのインストール
conda install -c conda-forge lightgbm
データの準備など
import numpy as np
import pandas as pd
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import lightgbm as lgb
boston = load_boston()
df_X = pd.DataFrame(boston.data, columns=boston.feature_names)
df_y = pd.DataFrame(boston.target,columns=['Price'])
X_train, X_test, y_train, y_test = train_test_split(df_X, df_y,test_size=0.3)
通常の方法
# データセットを生成する
lgb_train = lgb.Dataset(X_train, y_train)
# LightGBMのハイパーパラメータ
params = {'objective': 'regression'}
# 上記のパラメータでモデルを学習する
model = lgb.train(params, lgb_train)
y_pred = model.predict(X_test)
# RMSE を計算する
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
print('RMSE:',round(rmse,3))
"""output
RMSE: 3.59
"""
#各変数の重要度を出す場合
"""
model.feature_importance()
#pandas DataFrameに出力
df_importance = pd.DataFrame(model.feature_importance(),
index=df_X.columns,
columns=['importance'])
"""
各手法のパラメータ
- 回帰問題:'regression'
- 分類問題:'binary'
- 多クラス類問題:'multiclass'
scikit-learn APIを使用する方法
model = lgb.LGBMRegressor()
#回帰問題の場合
#model = lgb.LGBMClassifier()
model.fit(X_train, y_train)
# テストデータを予測する
y_pred = model.predict(X_test)
# RMSEを計算する
mse = np.sqrt(mean_squared_error(y_test, y_pred))
print('RMSE:',round(rmse,3))
"""output
RMSE: 3.59
"""
#各変数の重要度を出す場合
"""
model.feature_importance()
#pandas DataFrameに出力
df_importance = pd.DataFrame(model.feature_importances_,
index=df_X.columns,
columns=['importance'])
"""
最適なブーストラウンド数を自動で決める方法
ブーストラウンド数は少なすぎると過小適合、多すぎると学習データに過剰適合してしまう恐れがあるため、適切な値を設定する必要がある。
early_stopping_roudsオプションを使うと訓練データとともに精度評価用データをモデルに渡ことで、モデルの性能が頭打ちになったところで学習を打ち切ることができ、最適なブーストラウンド数を決めることができる。
(評価用データはvalid_sets オプションで渡す。またこの際に精度評価に用いる指標も指定する必要がある)
- n_estimators:最大のブーストラウンド数(何回学習するか)
- early_stopping_rounds:何ラウンド進めた時に予測性能向上みられなかった時に学習を打ち切る。
精度評価に用いる指標
回帰(regression)
- 誤差平均:'mae'
- 二乗誤差:'mse'
- 平均平方二乗誤差:'rmse'
二値分類
- クロスエントロピー:'binary_logloss'
- 正答率:'binary_error'
多クラス分類
- Logarthmic Loss:'multi_logloss'
- 正答率:'multi_error'
通常の方法
# データセットを生成する
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test)
params = {'objective': 'regression',
'metric': 'rmse',
'early_stopping_rounds':10,
'n_estimators':10000}
# モデル作成時に精度評価用データもわたす。
model = lgb.train(params, lgb_train, valid_sets=lgb_eval)
# 予測時には先ほど決めた学習回数を用いる。
y_pred = model.predict(X_test, num_iteration=model.best_iteration)
# RMSE を計算する
mse = np.sqrt(mean_squared_error(y_test, y_pred))
print('RMSE:',round(rmse,3))
"""output
RMSE: 3.59
"""
scikit-learn API を用いる方法
model = lgb.LGBMRegressor(n_estimators=10000)
#各ラウンドでの予測精度などを格納する辞書
evals_result = {}
model.fit(X_train, y_train,
eval_set=[(X_train, y_train),(X_test, y_test)],
eval_metric='mse',
early_stopping_rounds=10,
callbacks=[lgb.callback.record_evaluation(evals_result)],
)
print('best iteration:',model.best_iteration_)
y_pred = model.predict(X_test)
mse = np.sqrt(mean_squared_error(y_test, y_pred))
print('RMSE:',round(rmse,3))
"""output
RMSE: 3.59
"""
参考
- LightGBM 徹底入門
- LightGBMのパラメータチューニングまとめ(qiita)
- LightGBMのパラメータ(引数)
- Python: LightGBM を使ってみる
- LightGBM(parameters)
関連書籍
リンク
リンク
リンク