LightGBMの精度をあげるためには、ハイパーパラメータのチューニングを行う必要があります。
しかし、LightGBMのパラーメータ数は非常に多く、自分のような初心者が調節するのは非常に困難です。
今回はOptunaを使用して、ハイパーパラメータのチューニングを行う過程で、ハイパーパラメータの意味を理解していきます。
LightGBMの公式ドキュメント
「まずは、公式ドキュメントをよめ。」と言われますが、パラメーターの数の多さにびびります。
公式ドキュメントを参照しながら、進めていきます。
・LightGBMの公式ドキュメント
https://lightgbm.readthedocs.io/en/stable/index.html
・Optunaの公式ドキュメント
https://optuna.readthedocs.io/en/stable/index.html
Optunaによるハイパーパラメータのチューニングのコード例
# 固定するパラメータ
fixed_params = {
'objective': 'binary',
'metric': 'auc',
'boosting_type': 'gbdt',
'verbosity': -1,
'random_state': 42,
'num_threads': 1
}
# optunaで探索するパラメータ
def objective(trial):
params = {
'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.2, log=True),
'num_leaves': trial.suggest_int('num_leaves', 31, 255),
'max_depth': trial.suggest_int('max_depth', 5, 20),
'min_data_in_leaf': trial.suggest_int('min_data_in_leaf', 20, 100),
'bagging_fraction': trial.suggest_float('bagging_fraction', 0.6, 1.0),
'feature_fraction': trial.suggest_float('feature_fraction', 0.6, 1.0),
'lambda_l1': trial.suggest_float('lambda_l1', 0.0, 10.0),
'lambda_l2': trial.suggest_float('lambda_l2', 0.0, 10.0),
}
# パラメータの更新
params.update(fixed_params)
# Dataset形式に変換
train_data = lgb.Dataset(X_train, label=y_train, categorical_feature=categorical_features)
valid_data = lgb.Dataset(X_valid, label=y_valid, categorical_feature=categorical_features)
# モデルの学習
model = lgb.train(
params,
train_data,
valid_sets=[valid_data],
num_boost_round=1000,
callbacks = [early_stopping(stopping_rounds=50), log_evaluation(period=100)])
# AUCスコアの表示
y_pred = model.predict(X_valid, num_iteration=model.best_iteration)
auc = roc_auc_score(y_valid, y_pred)
return auc
# Optunaで最適化
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=30)
print('Best AUC:',study.best_value)
print('Best Parameters:')
for k, v in study.best_params.items():
print(f" {k}: {v}")
# 最適パラメータ保存
best_params = fixed_params.copy()
best_params.update(study.best_params)固定するパラメータの詳細
fixed_params = {
'objective': 'binary',
'metric': 'auc',
'boosting_type': 'gbdt',
'verbosity': -1,
'random_state': 42,
'num_threads': -1
}固定するパラメータについてそれぞれ公式ドキュメントをみていきます。
objective
https://lightgbm.readthedocs.io/en/stable/Parameters.html#
objective🔗︎, default =regression, type = enum, options:regression,regression_l1,huber,fair,poisson,quantile,mape,gamma,tweedie,binary,multiclass,multiclassova,cross_entropy,cross_entropy_lambda,lambdarank,rank_xendcg, aliases:objective_type,app,application,loss
意味:目的関数(損失関数)を指定。
デフォルトは’regression'(回帰)。
・2クラス分類→’binary’
・多クラス分類→’multiclass’
metric
metric🔗︎, default ="", type = multi-enum, aliases:metrics,metric_typeshttps://lightgbm.readthedocs.io/en/stable/Parameters.html#
- metric(s) to be evaluated on the evaluation set(s)
意味:モデル評価指標を指定。
デフォルトは””。LightGBMがタスクに応じて選択する。
objective=’binary’の場合は、binary_loglossが自動的に選択される。
・ROC曲線の面積→’auc’
・2値分類の損失関数→’binary_logloss’
*損失関数:確率が正解から遠いほど大きなペナルティを与える。分類結果そのものより、予測確率の信頼性を重視したいときに有効。
boosting_type
https://lightgbm.readthedocs.io/en/stable/Parameters.html#
boosting🔗︎, default =gbdt, type = enum, options:gbdt,rf,dart, aliases:boosting_type,boost
gbdt, traditional Gradient Boosting Decision Tree, aliases:gbrtrf, Random Forest, aliases:random_forestdart, Dropouts meet Multiple Additive Regression Trees
- Note: internally, LightGBM uses
gbdtmode for the first1 / learning_rateiterations
意味:ブースティングのアルゴリズム種類を指定。
デフォルトは’gbdt’。基本はgbdtでおk
・’gbdt’:Gradient-based One-Side Sampling(一般的な勾配ブースティング)
・’dart’:Dropouts meet Multiple Additive Regression Trees(過学習に強い)
・’goss’:Gradient-based One-Side Sampling(高速な勾配計算)。
verbosity
https://lightgbm.readthedocs.io/en/stable/Parameters.html#
verbosity🔗︎, default =1, type = int, aliases:verbose
- controls the level of LightGBM’s verbosity
< 0: Fatal,= 0: Error (Warning),= 1: Info,> 1: Debug
意味:ログ出力の詳細レベル。
デフォルトは1。
・<0 :致命的なエラーだけ表示
・=0 :エラーや警告だけ表示
・=1 :進捗などの通常の情報も表示
・>1 :デバッグ情報まで詳しく表示
num_threads
https://lightgbm.readthedocs.io/en/stable/Parameters.html#
num_threads🔗︎, default =0, type = int, aliases:num_thread,nthread,nthreads,n_jobs
- used only in
train,predictionandrefittasks or in correspondent functions of language-specific packages- number of threads for LightGBM
0means default number of threads in OpenMP- for the best speed, set this to the number of real CPU cores, not the number of threads (most CPUs use hyper-threading to generate 2 threads per CPU core)
- do not set it too large if your dataset is small (for instance, do not use 64 threads for a dataset with 10,000 rows)
- be aware a task manager or any similar CPU monitoring tool might report that cores not being fully utilized. This is normal
- for distributed learning, do not use all CPU cores because this will cause poor performance for the network communication
- Note: please don’t change this during training, especially when running multiple jobs simultaneously by external packages, otherwise it may cause undesirable errors
意味:LightGBM が トレーニング・予測・再学習時に使うスレッド数(CPUの並列処理の数)
デフォルトは0。OpenMP(内部ライブラリ)に任せる(自動でコア数を判断)。
Optunaで探索するパラメータの詳細
# optunaで探索するパラメータ
def objective(trial):
params = {
'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.2, log=True),
'num_leaves': trial.suggest_int('num_leaves', 31, 255),
'max_depth': trial.suggest_int('max_depth', 5, 20),
'min_data_in_leaf': trial.suggest_int('min_data_in_leaf', 20, 100),
'bagging_fraction': trial.suggest_float('bagging_fraction', 0.6, 1.0),
'feature_fraction': trial.suggest_float('feature_fraction', 0.6, 1.0),
'lambda_l1': trial.suggest_float('lambda_l1', 0.0, 10.0),
'lambda_l2': trial.suggest_float('lambda_l2', 0.0, 10.0),
}Optunaで探索するパラメータをみていく。
Optunaのtrial.suggest()メソッド
https://optuna.readthedocs.io/en/stable/reference/generated/optuna.trial.Trial.html#optuna.trial.Trial
suggest_categorical()Suggest a value for the categorical parameter. suggest_discrete_uniform(name, low, high, q)Suggest a value for the discrete parameter. suggest_float(name, low, high, *[, step, log])Suggest a value for the floating point parameter. suggest_int(name, low, high, *[, step, log])Suggest a value for the integer parameter. suggest_loguniform(name, low, high)Suggest a value for the continuous parameter. suggest_uniform(name, low, high)Suggest a value for the continuous parameter.
各メソッドは、探索すべきハイパーパラメータの「候補値」をOptuna に提案させます。
指定した範囲や条件に従って、Optunaが自動的に探索していきます。
・suggest_int(name, low, high) :整数値を範囲内から提案
・suggest_float(name, low, high, log=False):連続値を範囲内から提案(log=Trueで対数スケール)
・suggest_categorical(name, choices):カテゴリ変数をリストから提案
learning_rate
https://lightgbm.readthedocs.io/en/stable/Parameters.html#
learning_rate🔗︎, default =0.1, type = double, aliases:shrinkage_rate,eta, constraints:learning_rate > 0.0
- shrinkage rate
- in
dart, it also affects on normalization weights of dropped trees
意味:学習の一回ごとの更新のステップサイズを決めるパラメータ。
「学習率」または「縮小率」とも呼ばれます。
LightGBMでは、各ラウンド(木を1本追加)ごとに予測を更新していきますが、
新しい予測=前の予測+learning_rate×新しい木の予測
のように、新しい木の寄与を弱めて、少しずつ学習する仕組みです。
デフォルトは0.1。
低いと精度は上がりやすいが時間がかかる。高いと早く収束するが過学習リスクあり。
num_leaves
https://lightgbm.readthedocs.io/en/stable/Parameters.html#
num_leaves🔗︎, default =31, type = int, aliases:num_leaf,max_leaves,max_leaf,max_leaf_nodes, constraints:1 < num_leaves <= 131072
- max number of leaves in one tree
意味:1本の決定木(tree)で使える「最大の葉の数」を指定します。
葉とは?
決定木における「分岐の終点」。
分類や回帰の最終的な出力が決まる場所。
木の構造において、葉の数が多いほど 複雑な表現が可能(=精度が上がる可能性)。
デフォルトは31。
・精度を高めたい→num_leavesを大きくする
・過学習を防ぐ→num_leavesを小さくする
max_depth
https://lightgbm.readthedocs.io/en/stable/Parameters.html#
max_depth🔗︎, default =-1, type = int
- limit the max depth for tree model. This is used to deal with over-fitting when
#datais small. Tree still grows leaf-wise<= 0means no limit
意味:決定木が「どこまで深く分岐できるか(=分割できるか)」を制限するパラメータです。
深くなるほど複雑なモデルになります。
デフォルトは-1。深さの制限なし。
| パラメータ | 意味 | 効果 |
|---|---|---|
num_leaves | 葉の最大数 | モデルの複雑さを制御する主パラメータ |
max_depth | 深さの上限 | 構造上の過学習制御に使う補助的パラメータ |
num_leaves をメインにチューニングしつつ、必要なら max_depthを組み合わせるのが一般的。
min_data_in_leaf
https://lightgbm.readthedocs.io/en/stable/Parameters.html#
min_data_in_leaf🔗︎, default =20, type = int, aliases:min_data_per_leaf,min_data,min_child_samples,min_samples_leaf, constraints:min_data_in_leaf >= 0
- minimal number of data in one leaf. Can be used to deal with over-fitting
- Note: this is an approximation based on the Hessian, so occasionally you may observe splits which produce leaf nodes that have less than this many observations
意味:1つの葉(leaf)に含めることができる 最小のデータ数 を指定します。
何を制御しているか?
決定木を分割する際に、「この分割をしたら、どちらかの葉にデータ数が少なすぎる」というのを防ぎます。
葉に十分なデータがあるときだけ、分割を許して、過学習を防止します。
デフォルトは20。データ量によって調整する。
bagging_fraction
https://lightgbm.readthedocs.io/en/stable/Parameters.html
bagging_fraction🔗︎, default =1.0, type = double, aliases:sub_row,subsample,bagging, constraints:0.0 < bagging_fraction <= 1.0
- like
feature_fraction, but this will randomly select part of data without resampling- can be used to speed up training
- can be used to deal with over-fitting
- Note: to enable bagging,
bagging_freqshould be set to a non zero value as well
意味:各決定木の学習に使うデータの割合(レコード数の比率)を指定するパラメータ
デフォルトは1.0。
何をするのか?
学習時に、全データからランダムに一部だけ使うようにすることで:
- 学習を速くする
- 過学習(overfitting)を防ぐ
feature_fraction
https://lightgbm.readthedocs.io/en/stable/Parameters.html
feature_fraction🔗︎, default =1.0, type = double, aliases:sub_feature,colsample_bytree, constraints:0.0 < feature_fraction <= 1.0
- LightGBM will randomly select a subset of features on each iteration (tree) if
feature_fractionis smaller than1.0. For example, if you set it to0.8, LightGBM will select 80% of features before training each tree- can be used to speed up training
- can be used to deal with over-fitting
意味:各決定木の学習に使う特徴量数の割合を指定するためのパラメータ
デフォルトは1.0。
何をしているか?
・デフォルト(1.0)だと、全ての特徴量を使って木を構築します。
・feature_fraction < 1.0 に設定すると、各木ごとにランダムで一部の特徴量だけを使うようになります。
lambda_l1
https://lightgbm.readthedocs.io/en/stable/Parameters.html
lambda_l1🔗︎, default =0.0, type = double, aliases:reg_alpha,l1_regularization, constraints:lambda_l1 >= 0.0
- L1 regularization
意味:葉の重みに対するL1正則化の強さを制御するパラメータ
デフォルトは0.0。
lambda_l2
https://lightgbm.readthedocs.io/en/stable/Parameters.html
lambda_l2🔗︎, default =0.0, type = double, aliases:reg_lambda,lambda,l2_regularization, constraints:lambda_l2 >= 0.0
- L2 regularization
意味:葉の重みに対するL2正則化の強さを制御するパラメータ
デフォルトは0.0。
Optunaで最適化するためのパラメータ
# Optunaで最適化
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=30)optuna.study.create_study()
optuna.study.create_study(*, storage=None, sampler=None, pruner=None, study_name=None, direction=None, load_if_exists=False, directions=None)[source]
https://optuna.readthedocs.io/en/stable/reference/generated/optuna.study.create_study.html#optuna.study.create_study
新しい最適化studyを作るための関数。
Optuna のハイパーパラメータ探索の土台になります。
direction
https://optuna.readthedocs.io/en/stable/reference/generated/optuna.study.create_study.html#optuna.study.create_study
- direction (str | StudyDirection | None) –Direction of optimization. Set
minimizefor minimization andmaximizefor maximization. You can also pass the correspondingStudyDirectionobject.directionanddirectionsmust not be specified at the same time.NoteIf none of direction and directions are specified, the direction of the study is set to “minimize”.
意味:どの方向に目的関数(objective)を最適化するかを指定するもの。
デフォルトは’minimize’。
・minimize:値をできるだけ小さくしたい(損失関数、エラーなど)
・maximize:値をできるだけ大きくしたい(精度、AUC、スコアなど)
optimize()
optimize(func, n_trials=None, timeout=None, n_jobs=1, catch=(), callbacks=None, gc_after_trial=False, show_progress_bar=False)[source]
Optimize an objective function.
Optimization is done by choosing a suitable set of hyperparameter values from a given range. Uses a sampler which implements the task of value suggestion based on a specified distribution. The sampler is specified in
create_study()and the default choice for the sampler is TPE. See alsoTPESamplerfor more details on ‘TPE’.Optimization will be stopped when receiving a termination signal such as SIGINT and SIGTERM. Unlike other signals, a trial is automatically and cleanly failed when receiving SIGINT (Ctrl+C). If
n_jobsis greater than one or if another signal than SIGINT is used, the interrupted trial state won’t be properly updated.
指定した範囲からハイパーパラメータの組み合わせを選び、目的関数(objective)の最適値を探索する関数。
最適なパラメータを自動で見つける仕組みです。
n_trials
- n_trials (int | None) –The number of trials for each process.
Nonerepresents no limit in terms of the number of trials. The study continues to create trials until the number of trials reachesn_trials,timeoutperiod elapses,stop()is called, or a termination signal such as SIGTERM or Ctrl+C is received.See alsooptuna.study.MaxTrialsCallbackcan ensure how many times trials will be performed across all processes.
意味:目的関数(objective)を 何回繰り返して最適化を行うか を決める引数です。
デフォルトはNone。回数制限なしで最適化を継続する。
(スポンサーリンク)


コメント