LightGBMの使い方
LightGBMは、独自のクラスと、sklearnライクなクラスがあります。
sklearnライクなクラスでは、
- 分類問題のLightGBMClassifier
- 回帰問題のLightGBMRegression
LightGBM
2値の分類問題
パラメータの‘objective’に”binary”を渡す。
#====パラメータ==== params = {'objective': "binary", 'boosting_type': "gbdt", 'metric': "auc" } #====データセット==== dtrain = lgb.Dataset(X_train, label=y_train) dvalid = lgb.Dataset(X_valid, label=y_valid) #====学習==== clf = lgb.train(params, dtrain, 10000, valid_sets = [dtrain, dvalid], verbose_eval=500, early_stopping_rounds=500) #====予測==== y_pred = clf.predict(text) #====0.5以上を1とする==== y_pred = (y_pred> 0.5).astype(int)
多値の分類問題
パラメータの‘objective’に”multiclass”を渡す。
#====予測==== y_pred = clf.predict(test) #====argmaxをとる==== y_pred = np.argmax(y_pred, axis=1).astype(int)
回帰問題
パラメータの‘objective’に”regression”を渡す。
‘metric’は、’mean_absolute_error’, ‘mean_squared_error’, ‘rmse’から選ぶ。
feature_importance
特徴量の重要度を示す。
clf.feature_importance()
LightGBM.Classifier
LightGBM.Regressor
optunaを使ったパラメータチューニング
パラメータチューニングしたい学習を定義したobjectivesを用意します。
この関数の返却値は、評価値(metrics_score)です。
def objectives(trial): #==== 最適化したいパラメータ ==== lambda_l1 = trial.suggest_loguniform('lambda_l1', 1e-8, 10.0) lambda_l2 = trial.suggest_loguniform('lambda_l2', 1e-8, 10.0) learning_rate = trial.suggest_uniform('learning_rate', 0, 1.0) feature_fraction = trial.suggest_uniform('feature_fraction', 0, 1.0) bagging_fraction = trial.suggest_uniform('bagging_fraction', 0, 1.0) bagging_freq = trial.suggest_int('bagging_freq', 5, 500) num_leaves = trial.suggest_int('num_leaves', 5, 1000) num_iterations = trial.suggest_int('num_iterations', 5, 1000) min_child_samples = trial.suggest_int('min_child_samples', 5, 500) min_child_weight = trial.suggest_int('min_child_weight', 5, 500) max_dapth = trial.suggest_int('max_dapth', 5, 100) #==== 定義したパラメータ ==== params = {"objective": "binary", "boosting_type": "gdbt", "metric": "auc", "lambda_l1": lambda_l1, "lambda_l2": lambda_l2, "learning_rate": learning_rate, "feature_fraction": feature_fraction, "bagging_fraction": bagging_fraction, "bagging_freq": bagging_freq, "num_leaves": num_leaves, "num_iterations": num_iterations, "min_child_samples": min_child_samples, "min_child_weight": min_child_weight, "max_dapth": max_dapth, "verbosity": -1 } NFOLD=5 folds = StratifiedKFold(n_splits=NFOLD, shuffle=True, random_state=2020) splits = folds.split(X, y) scores = 0 for fold_n, (train_index, valid_index) in enumerate(splits): X_train, X_valid = X.iloc[train_index], X.iloc[valid_index] y_train, y_valid = y.iloc[train_index], y.iloc[valid_index] dtrain = lgb.Dataset(X_train, label=y_train) dvalid = lgb.Dataset(X_valid, label=y_valid) clf = lgb.train(params, dtrain, 10000, valid_sets = [dtrain, dvalid], verbose_eval=1000, early_stopping_rounds=500, ) y_pred_val = clf.predict(X_valid) y_pred_val = (y_pred_val > 0.5).astype(int) score = f1_score(y_pred_val, y_valid) scores += score/NFOLD print(f"{fold_n}Fold: {score}") print("F1:", scores) return scores # scoreの最大化を目指す"maximize"。最小化の場合は"minimize" opt = optuna.create_study(direction='maximize') opt.optimize(objectives, n_trials=100) trial = opt.best_trial print(trial.params) params = {'objective': "binary", 'boosting_type': "gdbt", 'metric': "auc", "verbosity": -1 } params.update(**params, **trial.params)
metricsの変更
まず、変更するmetricsを関数を作る。
返却値を次のようにする。
def metrics(y_hat, data): return "metrics名", metrics_score, True
この作った関数をtrain時の引数fevalに渡す。
F1スコアの場合
from sklearn.metrics import f1_score #==== カスタムmetrics ==== def f1_metrics(y_hat, data): y_true = data.get_label() y_hat = np.round(y_hat) # scikits f1 doesn't like probabilities return 'f1', f1_score(y_true, y_hat), True #==== train ==== #fevalに渡す clf = lgb.train(params, dtrain, valid_sets= [dvalid], verbose_eval=25, feval=f1_metric)
f1_score metric in lightgbm|stack overflow
参考
Optuna+KerasでCNNのハイパーパラメータを最適化
OptunaとLightGBMを使って、Kaggle過去コンペにsubmitする