核主成分分析 (Kernel PCA)#

此示例展示了主成分分析 (PCA) 及其核化版本 (KernelPCA) 之间的区别。

一方面,我们展示了 KernelPCA 能够找到线性分离数据的投影,而 PCA 则不能。

最后,我们展示了使用 KernelPCA 反转此投影是一种近似,而使用 PCA 则是精确的。

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

数据投影:PCAKernelPCA#

在本节中,我们将展示使用核函数进行主成分分析 (PCA) 投影数据的优势。我们创建一个由两个嵌套圆组成的数据集。

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)

让我们快速了解一下生成的数据集。

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")
Training data, Testing data

每个类别的样本都不能线性分离:没有直线可以将内部集合的样本与外部集合的样本分开。

现在,我们将使用带核和不带核的 PCA,以了解使用此类核函数的效果。这里使用的核函数是径向基函数 (RBF) 核。

from sklearn.decomposition import PCA, KernelPCA

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

X_test_pca = pca.fit(X_train).transform(X_test)
X_test_kernel_pca = kernel_pca.fit(X_train).transform(X_test)
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")
Testing data, Projection of testing data  using PCA, Projection of testing data  using KernelPCA

我们回顾一下,PCA 对数据进行线性变换。直观地说,这意味着坐标系将被居中,每个分量将根据其方差进行重新缩放,最后进行旋转。从这种变换中获得的数据是各向同性的,现在可以投影到其主成分上。

因此,观察使用 PCA 进行的投影(即中间的图),我们看到缩放没有变化;事实上,数据是两个以零为中心同心圆,原始数据已经是各向同性的。但是,我们可以看到数据已经旋转。综上所述,我们看到如果定义一个线性分类器来区分两个类别的样本,这样的投影将无济于事。

使用核函数可以进行非线性投影。在这里,通过使用 RBF 核,我们期望投影能够展开数据集,同时近似保留原始空间中相互靠近的数据点对的相对距离。

我们在右图中观察到了这种行为:给定类别的样本彼此之间比与对立类别的样本更接近,从而解开了两个样本集。现在,我们可以使用线性分类器来分离这两个类别的样本。

投影回原始特征空间#

使用 KernelPCA 时需要记住的一个特点与重构(即在原始特征空间中的反向投影)有关。使用 PCA 时,如果 n_components 与原始特征的数量相同,则重构将是精确的。本示例中就是这种情况。

我们可以研究使用 KernelPCA 反向投影时是否能得到原始数据集。

X_reconstructed_pca = pca.inverse_transform(pca.transform(X_test))
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")
Original test data, Reconstruction via PCA, Reconstruction via KernelPCA

虽然我们看到 PCA 实现了完美的重构,但 KernelPCA 的结果则不同。

实际上,inverse_transform 不能依赖于解析反向投影,因此无法实现精确重构。相反,内部会训练一个 KernelRidge 来学习从核化 PCA 基到原始特征空间的映射。因此,这种方法带有一个近似,在反向投影到原始特征空间时会引入细微差异。

为了提高使用 inverse_transform 进行的重构,可以调整 KernelPCA 中的 alpha 参数,该参数是正则化项,控制映射训练过程中对训练数据的依赖程度。

脚本总运行时间: (0 分钟 0.548 秒)

相关示例

使用核主成分分析进行图像去噪

使用核主成分分析进行图像去噪

特征缩放的重要性

特征缩放的重要性

增量主成分分析

增量主成分分析

人脸数据集分解

人脸数据集分解

由 Sphinx-Gallery 生成的图库