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する
