PCA, вычисленный GPflow, и Sklearn не совпадает - PullRequest
0 голосов
/ 03 ноября 2018

Я выполняю анализ PCA, используя Sklearn и GPflow . Я заметил, что выходные данные, возвращаемые обеими библиотеками, не совпадают.

Пожалуйста, смотрите ниже пример кода -

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. Почему такое поведение?

1 Ответ

0 голосов
/ 03 ноября 2018

Здесь сговорились две разные проблемы:

  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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...