はじめに
勾配ブースティングは、複数の弱学習器(回帰木)を反復的に組み合わせて強力な単一モデルを生成するアンサンブル手法です。勾配ブースティングにおける早期終了機能により、未見のデータに対して良好な汎化性能を持つモデルを構築するのに十分な最小反復回数を見つけることができます。
VM のヒント
VM の起動が完了した後、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使って練習しましょう。
Jupyter Notebook が読み込み終了するまで数秒待つことがあります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。
学習中に問題に遭遇した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。
必要なライブラリとデータの読み込み
まず、必要なライブラリとデータを読み込む必要があります。勾配ブースティングの実装には scikit - learn ライブラリを使用します。
import time
import numpy as np
import matplotlib.pyplot as plt
from sklearn import ensemble
from sklearn import datasets
from sklearn.model_selection import train_test_split
data_list = [
datasets.load_iris(return_X_y=True),
datasets.make_classification(n_samples=800, random_state=0),
datasets.make_hastie_10_2(n_samples=2000, random_state=0),
]
names = ["Iris Data", "Classification Data", "Hastie Data"]
n_estimators = 200
データの準備
次に、データを訓練セットとテストセットに分割することでデータを準備します。
for X, y in data_list:
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=0
)
早期終了なしでモデルを構築して訓練する
ここでは、早期終了なしで勾配ブースティングモデルを構築して訓練します。
gb = ensemble.GradientBoostingClassifier(n_estimators=n_estimators, random_state=0)
start = time.time()
gb.fit(X_train, y_train)
time_gb.append(time.time() - start)
早期終了付きでモデルを構築して訓練する
ここでは、早期終了付きで勾配ブースティングモデルを構築して訓練します。検証用の割合(validationfraction)を指定します。これは、モデルの検証損失を評価するために訓練から取り除かれる全体のデータセットの割合を示します。勾配ブースティングモデルは訓練セットを使って訓練され、検証セットを使って評価されます。回帰木の追加の各段階が追加されるたびに、検証セットを使ってモデルのスコア付けが行われます。これは、最後の n_iter_no_change 段階でのモデルのスコアが少なくとも tol だけ改善しなくなるまで続けられます。その後、モデルは収束したと見なされ、さらなる段階の追加は「早期に停止」されます。最終モデルの段階数は属性 n_estimatorsで利用できます。
gbes = ensemble.GradientBoostingClassifier(
n_estimators=n_estimators,
validation_fraction=0.2,
n_iter_no_change=5,
tol=0.01,
random_state=0,
)
start = time.time()
gbes.fit(X_train, y_train)
time_gbes.append(time.time() - start)
早期終了有無でのスコア比較
ここでは、2 つのモデルのスコアを比較します。
score_gb.append(gb.score(X_test, y_test))
score_gbes.append(gbes.score(X_test, y_test))
早期終了有無でのフィット時間比較
ここでは、2 つのモデルのフィット時間を比較します。
plt.figure(figsize=(9, 5))
bar1 = plt.bar(
index, time_gb, bar_width, label="Without early stopping", color="crimson"
)
bar2 = plt.bar(
index + bar_width, time_gbes, bar_width, label="With early stopping", color="coral"
)
max_y = np.amax(np.maximum(time_gb, time_gbes))
plt.xticks(index + bar_width, names)
plt.yticks(np.linspace(0, 1.3 * max_y, 13))
autolabel(bar1, n_gb)
autolabel(bar2, n_gbes)
plt.ylim([0, 1.3 * max_y])
plt.legend(loc="best")
plt.grid(True)
plt.xlabel("Datasets")
plt.ylabel("Fit Time")
plt.show()
早期終了有無でのスコア比較
ここでは、2 つのモデルのスコアを比較します。
plt.figure(figsize=(9, 5))
bar1 = plt.bar(
index, score_gb, bar_width, label="Without early stopping", color="crimson"
)
bar2 = plt.bar(
index + bar_width, score_gbes, bar_width, label="With early stopping", color="coral"
)
plt.xticks(index + bar_width, names)
plt.yticks(np.arange(0, 1.3, 0.1))
autolabel(bar1, n_gb)
autolabel(bar2, n_gbes)
plt.ylim([0, 1.3])
plt.legend(loc="best")
plt.grid(True)
plt.xlabel("Datasets")
plt.ylabel("Test score")
plt.show()
まとめ
この実験では、勾配ブースティングにおける早期終了について学びました。これにより、未見のデータに対して十分に汎化するモデルを構築するのに必要な最小限の反復回数を見つけることができます。早期終了の有無のある勾配ブースティングモデルの性能を比較し、早期終了が学習時間、メモリ使用量、予測待ち時間を大幅に削減できることを観察しました。