LightGBMはKaggleでも大活躍している大変優れた機械学習アルゴリズムです。
今回はそのLightGBMで使い方に疑問があったのでこの疑問を解消するためにこの記事を書いています。
その疑問とは、「さらに精度を上げるためにValidationデータも含めてモデリングできないか?」というものです。
つまり、
一度学習したモデルの情報を引き継いだ状態でデータ数を増やして再学習させる。
ということがやりたいわけです。
以前の記事で、LightGBMの使い方に関する記事を執筆しているのでそちらもぜひ参考に
⇒忘れても大丈夫!すぐに使えるLightGBMの種類と使い方
Titanicのデータを準備
まずはデータ準備です。
かの有名なTitanicのデータを使うことにします。(kaggleからいつでもダウンロードできます)
データ詳細等の内容は省略していきます。
データを学習用、評価用に分けてモデリング
続いてモデリングですが、ここではScikit-learn APIを用いてモデリングしていきます。
以下、コード全文
import lightgbm as lgb
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
df=pd.read_csv('train.csv').drop(['Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'],axis=1)
df_test=pd.read_csv('test.csv').drop(['Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'],axis=1)
X = df.drop('Survived',axis=1)
y = df['Survived'] # データを学習用(説明変数/目的変数)、評価用(説明変数/目的変数)に分離
# データを分ける
X_train, X_validation, y_train, y_validation = train_test_split(X, y, test_size =0.3, random_state =0) # 学習データの指定
###Scikit-learn API###
# LightGBMのパラメータ設定。全て初期値でも良さそう
model_sc = lgb.LGBMClassifier(
objective='binary',
boosting= 'gbdt',
metric= 'binary_logloss',
num_leaves= 64,
min_data_in_leaf= 20,
max_depth= 7,
verbose= 0,
)
### パターン① validationあり、early_stoppingありで学習 ###
model_sc.fit(X_train,y_train,eval_set=[(X_validation, y_validation)],early_stopping_rounds=20)
# 予測実行
df_test['Survived']=model_sc.predict(df_test)
# 予測結果をcsvファイルに保存
df_test[['PassengerId','Survived']].to_csv('pred_sc.csv',index=False)
#######################################################################################
### パターン② 1回目のモデル情報を引き継ぎフルサイズで学習 ###
model_sc_full.fit(
pd.concat([X_train,X_validation]), # 全行の説明変数で学習
pd.concat([y_train,y_validation]), # 全行の目的変数
init_model=model_sc # ここに1回目のモデルを指定
)
# 予測実行
df_test['Survived']=model_sc.predict(df_test)
# 予測結果をcsvファイルに保存
df_test[['PassengerId','Survived']].to_csv('pred_sc.csv',index=False)
#######################################################################################
### パターン③ モデル情報を引き継がないでフルサイズで学習 ###
model_sc_full_no.fit(
pd.concat([X_train,X_validation]),
pd.concat([y_train,y_validation])
)
# 予測実行
df_test['Survived']=model_sc.predict(df_test)
# 予測結果をcsvファイルに保存
df_test[['PassengerId','Survived']].to_csv('pred_sc.csv',index=False)
今回、比較対象は次の3パターン
- パターン① validationあり、early_stoppingありで学習
- パターン② パターン①のモデル情報を引き継いでフルサイズで学習
- パターン③ モデル情報を引き継がないでフルサイズで学習
それぞれ、テストデータを使って予測して実際にKaggleに提出して精度を評価します。
結果 ”init_model”を指定することで精度改善がみられる
結果は「パターン② パターン①のモデル情報を引き継いでフルサイズで学習」が最も高い精度となりました。
パターン | 内容 | 精度(Accuracy) |
パターン① | validationあり、early_stoppingありで学習 | 0.66028 |
パターン② | パターン①のモデル情報を引き継ぎ、フルサイズで学習 | 0.67942 |
パターン③ | モデル情報を引き継がないでフルサイズで学習 | 0.67703 |
パターン②ではfit()の中身の”init_model”に過去に学習したモデル情報を指定することで、パターン①よりそれなりに精度向上が見られました。(そもそも学習データ数が増えているので当然と言えば当然?)
そして、同じ学習データ量である③と比較してもわずかに精度が上がっていることから、init_modelを指定することに意味はありそうです。
まとめ
- 全データを用いてLightGBMを再学習させるときは”init_model”にvalidationなどで学習したモデルを指定すると、モデル情報を引き継げるので精度が上がりそう
- この”init_model”はいったいなんの情報を引き継いでいるのだろうか…
early_stoppingの回数とか、LightGBMのパラメータを引き継いでいる? - Kaggleといったコンペではぜひ使っていきたい
コメント