LightGBMによる予測モデルの構築とOptunaを用いたハイパーパラメータ調整の利用テンプレ
データの読み込み
#ライブラリのインポート
import pandas as pd
import numpy as np
from tqdm import tqdm
#データの読み込み
TRAIN = pd.read_csv('train.csv')
TEST = pd.read_csv('test.csv')
TRAIN['CAT']='train'
TEST['CAT']='test'
DATA = pd.concat([TRAIN, TEST], axis=0)
DATA = DATA.reset_index(drop=True)
DATA = pd.concat([DATA['y'], DATA.drop('y', axis=1)], axis=1)
###############
#特徴量作成
###############
訓練用データとテストデータを読み込む。
この後のフェーズで特徴量を作ることになるが、別々に作ると作業が面倒なのでtrain/testを縦に結合して処理していく。その際にどちらのデータかわからなくなるのでカテゴリ(CAT)としてtrainとtestそれぞれ記載しておく。
結合の際はindexが重複してしまうので「.reset_index」でインデックスを振り直す。
「drop=True」は旧indexを残すかどうかの引数で、不要なのでTrueに設定
特徴量を追加していくと列が長くなっていくため、目的変数を一番左に移動させると作業し易い。
データの分割
TRAIN = DATA[DATA['CAT']=='train'].drop('CAT', axis=1)
TEST = DATA[DATA['CAT']=='test'].drop('CAT', axis=1)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(TRAIN.iloc[:,1:],TRAIN['y'], random_state=32, test_size=.25)
特徴量作成後、再度訓練用と検証用データに分割する。カテゴリ列は不要なので削除する。
精度の検証用にtrainデータを更にtrain/testに分割する。
sklearnのtrain_test_splitを利用して、X_train, X_test, y_train, y_testに分割する。
目的変数yはTRAINデータの一番左端に移動させたので、残りの特徴量は「TRAIN.iloc[:,1:]」で選択できる。
train/testの比率は「test_size」で設定でき、今回は25%をtestに利用。
optunaを使ったハイパーパラメータの調整
import optuna
from lightgbm import LGBMRegressor
#from lightgbm import LGBMClassifier
from sklearn.metrics import mean_squared_error
def objective(trial):
max_depth = trial.suggest_int('max_depth', 2, 32)
n_estimators = trial.suggest_int('n_estimators', 100, 10000)
lgb = LGBMRegressor(max_depth=max_depth
, n_estimators=n_estimators
, random_state = 1)
lgb.fit(X_train, y_train)
return mean_squared_error(y_test, lgb.predict(X_test), squared=False)
#optunaの実行
study = optuna.create_study()
study.optimize(objective, n_trials=100)
study.best_params
値を予測する場合はLGBMRegressorを、カテゴリを予測する場合はLGBMClassifierを利用する。
コンペの評価方法に応じてreturnの返り値を設定する。今回はRMSEの場合で記載。
optunaは値を最小化するように試行錯誤していくため、精度が上がるに連れて値が大きくなるようなaccuracyの場合は「1 – accuracy_score」となるよう工夫する必要がある。
from sklearn.metrics import accuracy_score
#中略
return 1- accuracy_score(y_test, lgb.predict(X_test))
モデルの作成と予測
#optunaのハイパーパラメータを利用してモデルを作成
lgb = LGBMRegressor(max_depth=study.best_params['max_depth']
, n_estimators=study.best_params['n_estimators']
, random_state = 1)
lgb.fit(TRAIN.iloc[:,1:],TRAIN['y'])
#モデルを予測データ
pred = lgb.predict(TEST.iloc[:,1:])
#元のテストデータのデータフレームと結合させる
TEST_pred = TEST.copy()
TEST_pred['pred'] = pred
#提出用のデータ形式に変更して保存
submit = TEST_pred[['ID','pred']]
submit.to_csv('submit.csv' , header = False, index = False )
optunaで得られたmax_depthとn_estimatorsを設定して学習する
提出の際はテストデータの一部の列と予測結果を合わせて提出することが多く、一旦元のデータフレームと結合した後に必要な形式に変更して保存する。(この場合はIDと予測値のpredを選択)
ヘッダー不要、index不要の場合が多いので「header = False, index = False」を設定する
コピペ用全体コード
#ライブラリのインポート
import pandas as pd
import numpy as np
from tqdm import tqdm
##############################
#データの読み込み
##############################
TRAIN = pd.read_csv('train.csv')
TEST = pd.read_csv('test.csv')
TRAIN['CAT']='train'
TEST['CAT']='test'
DATA = pd.concat([TRAIN, TEST], axis=0)
DATA = DATA.reset_index(drop=True)
DATA = pd.concat([DATA['y'], DATA.drop('y', axis=1)], axis=1)
###############
#特徴量作成
###############
##############################
#データ分割
##############################
TRAIN = DATA[DATA['CAT']=='train'].drop('CAT', axis=1)
TEST = DATA[DATA['CAT']=='test'].drop('CAT', axis=1)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(TRAIN.iloc[:,1:],TRAIN['y'], random_state=32, test_size=.25)
##############################
#optunaでのパラメータ調整
##############################
import optuna
from lightgbm import LGBMRegressor
#from lightgbm import LGBMClassifier
from sklearn.metrics import mean_squared_error
def objective(trial):
max_depth = trial.suggest_int('max_depth', 2, 32)
n_estimators = trial.suggest_int('n_estimators', 100, 10000)
lgb = LGBMRegressor(max_depth=max_depth
, n_estimators=n_estimators
, random_state = 1)
lgb.fit(X_train, y_train)
return mean_squared_error(y_test, lgb.predict(X_test), squared=False)
#optunaの実行
study = optuna.create_study()
study.optimize(objective, n_trials=100)
study.best_params
##############################
#モデル作成と予測
##############################
lgb = LGBMRegressor(max_depth=study.best_params['max_depth']
, n_estimators=study.best_params['n_estimators']
, random_state = 1)
lgb.fit(TRAIN.iloc[:,1:],TRAIN['y'])
#モデルを予測データ
pred = lgb.predict(TEST.iloc[:,1:])
#元のテストデータのデータフレームと結合させる
TEST_pred = TEST.copy()
TEST_pred['pred'] = pred
#提出用のデータ形式に変更して保存
submit = TEST_pred[['ID','pred']]
submit.to_csv('submit.csv' , header = False, index = False )