Kernel PCA による主成分分析

Beginner

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

はじめに

主成分分析 (Principal Component Analysis: PCA) は、データセットの次元を削減しながら、その元の変動の大部分を保つために使用される手法です。ただし、PCA は線形手法であり、データが非線形構造を持つ場合にはうまく機能しないことがあります。そのような場合には、代わりに Kernel PCA を使用できます。この実験では、PCA と Kernel PCA の違いとそれらの使い方を示します。

VM のヒント

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

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

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

データセットを読み込む

sklearn.datasetsmake_circles 関数を使って、2 つの入れ子になった円から構成されるデータセットを作成します。

from sklearn.datasets import make_circles
from sklearn.model_selection import train_test_split

X, y = make_circles(n_samples=1_000, factor=0.3, noise=0.05, random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=0)

データセットを可視化する

生成したデータセットを可視化するために、matplotlib を使ってデータセットをプロットします。

import matplotlib.pyplot as plt

_, (train_ax, test_ax) = plt.subplots(ncols=2, sharex=True, sharey=True, figsize=(8, 4))

train_ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train)
train_ax.set_ylabel("Feature #1")
train_ax.set_xlabel("Feature #0")
train_ax.set_title("Training data")

test_ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test)
test_ax.set_xlabel("Feature #0")
_ = test_ax.set_title("Testing data")

PCA を使ってデータセットを射影する

PCA は、データセットの元の変動の大部分を保つ新しい空間にデータセットを射影するために使用されます。

from sklearn.decomposition import PCA

pca = PCA(n_components=2)

X_test_pca = pca.fit(X_train).transform(X_test)

Kernel PCA を使ってデータセットを射影する

Kernel PCA は、データセットの元の変動の大部分を保つだけでなく、非線形構造も許容する新しい空間にデータセットを射影するために使用されます。

from sklearn.decomposition import KernelPCA

kernel_pca = KernelPCA(
    n_components=None, kernel="rbf", gamma=10, fit_inverse_transform=True, alpha=0.1
)

X_test_kernel_pca = kernel_pca.fit(X_train).transform(X_test)

PCA と Kernel PCA の射影を可視化する

PCA と Kernel PCA の射影をプロットして、それらの違いを可視化します。

fig, (orig_data_ax, pca_proj_ax, kernel_pca_proj_ax) = plt.subplots(
    ncols=3, figsize=(14, 4)
)

orig_data_ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test)
orig_data_ax.set_ylabel("Feature #1")
orig_data_ax.set_xlabel("Feature #0")
orig_data_ax.set_title("Testing data")

pca_proj_ax.scatter(X_test_pca[:, 0], X_test_pca[:, 1], c=y_test)
pca_proj_ax.set_ylabel("Principal component #1")
pca_proj_ax.set_xlabel("Principal component #0")
pca_proj_ax.set_title("Projection of testing data\n using PCA")

kernel_pca_proj_ax.scatter(X_test_kernel_pca[:, 0], X_test_kernel_pca[:, 1], c=y_test)
kernel_pca_proj_ax.set_ylabel("Principal component #1")
kernel_pca_proj_ax.set_xlabel("Principal component #0")
_ = kernel_pca_proj_ax.set_title("Projection of testing data\n using KernelPCA")

Kernel PCA の射影を元の空間に逆射影する

Kernel PCA の射影を元の空間に逆射影するために、Kernel PCA の inverse_transform メソッドを使用します。

X_reconstructed_kernel_pca = kernel_pca.inverse_transform(kernel_pca.transform(X_test))

再構築されたデータセットを可視化する

元のデータセットと再構築されたデータセットをプロットして比較します。

fig, (orig_data_ax, pca_back_proj_ax, kernel_pca_back_proj_ax) = plt.subplots(
    ncols=3, sharex=True, sharey=True, figsize=(13, 4)
)

orig_data_ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test)
orig_data_ax.set_ylabel("Feature #1")
orig_data_ax.set_xlabel("Feature #0")
orig_data_ax.set_title("Original test data")

pca_back_proj_ax.scatter(X_reconstructed_pca[:, 0], X_reconstructed_pca[:, 1], c=y_test)
pca_back_proj_ax.set_xlabel("Feature #0")
pca_back_proj_ax.set_title("Reconstruction via PCA")

kernel_pca_back_proj_ax.scatter(
    X_reconstructed_kernel_pca[:, 0], X_reconstructed_kernel_pca[:, 1], c=y_test
)
kernel_pca_back_proj_ax.set_xlabel("Feature #0")
_ = kernel_pca_back_proj_ax.set_title("Reconstruction via KernelPCA")

まとめ

この実験では、PCA と Kernel PCA の違いについて学びました。PCA と Kernel PCA を使ってデータセットを新しい空間に射影し、その射影を可視化しました。また、Kernel PCA を使って射影を元の空間に逆射影し、元のデータセットと比較しました。