为什么 PCA 在非线性问题上的表现通常与非线性模型相当?

机器算法验证 主成分分析 降维
2022-04-13 11:23:54

流形学习的标准理由是从潜在空间到观察空间的映射是非线性的。例如,下面是另一个 StackExchange 用户如何证明 Isomap 优于 PCA

在这里,我们正在寻找二维中的一维结构。这些点位于 S 形曲线上。PCA 试图用线性一维流形来描述数据,它只是一条线;当然,一条线非常适合这些数据。Isomap 正在寻找非线性(即弯曲!)一维流形,并且应该能够发现潜在的 S 形曲线。

PCA 与 Isomap

然而,根据我的经验,要么 PCA 与非线性模型相当好,要么非线性模型也失败了。例如,考虑这个结果:

正弦函数图上的 PCA 与 Isomap

一个简单的潜在变量随时间变化。进入观察空间的地图共有三张。二是噪音;一个是正​​弦波(参见下面的代码 1)。显然,观察空间中的大值并不对应于大x潜在空间中的价值。这是按索引着色的数据:

在此处输入图像描述

在这种情况下,PCA 和 Isomap 一样好。我的第一个问题:为什么 PCA 在这里做得很好?地图不是非线性的吗?


你可能会说这个问题太简单了。这是一个更复杂的例子。让我们介绍两个非线性:非线性潜在空间和非线性映射。在这里,潜在变量的形状像“S”。并且这些地图是 GP 分发的,这意味着如果有J地图,每个fj(x)N(0,Kx), 在哪里Kx是基于核函数的协方差矩阵(参见下面的代码 2)。同样,PCA 做得很好。事实上,其数据生成过程完全匹配的 GPLVM似乎与它的 PCA 初始化没有太大偏差:

GP 分布式地图上的 PCA、Isomap 和 GPLVM

所以我再次问:这里发生了什么?为什么我不破坏 PCA?


最后,我可以打破 PCA 并仍然从流形学习器中获得一些结构化的唯一方法是,如果我真的将潜在变量“嵌入”到更高维空间中(参见下面的代码 3):

嵌入式数据上的 PCA、Isomap 和 GPLVM

总而言之,我有几个问题我认为与共同的误解有关:

  1. 为什么 PCA 在简单的非线性映射(正弦函数)上表现出色?这些地图不是线性的建模假设吗?

  2. 为什么 PCA 在双重非线性问题上的表现与 GPLVM 一样好?特别令人惊讶的是,我使用了 GPLVM 的数据生成过程。

  3. 为什么第三个案例最终打破了 PCA?这个问题有什么不同?

我很欣赏这是一个广泛的问题,但我希望对这些问题有更多了解的人可以帮助综合和完善它。

编辑:

非线性可分且具有非线性映射的潜在变量上的 PCA:

界


代码

1.线性潜变量,非线性映射

import matplotlib.pyplot as plt
import numpy as np
from   sklearn.decomposition import PCA
from   sklearn.manifold import Isomap


def gen_data():
    n_features = 3
    n_samples  = 500
    time       = np.arange(1, n_samples+1)
    # Latent variable is a straight line.
    lat_var    = 3 * time[:, np.newaxis]
    data = np.empty((n_samples, n_features))
    # But mapping functions are nonlinear or nose.
    data[:, 0] = np.sin(lat_var).squeeze()
    data[:, 1] = np.random.normal(0, 1, size=n_samples)
    data[:, 2] = np.random.normal(0, 1, size=n_samples)
    return data, lat_var, time


data, lat_var, time = gen_data()

lat_var_pca = PCA(n_components=1).fit_transform(data)
lat_var_iso = Isomap(n_components=1).fit_transform(data)

fig, (ax1, ax2, ax3) = plt.subplots(1, 3)
fig.set_size_inches(20, 5)

ax1.set_title('True')
ax1.scatter(time, lat_var, c=time)
ax2.set_title('PCA')
ax2.scatter(time, lat_var_pca, c=time)
ax3.set_title('Isomap')
ax3.scatter(time, lat_var_iso, c=time)

plt.tight_layout()
plt.show()

2.非线性潜变量,GP分布图

from   GPy.models import GPLVM
import matplotlib.pyplot as plt
import numpy as np
from   sklearn.decomposition import PCA
from   sklearn.datasets import make_s_curve
from   sklearn.manifold import Isomap
from   sklearn.metrics.pairwise import rbf_kernel


def gen_data():
    n_features = 10
    n_samples  = 500

    # Latent variable is 2D S-curve.
    lat_var, time = make_s_curve(n_samples)
    lat_var = np.delete(lat_var, obj=1, axis=1)
    lat_var /= lat_var.std(axis=0)

    # And maps are GP-distributed.
    mean = np.zeros(n_samples)
    cov  = rbf_kernel(lat_var)
    data = np.random.multivariate_normal(mean, cov, size=n_features).T

    return data, lat_var, time


