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_types
https://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:gbrt
rf
, Random Forest, aliases:random_forest
dart
, Dropouts meet Multiple Additive Regression Trees
- Note: internally, LightGBM uses
gbdt
mode for the first1 / learning_rate
iterations
意味:ブースティングのアルゴリズム種類を指定。
デフォルトは’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
,prediction
andrefit
tasks or in correspondent functions of language-specific packages- number of threads for LightGBM
0
means 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
#data
is small. Tree still grows leaf-wise<= 0
means 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_freq
should 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_fraction
is 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
minimize
for minimization andmaximize
for maximization. You can also pass the correspondingStudyDirection
object.direction
anddirections
must 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 alsoTPESampler
for 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_jobs
is 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.
None
represents no limit in terms of the number of trials. The study continues to create trials until the number of trials reachesn_trials
,timeout
period elapses,stop()
is called, or a termination signal such as SIGTERM or Ctrl+C is received.See alsooptuna.study.MaxTrialsCallback
can ensure how many times trials will be performed across all processes.
意味:目的関数(objective
)を 何回繰り返して最適化を行うか を決める引数です。
デフォルトはNone。回数制限なしで最適化を継続する。
(スポンサーリンク)
コメント