ガウス混合モデルの共分散

Beginner

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

はじめに

このチュートリアルでは、ガウス混合モデル (GMM) で異なる共分散タイプを使用する方法を示します。GMM は頻繁にクラスタリングに使用され、取得したクラスタとデータセットの実際のクラスを比較することができます。この比較を有効にするために、ガウス分布の平均値を訓練セットのクラスの平均値で初期化します。アイリスデータセットでさまざまな GMM 共分散タイプを使用して、訓練データとホールドアウトテストデータの両方に予測ラベルをプロットします。性能の昇順で、球状、対角線、完全、および結合された共分散行列を持つ GMM を比較します。

一般的には完全共分散が最適な性能を発揮すると予想されますが、小さなデータセットではオーバーフィッティングの傾向があり、ホールドアウトテストデータに対する汎化性能は良好ではありません。

プロットでは、訓練データはドットとして表示され、テストデータはクロスとして表示されます。アイリスデータセットは 4 次元です。ここでは最初の 2 次元のみが表示されており、したがって一部の点は他の次元で分離されています。

VM のヒント

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

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

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

ライブラリのインポート

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets
from sklearn.mixture import GaussianMixture
from sklearn.model_selection import StratifiedKFold

アイリスデータセットの読み込み

iris = datasets.load_iris()

訓練データとテストデータの準備

skf = StratifiedKFold(n_splits=4)
train_index, test_index = next(iter(skf.split(iris.data, iris.target)))

X_train = iris.data[train_index]
y_train = iris.target[train_index]
X_test = iris.data[test_index]
y_test = iris.target[test_index]

異なる共分散タイプの GMM 推定器の設定

colors = ["navy", "turquoise", "darkorange"]
n_classes = len(np.unique(y_train))

estimators = {
    cov_type: GaussianMixture(
        n_components=n_classes, covariance_type=cov_type, max_iter=20, random_state=0
    )
    for cov_type in ["spherical", "diag", "tied", "full"]
}

n_estimators = len(estimators)

GMM の楕円を描画する関数を定義する

def make_ellipses(gmm, ax):
    for n, color in enumerate(colors):
        if gmm.covariance_type == "full":
            covariances = gmm.covariances_[n][:2, :2]
        elif gmm.covariance_type == "tied":
            covariances = gmm.covariances_[:2, :2]
        elif gmm.covariance_type == "diag":
            covariances = np.diag(gmm.covariances_[n][:2])
        elif gmm.covariance_type == "spherical":
            covariances = np.eye(gmm.means_.shape[1]) * gmm.covariances_[n]
        v, w = np.linalg.eigh(covariances)
        u = w[0] / np.linalg.norm(w[0])
        angle = np.arctan2(u[1], u[0])
        angle = 180 * angle / np.pi
        v = 2.0 * np.sqrt(2.0) * np.sqrt(v)
        ell = mpl.patches.Ellipse(
            gmm.means_[n, :2], v[0], v[1], angle=180 + angle, color=color
        )
        ell.set_clip_box(ax.bbox)
        ell.set_alpha(0.5)
        ax.add_artist(ell)
        ax.set_aspect("equal", "datalim")

異なる共分散タイプの GMM を描画する

plt.figure(figsize=(3 * n_estimators // 2, 6))
plt.subplots_adjust(
    bottom=0.01, top=0.95, hspace=0.15, wspace=0.05, left=0.01, right=0.99
)

for index, (name, estimator) in enumerate(estimators.items()):
    estimator.means_init = np.array(
        [X_train[y_train == i].mean(axis=0) for i in range(n_classes)]
    )

    estimator.fit(X_train)

    h = plt.subplot(2, n_estimators // 2, index + 1)
    make_ellipses(estimator, h)

    for n, color in enumerate(colors):
        data = iris.data[iris.target == n]
        plt.scatter(
            data[:, 0], data[:, 1], s=0.8, color=color, label=iris.target_names[n]
        )

    for n, color in enumerate(colors):
        data = X_test[y_test == n]
        plt.scatter(data[:, 0], data[:, 1], marker="x", color=color)

    y_train_pred = estimator.predict(X_train)
    train_accuracy = np.mean(y_train_pred.ravel() == y_train.ravel()) * 100
    plt.text(0.05, 0.9, "Train accuracy: %.1f" % train_accuracy, transform=h.transAxes)

    y_test_pred = estimator.predict(X_test)
    test_accuracy = np.mean(y_test_pred.ravel() == y_test.ravel()) * 100
    plt.text(0.05, 0.8, "Test accuracy: %.1f" % test_accuracy, transform=h.transAxes)

    plt.xticks(())
    plt.yticks(())
    plt.title(name)

plt.legend(scatterpoints=1, loc="lower right", prop=dict(size=12))
plt.show()

まとめ

このチュートリアルでは、Python におけるガウス混合モデル (GMM) での異なる共分散タイプの使用方法を示しました。Iris データセットを例にとり、性能の昇順で球状、対角、完全、および結合共分散行列を持つ GMM を比較しました。訓練データとホールドアウトテストデータの両方に予測されたラベルをプロットし、完全共分散は小さなデータセットで過学習しやすく、ホールドアウトテストデータに対してうまく汎化しないことを示しました。