多クラス AdaBoost 決定木

Beginner

This tutorial is from open-source community. Access the source code

はじめに

この実験では、マルチクラス問題における予測精度を向上させるために、ブースティングがどのように機能するかを調べます。10 次元の標準正規分布を使って構築されたデータセットを使い、ネストした同心円状の 10 次元の球体によって分離された 3 つのクラスを定義します。各クラスには、ほぼ同じ数のサンプルが含まれます。

SAMME と SAMME.R アルゴリズムの性能を比較します。SAMME.R は、確率推定値を使って加法的モデルを更新しますが、SAMME は分類結果のみを使います。

VM のヒント

VM の起動が完了したら、画面の左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使って練習しましょう。

Jupyter Notebook の読み込みには数秒かかる場合があります。Jupyter Notebook の制限により、操作の検証は自動化できません。

学習中に問題がある場合は、Labby にお問い合わせください。セッション終了後にフィードバックを提供してください。すぐに問題を解決いたします。

必要なライブラリをインポートする

必要なライブラリをインポートして始めましょう。これには、sklearn.datasets からの make_gaussian_quantilesaccuracy_scoresklearn.ensemble からの AdaBoostClassifierDecisionTreeClassifier、および matplotlib.pyplot が含まれます。

import matplotlib.pyplot as plt
from sklearn.datasets import make_gaussian_quantiles
from sklearn.ensemble import AdaBoostClassifier
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier

データセットを読み込む

sklearn.datasets からの make_gaussian_quantiles 関数を使ってデータセットを生成します。この関数は等方性ガウス分布を生成し、クラス間に分離を追加して問題を難しくします。

X, y = make_gaussian_quantiles(
    n_samples=13000, n_features=10, n_classes=3, random_state=1
)

データセットを分割する

データセットを訓練用とテスト用に分割します。最初の 3000 サンプルを訓練に、残りのサンプルをテストに使用します。

n_split = 3000
X_train, X_test = X[:n_split], X[n_split:]
y_train, y_test = y[:n_split], y[n_split:]

モデルを作成して訓練する

SAMME を使用する AdaBoost モデルと SAMME.R を使用する AdaBoost モデルの 2 つを作成します。両方のモデルは、最大深さが 2 で推定器が 300 個の DecisionTreeClassifier を使用します。

bdt_real = AdaBoostClassifier(
    DecisionTreeClassifier(max_depth=2), n_estimators=300, learning_rate=1
)

bdt_discrete = AdaBoostClassifier(
    DecisionTreeClassifier(max_depth=2),
    n_estimators=300,
    learning_rate=1.5,
    algorithm="SAMME",
)

bdt_real.fit(X_train, y_train)
bdt_discrete.fit(X_train, y_train)

モデルをテストする

モデルをテストし、各ブースティング反復後に各モデルのテストエラーを計算します。

real_test_errors = []
discrete_test_errors = []

for real_test_predict, discrete_test_predict in zip(
    bdt_real.staged_predict(X_test), bdt_discrete.staged_predict(X_test)
):
    real_test_errors.append(1.0 - accuracy_score(real_test_predict, y_test))
    discrete_test_errors.append(1.0 - accuracy_score(discrete_test_predict, y_test))

結果をプロットする

各モデルのテストエラー、分類エラー、およびブースト重みをプロットします。

n_trees_discrete = len(bdt_discrete)
n_trees_real = len(bdt_real)

## Boosting might terminate early, but the following arrays are always
## n_estimators long. We crop them to the actual number of trees here:
discrete_estimator_errors = bdt_discrete.estimator_errors_[:n_trees_discrete]
real_estimator_errors = bdt_real.estimator_errors_[:n_trees_real]
discrete_estimator_weights = bdt_discrete.estimator_weights_[:n_trees_discrete]

plt.figure(figsize=(15, 5))

plt.subplot(131)
plt.plot(range(1, n_trees_discrete + 1), discrete_test_errors, c="black", label="SAMME")
plt.plot(
    range(1, n_trees_real + 1),
    real_test_errors,
    c="black",
    linestyle="dashed",
    label="SAMME.R",
)
plt.legend()
plt.ylim(0.18, 0.62)
plt.ylabel("テストエラー")
plt.xlabel("木の数")

plt.subplot(132)
plt.plot(
    range(1, n_trees_discrete + 1),
    discrete_estimator_errors,
    "b",
    label="SAMME",
    alpha=0.5,
)
plt.plot(
    range(1, n_trees_real + 1), real_estimator_errors, "r", label="SAMME.R", alpha=0.5
)
plt.legend()
plt.ylabel("エラー")
plt.xlabel("木の数")
plt.ylim((0.2, max(real_estimator_errors.max(), discrete_estimator_errors.max()) * 1.2))
plt.xlim((-20, len(bdt_discrete) + 20))

plt.subplot(133)
plt.plot(range(1, n_trees_discrete + 1), discrete_estimator_weights, "b", label="SAMME")
plt.legend()
plt.ylabel("重み")
plt.xlabel("木の数")
plt.ylim((0, discrete_estimator_weights.max() * 1.2))
plt.xlim((-20, n_trees_discrete + 20))

## prevent overlapping y-axis labels
plt.subplots_adjust(wspace=0.25)
plt.show()

まとめ

この実験では、ブースティングが多クラス問題における予測精度をどのように向上させるかを検討しました。10 次元の標準正規分布を取り、ネストした同心円状の 10 次元の球体によって区切られた 3 つのクラスを定義することで構築されたデータセットを使用しました。SAMME と SAMME.R アルゴリズムの性能を比較し、各モデルのテストエラー、分類エラー、およびブースト重みをプロットしました。結果は、SAMME.R が通常 SAMME よりも速く収束し、より少ないブースティング反復でより低いテストエラーを達成することを示しています。