AI競馬で回収率100%越えを目指して

はなむけ競馬場

python

xgboostのearly stoppingをしたモデルを保存する

投稿日:

xgboostを使うのにLearning APIとscikit APIみたいなのがあり、二通りで学習できるらしい。

どちらも特に変わらないみたいだが、学習モデルの保存時にはまったので書いておく。

学習モデルの保存にはscikit APIでモデルを構築したほうが良いみたいだが、競馬モデル作成にはLearning APIで作ってしまった。

書き換えようと思ったが、どうにもうまくいかなかった。

early stoppingで止めた回数の最適化されたモデルを保存したいのだが、Learning APIでsave_modelの機能を使っても、たぶん最後に学習したモデルを保存してしまう。

ほとんど過学習したようなモデルを保存してしまうので、汎化性能に劣ってしまう。

validationとtestの精度がかなり落ちてしまい、実際に使うときに意味のないものになってしまう。

Learning APIでモデルを保存しようとするときには、最適なearly stoppingの回数を指定する必要がある。

なので、

  1. 一旦、普通にearly stopping しておいて、model.best_ntree_limitの数字を配列にでも入れておく
  2. その後、1で保存しておいた数字をn_estimatorsに代入して、もう一回学習させる
  3. 2の時のモデルをsave_modelで保存する

#[247, 188, 195, 287, 199, 319, 215, 241]は1回目の学習で特定したrounds.append(model.best_ntree_limit)
for va_period,r in zip(va_period_list,[247, 188, 195, 287, 199, 319, 215, 241]):
    #学習と評価のインデックス
    is_tr = X_train["period"] != va_period
    is_va = X_train["period"] == va_period
    #学習データと評価データ
    tr_x,va_x = X_train[is_tr],X_train[is_va]
    tr_x = tr_x.drop(["period"],axis=1)
    va_x = va_x.drop(["period"],axis=1)
    #ラベル
    tr_y,va_y = y_train[is_tr],y_train[is_va]
    #lightgbm用に加工
    dtrain = xgb.DMatrix(tr_x.drop("weight",axis=1),weight=tr_x["weight"],label=tr_y)
    deval= xgb.DMatrix(va_x.drop("weight",axis=1),label=va_y,weight=va_x["weight"])
    dtest= xgb.DMatrix(X_test)
    evals = [(dtrain, 'train'), (deval, 'eval')]
    evals_result = {}
    #学習
    model = xgb.train(params,
                dtrain,
                num_boost_round=r,
                evals=evals,evals_result=evals_result,
                early_stopping_rounds=100)
    
    model.save_model("xgb_" + str(va_period) + ".json")
    #予測する
    y_pred = model.predict(dtest,ntree_limit = model.best_ntree_limit)
    
    #rounds.append(model.best_ntree_limit)</pre>
<pre>

-python

Copyright© はなむけ競馬場 , 2021 All Rights Reserved Powered by AFFINGER5.