前提
lightgbmを用いて回帰問題を自作の損失関数で実行したい
デフォルトのrmseなどでは問題なく予測ができている
実現したいこと
lightgbmを用いて回帰問題を自作の損失関数で実行したいが、
適当な損失関数を与えても学習結果に違いがみられない
損失関数を乱数や定数にしても学習できてしまっています
発生している問題・出力メッセージ
[1] Test's l2: 67.3008 Test's custom_metrics: 0 [LightGBM] [Warning] No further splits with positive gain, best gain: -inf customが呼び出されました [2] Test's l2: 57.9106 Test's custom_metrics: 0 [LightGBM] [Warning] No further splits with positive gain, best gain: -inf customが呼び出されました [3] Test's l2: 50.4481 Test's custom_metrics: 0 [LightGBM] [Warning] No further splits with positive gain, best gain: -inf customが呼び出されました
該当のソースコード
import numpy as np import matplotlib.pyplot as plt plt.rcParams['font.family'] = 'Times New Roman' # Fonts from sklearn.model_selection import train_test_split import lightgbm as lgb from sklearn import datasets dataset=datasets.load_boston() data=dataset["data"] target=dataset["target"].reshape(-1,1) feature=dataset["feature_names"].flatten() data_train,data_test,target_train,target_test=train_test_split(data,target, test_size=0.3, random_state=999, shuffle=True) def custom_metrics(y_pred, data): """ 適当に作ったカスタム損失関数 """ print("customが呼び出されました") y_true = data.get_label() # lgb.Dataset() から 目的変数を取得 #score = np.mean(y_true - y_pred) ** 2 # 最小2乗和を最小化(一般的なもの) #score=np.random.uniform(0.1,1.0)# 損失関数がランダムなら学習結果もあべこべになるはず? score=0.0 # 損失関数が定数なら全く学習できないはず? # 返り値: 関数名,評価値,最大化問題かどうか return 'custom_metrics', score, False def train_lgb(train_x, train_y): """ lightGBMでデータセットを訓練する関数 (関数のドキュメント):https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.train.html lightgbm.train(params, train_set, num_boost_round=100, valid_sets=None, valid_names=None, feval=None, init_model=None, feature_name='auto', categorical_feature='auto', keep_training_booster=False, callbacks=None) """ # データセットを学習用と検証用に分割する x_tr, x_val, y_tr, y_val = train_test_split(train_x, train_y, test_size=0.3, shuffle=True, random_state=0) # LightGBM用のデータセットに入れる lgb_train = lgb.Dataset(x_tr, y_tr) lgb_valid = lgb.Dataset(x_val, y_val) # 回帰の問題のみカスタム損失関数を用いる params = { 'objective': "regression", 'boosting_type': 'gbdt', } model = lgb.train( params=params, # ハイパーパラメータをセット train_set=lgb_train, # 訓練データを訓練用にセット valid_sets=[lgb_valid], # 訓練データとテストデータをセット valid_names=['Test'], # データセットの名前をそれぞれ設定 feval=custom_metrics,) return model # 学習の実行 model=train_lgb(data_train,target_train) # 予測 pred_train=model.predict(data_train) pred_test=model.predict(data_test) # 描画 plt.figure() plt.scatter(target_train,pred_train) plt.scatter(target_test,pred_test) plt.show()
試したこと
損失関数を
score = np.mean(y_true - y_pred) ** 2 # 最小2乗和を最小化(一般的なもの) score=np.random.uniform(0.1,1.0)# 損失関数がランダムなら学習結果もあべこべになるはず? score=0.0 # 損失関数が定数なら全く学習できないはず?
として学習がうまくいかないようにしたものの正解値と予測値が一致している
⇒出力されたログを見ると"Test's l2: 67.3008 Test's custom_metrics: 0"となっており
設定していないL2が学習時の評価値として使われcustom_metricsは参考として算出されているだけのようだが
設定の変更方法が分かりませんでした
補足情報(FW/ツールのバージョンなど)
lgb.version :'3.3.1'
あなたの回答
tips
プレビュー