【问题标题】:PCA computed by GPflow and Sklearn doesn't matchGPflow 和 Sklearn 计算的 PCA 不匹配
【发布时间】:2018-11-03 07:54:29
【问题描述】:

我正在使用 SklearnGPflow 执行 PCA 分析。我注意到两个库返回的输出不匹配。

请看下面的示例代码sn-p-

import numpy as np
from gpflow.models import PCA_reduce
from sklearn.decomposition import PCA

X = np.random.random((100, 10))

for n in range(1, 6):
    X1 = PCA(n_components=n).fit_transform(X)
    X2 = PCA_reduce(X, n)
    print('[n=%d] allclose=%s' % (n, np.allclose(X1, X2)))

下面是输出-

[n=1] allclose=True
[n=2] allclose=False
[n=3] allclose=False
[n=4] allclose=False
[n=5] allclose=False

只有在主成分数为 1 时才匹配。为什么会出现这种行为?

【问题讨论】:

    标签: python scikit-learn pca gpflow


    【解决方案1】:

    这里有两个不同的问题:

    1. 这两种方法的特征值顺序是相反的。在 sklearn 实现中,特征向量按其特征值的大小递减排序,而在 gpflow 实现中,它们按递增大小排序。特别是,您应该将PCA(n).fit_transform(X)PCA_reduce(X, n)[:, ::-1] 进行比较。这当然也解释了为什么只使用一个组件就能得到预期的结果。

    2. 但是,这本身是不够的:如果 $v$ 是一个长度为 1 且具有给定特征值的特征向量,那么 $-v$ 也是如此,因此您不能简单地使用 np.allclose结果是否一致;您需要考虑潜在的逆转。因此,您可以使用 a = np.all(np.isclose(X1, X2), 0) 之类的东西直接比较向量,b = np.all(np.isclose(X1, -X2), 0)(注意减号)在 X2 中的所有向量都反转时比较它们,从那时起,a | b 成为条件他们同意撤销。最后,np.all(a | b) 将检查这是否适用于每个特征向量。

    确实,对您的测试进行以下修改后,所有的结果都是正确的:

    In [74]: for n in range(1, 6):
        ...:     X1 = PCA(n_components=n).fit_transform(X)
        ...:     X2 = PCA_reduce(X, n)[:, ::-1]
        ...:     print('[n=%d] allclose=%s' % (n, np.all(np.all(np.isclose(X1, X2), 0) | np.all(np.isclose(X1, -X2), 0))))
    
    [n=1] allclose=True
    [n=2] allclose=True
    [n=3] allclose=True
    [n=4] allclose=True
    [n=5] allclose=True
    

    【讨论】:

    • 感谢@fuglede 的详细解释。我有一个快速的问题。你怎么知道这两种方法的特征值顺序是相反的?
    • @RaviJoshi:我只是检查了它们的输出,发现它们被颠倒了。对于 sklearn,我知道会发生什么。对于 GPflow,由于是开源的,因此可以直接 look up what the thing does 并验证其行为。
    猜你喜欢
    • 2014-10-10
    • 2018-09-06
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    • 2020-06-04
    • 2021-11-16
    • 1970-01-01
    相关资源
    最近更新 更多