機械学習のコンテストでは、パラメーター調整アーティファクトの組み合わせが非常に人気があり、 LightGBM+Optuna はkaggle
多くのトップ ソリューションに頻繁に登場します。パラメータ調整に時間がかかり悩んでいる友人も多いと思い、今回は私自身の経験も交えて、仕事でも使えるモデル+パラメータ調整の使い方についてのチュートリアルをお届けします。LGBM
OPTUNA
これについてはあまり言うことはありませLightGBM
んが、以前にも多くの記事で紹介しましたが、XGBoost
基本をベースに効率化を図るために最適化されたバージョンであり、マイクロソフト社からリリースされており、精度を落とすことなく非常に高い作業効率を実現しています。現在、比較的優れた機械学習モデルとして広く認識されており、分類と回帰をすべて満たすことができます。
パラメータチューニング、つまりモデルのハイパーパラメータチューニングに関しては、 と考えられるかもしれませんGridSearch
。実際、私も最初に使用しましたGridSearch
。暴力の美学は優れていますが、欠点は明らかです。実行するには時間がかかりすぎ、時間コストが高すぎます。対照的に、ベイジアン フレームワークに基づくパラメーター調整ツールははるかに快適です。一般的なツールなど、そのようなオープンソース ツールも多数ありますHyperOPT
。もちろん、今日の主役はそれではなく、より香りが良くOPTUNA
、軽量でより強力で、離陸するのに十分な速度を持った別のモデルです。
LGBM
例を使って説明する必要があるため、以下ではLGBM
主なハイパーパラメータから始めて、Optuna
これらのハイパーパラメータ設定に従ってパラメータを調整します。
技術交流
テクノロジーは共有とコミュニケーションを学ぶ必要があり、密室で作業することはお勧めできません。1 人で速く進むこともできますし、グループでより遠くまで進むこともできます。
関連するファイルとコードがアップロードされており、コミュニケーション グループに参加することで入手できます。グループのメンバーは 2,000 人を超えています。メモを追加する最良の方法は、ソース + 興味の方向です。これにより、同じ考えを持つ人を見つけるのに便利です友達。
方法①、WeChatアカウントを追加:dkl88194、備考:CSDNから+グループを追加
方法②、WeChat検索公式アカウント:Python学習とデータマイニング、バックグラウンド返信:グループを追加
LightGBMパラメータの概要
一般に、ツリーベース モデルのハイパーパラメータは 4 つのカテゴリに分類できます。
-
デシジョン ツリーの構造と学習に影響を与えるパラメータ
-
トレーニング速度に影響するパラメータ
-
精度向上のためのパラメータ
-
過学習を防ぐためのパラメータ
ほとんどの場合、これらのカテゴリは多くの部分で重複しているため、1 つのカテゴリの効率を上げると、別のカテゴリの効率が低下する可能性があります。パラメータを完全に手動で調整すると、さらに苦痛になります。したがって、初期段階では、いくつかの自動パラメータ調整ツールを使用して大まかな結果を得ることができます。自動パラメータ調整ツールの核心は、適切なパラメータ範囲を与える方法です。適切なパラメータ グリッドがあれば、Optuna
これらのカテゴリ間で最もバランスのとれたパラメータの組み合わせが自動的に見つかります。
ハイパーパラメータとしては以下のLGBM
4種類が導入されています。
1. ツリー構造のハイパーパラメータを制御する
max_ Depth と num_leaves
ではLGBM
、ツリー構造を制御するために調整する最初のパラメータはmax_depth
(ツリーの深さ) とnum_leaves
(リーフ ノードの数) です。これら 2 つのパラメーターは、ツリー構造を制御するのに最も簡単です。なぜならLGBM
、leaf-wise
ツリーの深さを制御しないと、非常に簡単にオーバーフィットしてしまうからです。max_depth
一般設定を に設定してみてください3到8
。
これら 2 つのパラメータの間には一定の関係もあります。二分木なのでnum_leaves
最大値は となるはずです2^(max_depth)
。したがって、決定するということは、値の範囲を決定するmax_depth
ことも意味します。num_leaves
min_data_in_leaf
ツリーのもう 1 つの重要な構造パラメータは、min_data_in_leaf
そのサイズが過学習かどうかにも関係していることです。これは、下向きに分割するリーフ ノードのサンプルの最小数を指定します。たとえば、100 に設定すると、ノード サンプルの数が 100 未満になると、成長が停止します。もちろん、min_data_in_leaf
の設定はトレーニング サンプルの数 と にも依存しますnum_leaves
。大規模なデータ セットの場合、通常は 1,000 を超えるレベルが設定されます。
精度を向上させるハイパーパラメータ
learning_rate と n_estimators
より高い精度を達成する一般的な方法は、より多くのサブツリーを使用し、学習率を下げることです。つまり、最適なLGBM
中和の組み合わせを見つけることです。n_estimators
learning_rate
n_estimators
決定木の数を制御しますlearning_rate
が勾配降下のステップ サイズ パラメーターも制御します。経験によれば、LGBM
オーバーフィットが容易であり、learning_rate
勾配ブースティング学習の速度の制御に使用できます。一般的な値は の間に設定できます0.01 和 0.3
。一般的なアプローチは、1000 などの少し多めのサブツリーを使用し、それよりも低いサブツリーを設定してlearning_rate
、early_stopping
最適な反復数を見つけることです。
max_bin
さらに、max_bin
精度を向上させるために値を増やすこともできます (デフォルトは 255)。変数ビンの数が多いほど、より詳細な情報が保持されるため、逆に、変数ビンの数が少ないほど、より多くの情報が失われますが、一般化が容易になるためです。これは特徴量エンジニアリングのビニングと同じですが、内部ヒストグラム アルゴリズムを通じてhist
処理されます。max_bin
高すぎると、過剰適合の危険性もあります。
過学習を制御するためのより多くのハイパーパラメータ
lambda_l1 と lambda_l2
lambda_l1
And はと の正則化lambda_l2
に対応し、 とと同じで、葉ノードの数と葉ノードの重みに対するペナルティで、値が大きいほどペナルティも大きくなります。これらのパラメーターの最適値は、その大きさが過学習に直接関係しないため、調整がより困難になりますが、関係する可能性があります。一般的な検索範囲は にあります。L1
L2
XGBoost
reg_lambda
reg_alpha
(0, 100)
min_gain_to_split
このパラメータは、スプリットの最小ゲインを定義します。このパラメータはデータの品質を示すものでもあり、計算ゲインが高くないと下方に分割できません。設定した深さが非常に深いにもかかわらず、下方向に分割できない場合は、分割できるものが見つからないというLGBM
メッセージが表示されます。warning
パラメータの意味はXGBoost
と同じでgamma
、データ品質が限界に達していることを示します。より保守的な検索範囲は、(0, 20)
大規模なパラメーター グリッドでの追加の正則化として使用できます。
Bagging_fraction と feature_fraction
これら 2 つのパラメータの値の範囲は です(0,1)
。
feature_fraction
各ツリーをトレーニングするときにサンプリングする特徴のパーセンテージを指定します。これは、過学習を避けるために存在します。一部の特徴はゲインが高いため、各サブツリーが均質化されるように、各サブツリーが分割されるときに同じ特徴が使用される場合があります。ただし、より低い確率で特徴をサンプリングすると、毎回同じ強力な特徴に遭遇することを回避できるため、サブツリーの特徴が差別化、つまり一般化されます。
bagging_fraction
各ツリーのトレーニングに使用されるトレーニング サンプルの割合を指定します。このパラメータを使用するには、それを設定する必要がありますbagging_freq
。理由はfeature_fraction
同じであり、すべてのサブツリーをより良く、異なるものにすることもできます。
Optuna で検索グリッドを作成する
Optuna
の最適化プロセスでは、まず目的関数が必要です。これには次のものが含まれます。
-
辞書形式のパラメータのグリッド
-
モデルを作成して (おそらく相互検証を使用して
kfold
)、ハイパーパラメーターの組み合わせを試します -
モデルトレーニング用のデータセット
-
このモデルを使用して予測を生成します
-
ユーザー定義の指標とリターンに基づいたスコア予測
一般的に使用されるフレームワークは次のとおりです。モデルは 50% オフでKfold
、モデルの安定性を確保できます。最後の行は、最適化する必要がある CV スコアの平均を返します。logloss
最小値、auc
最大値、最大値の指標、ks
トレーニング セットとテスト セット間のauc
最小ギャップなど、目的関数を自分で設定できます。
import optuna # pip install optuna
from sklearn.metrics import log_loss
from sklearn.model_selection import StratifiedKFold
def objective(trial, X, y):
# 后面填充
param_grid = {
}
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=1121218)
cv_scores = np.empty(5)
for idx, (train_idx, test_idx) in enumerate(cv.split(X, y)):
X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
model = lgbm.LGBMClassifier(objective="binary", **param_grid)
model.fit(
X_train,
y_train,
eval_set=[(X_test, y_test)],
eval_metric="binary_logloss",
early_stopping_rounds=100,
)
preds = model.predict_proba(X_test)
cv_scores[idx] = preds
return np.mean(cv_scores)
以下はパラメータ設定です。Optuna
より一般的なパラメータ設定方法はsuggest_categorical
、suggest_int
、 、ですsuggest_float
。このうち、suggest_int
と のsuggest_float
設定方法は です(参数,最小值,最大值,step=步长)
。
def objective(trial, X, y):
# 字典形式的参数网格
param_grid = {
"n_estimators": trial.suggest_categorical("n_estimators", [10000]),
"learning_rate": trial.suggest_float("learning_rate", 0.01, 0.3),
"num_leaves": trial.suggest_int("num_leaves", 20, 3000, step=20),
"max_depth": trial.suggest_int("max_depth", 3, 12),
"min_data_in_leaf": trial.suggest_int("min_data_in_leaf", 200, 10000, step=100),
"max_bin": trial.suggest_int("max_bin", 200, 300),
"lambda_l1": trial.suggest_int("lambda_l1", 0, 100, step=5),
"lambda_l2": trial.suggest_int("lambda_l2", 0, 100, step=5),
"min_gain_to_split": trial.suggest_float("min_gain_to_split", 0, 15),
"bagging_fraction": trial.suggest_float(
"bagging_fraction", 0.2, 0.95, step=0.1
),
"bagging_freq": trial.suggest_categorical("bagging_freq", [1]),
"feature_fraction": trial.suggest_float(
"feature_fraction", 0.2, 0.95, step=0.1
),
}
Optuna を作成して自動的に調整する
以下は、参照用の完全な目的関数フレームワークです。
from optuna.integration import LightGBMPruningCallback
def objective(trial, X, y):
# 参数网格
param_grid = {
"n_estimators": trial.suggest_categorical("n_estimators", [10000]),
"learning_rate": trial.suggest_float("learning_rate", 0.01, 0.3),
"num_leaves": trial.suggest_int("num_leaves", 20, 3000, step=20),
"max_depth": trial.suggest_int("max_depth", 3, 12),
"min_data_in_leaf": trial.suggest_int("min_data_in_leaf", 200, 10000, step=100),
"lambda_l1": trial.suggest_int("lambda_l1", 0, 100, step=5),
"lambda_l2": trial.suggest_int("lambda_l2", 0, 100, step=5),
"min_gain_to_split": trial.suggest_float("min_gain_to_split", 0, 15),
"bagging_fraction": trial.suggest_float("bagging_fraction", 0.2, 0.95, step=0.1),
"bagging_freq": trial.suggest_categorical("bagging_freq", [1]),
"feature_fraction": trial.suggest_float("feature_fraction", 0.2, 0.95, step=0.1),
"random_state": 2021,
}
# 5折交叉验证
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=1121218)
cv_scores = np.empty(5)
for idx, (train_idx, test_idx) in enumerate(cv.split(X, y)):
X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
# LGBM建模
model = lgbm.LGBMClassifier(objective="binary", **param_grid)
model.fit(
X_train,
y_train,
eval_set=[(X_test, y_test)],
eval_metric="binary_logloss",
early_stopping_rounds=100,
callbacks=[
LightGBMPruningCallback(trial, "binary_logloss")
],
)
# 模型预测
preds = model.predict_proba(X_test)
# 优化指标logloss最小
cv_scores[idx] = log_loss(y_test, preds)
return np.mean(cv_scores)
上記のグリッドでは、データのトレーニング前にあまり良くないハイパーパラメータのセットを検出する便利なクラスも追加し、検索時間を大幅に短縮しましたLightGBMPruningCallback
。callback
目的関数を設定したら、パラメータを調整しましょう。
study = optuna.create_study(direction="minimize", study_name="LGBM Classifier")
func = lambda trial: objective(trial, X, y)
study.optimize(func, n_trials=20)
direction
minimize
または、最大化maximize
するなどの も可能ですauc
。理論的にはtrials
、回数が多いほど結果は良くなりますが、実行時間も考慮する必要があります。
探索が終わったら呼び出しbest_value
てbast_params
属性を付けるとパラメータ調整が出てきます。
print(f"\tBest value (rmse): {
study.best_value:.5f}")
print(f"\tBest params:")
for key, value in study.best_params.items():
print(f"\t\t{
key}: {
value}")
-----------------------------------------------------
Best value (binary_logloss): 0.35738
Best params:
device: gpu
lambda_l1: 7.71800699380605e-05
lambda_l2: 4.17890272377219e-06
bagging_fraction: 0.7000000000000001
feature_fraction: 0.4
bagging_freq: 5
max_depth: 5
num_leaves: 1007
min_data_in_leaf: 45
min_split_gain: 15.703519227860273
learning_rate: 0.010784015325759629
n_estimators: 10000
このパラメーターの組み合わせを取得したら、それを使用してモデルを実行し、結果を確認した後に手動で微調整することができるため、時間を大幅に節約できます。
エピローグ
この記事では、上記のコードに限定されず、データの状況に応じてパラメータの範囲を調整したり、最適化の目標をカスタマイズしたりすることができる、非常に使いやすいパラメータチューニングによるコードフレームワークを提供Optuna
します。LGBM
logloss