myoshi11
@myoshi11

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

optunaで発見した最適パラメータをlightgbmに与えて予測すると精度が大幅に落ちる

解決したいこと

機械学習初学者です。
現在あるコンペに参加しており、lightgbmで予測をしております。

それにあたり、optunaでハイパーパラメータを最適化してlightgbmに与えて予測をしたのですが、どうもリーダーボードに投稿した時の結果が大幅に悪くなります。

考えられる要因は何でしょうか?
あまり、ハイパーパラメータそれぞれの意味が分かっておらず、それぞれの探索範囲が適切ではないかもしれません。
また、optunaで最適した結果精度が落ちることはよくあることなのでしょうか?

ご回答いただけますと幸いです。よろしくお願いいたします。

該当するソースコード

###optunaで最適なパラメータを発見
def objective(trial):
    params_tuning = {
        "num_leaves": trial.suggest_int("num_leaves",2,200),
        "min_data_in_leaf": trial.suggest_int("min_data_in_leaf", 1,30),
        "max_bin" : trial.suggest_int("max_bin", 30,400),
        "bagging_fraction" : trial.suggest_float("bagging_fraction", 0.8,0.95),
        "feature_fraction": trial.suggest_float("feature_fraciton", 0.35,0.65),
        "min_gain_to_split":trial.suggest_float("min_gain_to_split", 0.01, 1, log=True),
        "lambda_l1": trial.suggest_float ("lambdal1", 0.01,1,log=True),
        "lambda_l2": trial.suggest_float ("lambdal2", 0.01,1,log=True),
    }
    
    params_tuning.update(params_base)
    lgb_train = lgb.Dataset(X_tr, y_tr)
    lgb_eval = lgb.Dataset(X_va, y_va)
    
    model = lgb.train(params_tuning,
                      lgb_train,
                      num_boost_round=10000,
                      valid_sets=[lgb_train, lgb_eval],
                      valid_names=["train", "valid"],
                      callbacks=[lgb.early_stopping(100), lgb.log_evaluation(500)]
                     )
    y_va_pred = model.predict(X_va, num_iteration=model.best_iteration)
    score = mean_absolute_error(y_va, y_va_pred)
    print("")
    return score

import optuna 
study = optuna.create_study(sampler=optuna.samplers.RandomSampler(seed=0), direction="minimize")
study.optimize(objective, n_trials=200)

trial = study.best_trial
params_best = trial.params
display(params_best)

#######発見したパラメータで学習

from sklearn.model_selection import KFold


valid_scores = []
models = []
oof = np.zeros(len(X))

kf = KFold(n_splits=5, shuffle=True, random_state=0)
for fold, (tr_idx, va_idx) in enumerate(kf.split(X)):
    X_tr = X.iloc[tr_idx]
    X_va = X.iloc[va_idx]
    y_tr = y.iloc[tr_idx]
    y_va = y.iloc[va_idx]
    
    lgb_train = lgb.Dataset(X_tr, y_tr)
    lgb_eval = lgb.Dataset(X_va, y_va, reference=lgb_train)
    
    model = lgb.train(params_best, lgb_train, num_boost_round=10000, valid_sets=[lgb_train, lgb_eval],
                     valid_names=["train", "valid"], callbacks=[lgb.early_stopping(100), lgb.log_evaluation(500)])
    
    y_va_pred = model.predict(X_va, num_iteration=model.best_iteration)
    score = mean_absolute_error(y_va, y_va_pred)
    print("fold{} MAE valid:{:.2f}".format(fold+1, score))
    print("")
    
    valid_scores.append(score)
    models.append(model)
    oof[va_idx] = y_va_pred

cv_score = np.mean(valid_scores)
print("CV score{:.2f}".format(cv_score))


0

2Answer

どうもリーダーボードに投稿した時の結果が大幅に悪くなります。

「optunaでハイパーパラメータを最適化」前のモデルを再度投稿すると結果が良くなるという事でしょうか?

0Like

Comments

  1. @myoshi11

    Questioner

    おっしゃる通りです。
    パラメータ最適化前のデフォルトパラメータのモデルの方が精度が良くなります。

  2. あれ?質問文の「結果」とは順位のことかと思っていましたがそうではなく手元のデータでの「モデルの精度」のことでしたか?

  3. @myoshi11

    Questioner

    言葉足らずですみません、手元のデータでの「モデルの精度」と投稿した順位どちらにおいてもスコアが悪化します。

  4. oputunaではmean_absolute_errorを指標にしていてテストではKFoldを使う事の差異という事はありませんか?

元の値が探索範囲におらず、また元の方が最適ならそのような状態になるのではないでしょうか
元の値と最適化後の値がそれぞれどのようか比較してみてはいかがでしょうか

0Like

Comments

  1. @myoshi11

    Questioner

    ありがとうございます。元の値も探索範囲に含めているのですが、別のパラメータが採用され、精度が悪化します。最適化のコードがどこかよくないのでしょうか。。

Your answer might help someone💌