Kaggle(29) - Optunaでハイパーパラメータ調整 - LightGBM編6

学習パラメータの調整をする場合、グリッドサーチ機能を使うとパラメータの候補をリストで指定し、そのリストの組み合わせより最も成績のよい組み合わせを調べることができました。(前回記事参照)

Optunaを使うと、パラメータの候補リストではなく、パラメータの範囲を指定して最適な組み合わせを調べることができるのでより便利です。

データの読み込み

タイタニックのデータセットを読み込み、データの前処理を行って、正解ラベルとそれ以外にデータを分割します。

[ソース]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pandas as pd

df_train = pd.read_csv('/kaggle/input/titanic/train.csv')

# データ前処理
def preprocessing(df):
# 不要な列の削除
df.drop(['Name', 'Ticket', 'Cabin'], axis=1, inplace=True)

# カテゴリ変数の変換
df['Sex'] = df['Sex'].astype('category')
df['Embarked'] = df['Embarked'].astype('category')

return df

x_titanic = preprocessing(df_train.drop(['Survived'], axis=1))
y_titanic = df_train['Survived']

Optunaでハイパーパラメータ調整

Optunaで学習パラメータを最適化する場合には、目的関数の定義の定義を行い、その中で学習パラメータの種類と範囲を指定します。

返値としては、成績の良いものほど数値が低くなるようにします。今回は正解率が高いほど、低い数値が返るように定義しています。(13行目)

ハイパーパラメータの自動最適化を行うためにはoptunaのcreate_studyメソッドで最適化のセッションを作り、そのセッションのoptimizeメソッドに目的関数(objective)と試行回数(n_trials)を指定します。(20行目)

[ソース]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import optuna
import lightgbm as lgb
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split

# 目的関数の定義(最小値問題として定式化)
def objective(trial):
learning_rate = trial.suggest_loguniform('learning_rate', 1e-5, 1e-1)
num_leaves = trial.suggest_int('num_leaves', 5, 30)

gbm = lgb.LGBMClassifier(objective='binary', learning_rate=learning_rate, num_leaves=num_leaves)
gbm.fit(train_x, train_y)
return 1.0 - accuracy_score(valid_y, gbm.predict(valid_x))

# 訓練データをtrainとvalidに分割
train_x, valid_x, train_y, valid_y = train_test_split(x_titanic, y_titanic, test_size=0.33, random_state=0)

# ハイパーパラメータの自動最適化
study = optuna.create_study()
study.optimize(objective, n_trials = 100)

print('求めたハイパーパラメータ', study.best_params)
print('正答率', 1.0 - study.best_value)

[出力]

今回は、学習率(learning_rate)と木にある分岐の個数(num_leaves)の最適化を行い、各パラメータが0.08623、8という結果となりました。

正答率は84.06%と、まずまずの結果になっていると思います。

Kaggleに提出

最適化したハイパーパラメータを指定して、LightGBMのインスタンスを作成し、学習を行います。

その後、検証データを読み込み、推論・提出用のCSVの出力を行い、Kaggleに提出します。

[ソース]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
gbm = lgb.LGBMClassifier(objective='binary', learning_rate=0.08623, num_leaves=8)

# 学習
gbm.fit(x_titanic, y_titanic)

# 検証データの読み込み
df_test = pd.read_csv('/kaggle/input/titanic/test.csv')
df_test = preprocessing(df_test)

pre = gbm.predict(df_test)

result = pd.DataFrame(df_test['PassengerId'])
result['Survived'] = pre
result.to_csv('result0307c.csv', index=False)

[提出結果]

正解率77.99%となりました。

これまでの結果とほぼ同じ正解率となっていて、パラメータの調整だけでは成績向上は難しいのかもしれません。

もしくは、調整するパラメータの選択がよくないのか、範囲の指定がイマイチなのか・・・壁にぶつかっているような気がします。