data, lat_var, time = gen_data()

lat_var_pca = PCA(n_components=2).fit_transform(data)
lat_var_iso = Isomap(n_components=2).fit_transform(data)
gp = GPLVM(data, input_dim=2)
gp.optimize()
lat_var_gp = gp.X

fig, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4)
fig.set_size_inches(20, 5)

ax1.set_title('True')
ax1.scatter(lat_var[:, 0], lat_var[:, 1], c=time)
ax2.set_title('PCA')
ax2.scatter(lat_var_pca[:, 0], lat_var_pca[:, 1], c=time)
ax3.set_title('Isomap')
ax3.scatter(lat_var_iso[:, 0], lat_var_iso[:, 1], c=time)
ax4.set_title('GPLVM')
ax4.scatter(lat_var_gp[:, 0], lat_var_gp[:, 1], c=time)

plt.tight_layout()
plt.show()

3. 嵌入高维空间的非线性潜变量

from   GPy.models import GPLVM
import matplotlib.pyplot as plt
import numpy as np
from   sklearn.datasets import make_s_curve
from   sklearn.decomposition import PCA
from   sklearn.manifold import Isomap


def gen_data():
    n_features = 10
    n_samples = 500

    # Latent variable is 2D S-curve.
    lat_var, time = make_s_curve(n_samples)
    lat_var = np.delete(lat_var, obj=1, axis=1)
    lat_var /= lat_var.std(axis=0)

    # And maps are GP-distributed.
    data = np.random.normal(0, 1, size=(n_samples, n_features))
    data[:, 0] = lat_var[:, 0]
    data[:, 1] = lat_var[:, 1]

    return data, lat_var, time


data, lat_var, time = gen_data()

lat_var_pca = PCA(n_components=2).fit_transform(data)
lat_var_iso = Isomap(n_components=2).fit_transform(data)
gp = GPLVM(data, input_dim=2)
gp.optimize()
lat_var_gp = gp.X

fig, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4)
fig.set_size_inches(20, 5)

ax1.set_title('True')
ax1.scatter(lat_var[:, 0], lat_var[:, 1], c=time)
ax2.set_title('PCA')
ax2.scatter(lat_var_pca[:, 0], lat_var_pca[:, 1], c=time)
ax3.set_title('Isomap')
ax3.scatter(lat_var_iso[:, 0], lat_var_iso[:, 1], c=time)
ax4.set_title('GPLVM')
ax4.scatter(lat_var_gp[:, 0], lat_var_gp[:, 1], c=time)

plt.tight_layout()
plt.show()

4. 不能与 GP 分布图线性分离的潜在变量

from   GPy.models import GPLVM
import matplotlib.pyplot as plt
import numpy as np
from   sklearn.decomposition import PCA
from   sklearn.datasets import make_circles
from   sklearn.manifold import Isomap
from   sklearn.metrics.pairwise import rbf_kernel


def gen_data():
    n_features = 20
    n_samples  = 500
    lat_var, time = make_circles(n_samples)
    mean = np.zeros(n_samples)
    cov  = rbf_kernel(lat_var)
    data = np.random.multivariate_normal(mean, cov, size=n_features).T
    return data, lat_var, time


data, lat_var, time = gen_data()

lat_var_pca = PCA(n_components=2).fit_transform(data)
lat_var_iso = Isomap(n_components=2).fit_transform(data)
gp = GPLVM(data, input_dim=2)
gp.optimize()
lat_var_gp = gp.X

fig, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4)
fig.set_size_inches(20, 5)

ax1.set_title('True')
ax1.scatter(lat_var[:, 0], lat_var[:, 1], c=time)
ax2.set_title('PCA')
ax2.scatter(lat_var_pca[:, 0], lat_var_pca[:, 1], c=time)
ax3.set_title('Isomap')
ax3.scatter(lat_var_iso[:, 0], lat_var_iso[:, 1], c=time)
ax4.set_title('GPLVM')
ax4.scatter(lat_var_gp[:, 0], lat_var_gp[:, 1], c=time)

plt.tight_layout()
plt.show()
1个回答

您没有破坏 PCA 的原因是您的数据仍然“简单”并且具有强大的“线性属性”。

在您的第一个示例中,线示例中,我们可以将数据总结如下:回归目标将更大,相对于 x 和 y,即在原始特征空间中,右上角。

在你的第二个例子,S形例子中,我们可以将数据总结为:回归目标会更大,当x小y小,即在原始特征空间中,左下角。

以下示例将破坏线性 PCA。因为我们可以找到对不同类别进行分类的非线性关系/特征。(对于此类数据,类似于 pearson 相关系数将接近 0。)

在此处输入图像描述