多層パーセプトロンの正則化

Beginner

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

はじめに

この実験では、多層パーセプトロン(MLP)における正則化を使用して過学習を克服する方法を示します。正則化パラメータである alpha の異なる値を比較し、決定関数がどのように変化するかを観察します。

VM のヒント

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

時々、Jupyter Notebook が読み込み完了するまで数秒待つ必要があります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。

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

ライブラリのインポート

この実験に必要なライブラリをインポートして始めましょう。合成データセットを作成するために scikit-learn を、MLP モデルを構築するために MLPClassifier を、データを標準化するために StandardScaler を、変換と分類器のパイプラインを作成するために make_pipeline を使用します。

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_moons, make_circles, make_classification
from sklearn.neural_network import MLPClassifier
from sklearn.pipeline import make_pipeline

アルファの定義

正則化パラメータである alpha の異なる値を定義します。0.1 と 10 の間で対数的に等間隔な 5 つの値を生成するために np.logspace を使用します。

alphas = np.logspace(-1, 1, 5)

分類器の作成

alpha の各値に対して MLP 分類器を作成します。データを標準化するための StandardScaler と、異なる alpha 値の MLPClassifier を含むパイプラインを作成します。ソルバーを'lbfgs'に設定します。これは準ニュートン法のファミリーに属する最適化手法です。オーバーフィットを防ぐために max_iter を 2000 に設定し、early_stopping を True に設定します。2 つの隠れ層を持ち、各層に 10 個のニューロンを使用します。

classifiers = []
names = []
for alpha in alphas:
    classifiers.append(
        make_pipeline(
            StandardScaler(),
            MLPClassifier(
                solver="lbfgs",
                alpha=alpha,
                random_state=1,
                max_iter=2000,
                early_stopping=True,
                hidden_layer_sizes=[10, 10],
            ),
        )
    )
    names.append(f"alpha {alpha:.2f}")

データセットの作成

scikit-learn の make_classification、make_moons、make_circles 関数を使って 3 つの合成データセットを作成します。train_test_split を使って各データセットを訓練用とテスト用に分割します。

X, y = make_classification(
    n_features=2, n_redundant=0, n_informative=2, random_state=0, n_clusters_per_class=1
)
rng = np.random.RandomState(2)
X += 2 * rng.uniform(size=X.shape)
linearly_separable = (X, y)

datasets = [
    make_moons(noise=0.3, random_state=0),
    make_circles(noise=0.2, factor=0.5, random_state=1),
    linearly_separable,
]

figure = plt.figure(figsize=(17, 9))
i = 1
## iterate over datasets
for X, y in datasets:
    ## split into training and test part
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.4, random_state=42
    )

データセットのプロット

各データセットをプロットし、訓練ポイントとテストポイントを異なる色で塗り分けます。

    x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
    y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

    ## just plot the dataset first
    cm = plt.cm.RdBu
    cm_bright = ListedColormap(["#FF0000", "#0000FF"])
    ax = plt.subplot(len(datasets), len(classifiers) + 1, i)
    ## Plot the training points
    ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap=cm_bright)
    ## and testing points
    ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap=cm_bright, alpha=0.6)
    ax.set_xlim(xx.min(), xx.max())
    ax.set_ylim(yy.min(), yy.max())
    ax.set_xticks(())
    ax.set_yticks(())
    i += 1

分類器をフィットさせ、決定境界をプロットする

各データセットに対して各分類器をフィットさせ、決定境界をプロットします。決定境界をプロットするために contourf を、訓練ポイントとテストポイントをプロットするために scatter を使用します。各プロットに正解率を表示することもできます。

    ## iterate over classifiers
    for name, clf in zip(names, classifiers):
        ax = plt.subplot(len(datasets), len(classifiers) + 1, i)
        clf.fit(X_train, y_train)
        score = clf.score(X_test, y_test)

        ## Plot the decision boundary. For that, we will assign a color to each
        ## point in the mesh [x_min, x_max] x [y_min, y_max].
        if hasattr(clf, "decision_function"):
            Z = clf.decision_function(np.column_stack([xx.ravel(), yy.ravel()]))
        else:
            Z = clf.predict_proba(np.column_stack([xx.ravel(), yy.ravel()]))[:, 1]

        ## Put the result into a color plot
        Z = Z.reshape(xx.shape)
        ax.contourf(xx, yy, Z, cmap=cm, alpha=0.8)

        ## Plot also the training points
        ax.scatter(
            X_train[:, 0],
            X_train[:, 1],
            c=y_train,
            cmap=cm_bright,
            edgecolors="black",
            s=25,
        )
        ## and testing points
        ax.scatter(
            X_test[:, 0],
            X_test[:, 1],
            c=y_test,
            cmap=cm_bright,
            alpha=0.6,
            edgecolors="black",
            s=25,
        )

        ax.set_xlim(xx.min(), xx.max())
        ax.set_ylim(yy.min(), yy.max())
        ax.set_xticks(())
        ax.set_yticks(())
        ax.set_title(name)
        ax.text(
            xx.max() - 0.3,
            yy.min() + 0.3,
            f"{score:.3f}".lstrip("0"),
            size=15,
            horizontalalignment="right",
        )
        i += 1

プロットを表示する

最後に、サブプロットのレイアウトを調整してプロットを表示します。

figure.subplots_adjust(left=0.02, right=0.98)
plt.show()

まとめ

この実験では、多層パーセプトロンにおける正則化を使って過学習を克服する方法を学びました。正則化パラメータ alpha の異なる値を比較し、決定関数がどのように変化するかを観察しました。また、合成データセットを作成し、データを標準化し、MLP 分類器を作成し、決定境界をプロットする方法も学びました。