はじめに
主成分分析 (Principal Component Analysis: PCA) は、データセットの次元を削減しながら、その元の変動の大部分を保つために使用される手法です。ただし、PCA は線形手法であり、データが非線形構造を持つ場合にはうまく機能しないことがあります。そのような場合には、代わりに Kernel PCA を使用できます。この実験では、PCA と Kernel PCA の違いとそれらの使い方を示します。
VM のヒント
VM の起動が完了したら、左上隅をクリックして ノートブック タブに切り替えて、Jupyter Notebook を使って練習しましょう。
時々、Jupyter Notebook が読み込み終わるまで数秒待つ必要がある場合があります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。
学習中に問題に直面した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。
データセットを読み込む
sklearn.datasets の make_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 を使って射影を元の空間に逆射影し、元のデータセットと比較しました。