Разница в результатах для sci-kit learn PCA и ручного PCA

Я действительно озадачен, надеюсь, кто-нибудь сможет показать мне, чего я упускаю. Я пытаюсь получить основные компоненты двумя разными способами:

import numpy as np
data = np.array([[ 2.1250045 , -0.17169867, -0.47799957],
               [ 0.7400025 , -0.07970344, -0.99600106],
               [ 0.15800177,  1.2993019 , -0.8030003 ],
               [ 0.3159989 ,  1.919297  ,  0.24300112],
               [-0.14800562, -1.0827019 , -0.2890004 ],
               [ 0.26900184, -1.3816979 ,  1.1239979 ],
               [-0.5040008 , -2.9066994 ,  1.6400006 ],
               [-1.2230027 , -2.415702  ,  3.1940014 ],
               [-0.54700005,  1.757302  , -1.825999  ],
               [-1.1860001 ,  3.0623024 , -1.8090007 ]]) # this should already be mean centered



# Method 1. Scikit-Learn
from sklearn.decomposition import PCA

pca = PCA(n_components=3).fit(data)
print(pca.components_)
[[-0.04209988 -0.79261507  0.60826717]
 [ 0.88594009 -0.31106375 -0.34401963]
 [ 0.46188501  0.52440508  0.71530521]]


# Method 2. Manually with numpy
cov = np.cov(data.T)

evals , evecs = np.linalg.eig(cov)

# The next three lines are just sorting by the largest eigenvalue
idx = np.argsort(evals)[::-1]
evecs = evecs[:,idx]
evals = evals[idx]

print(evecs.T)
[[ 0.04209988  0.79261507 -0.60826717]
 [ 0.88594009 -0.31106375 -0.34401963]
 [-0.46188501 -0.52440508 -0.71530521]]

Значения собственных векторов такие же, но знаки неправильные. Я хочу получить вывод из sklearn PCA, но используя только numpy. Спасибо заранее за любые предложения.


person cschlick    schedule 25.06.2020    source источник


Ответы (1)


Это ожидается, потому что собственное подпространство матрицы (ковариационная матрица в вашем вопросе) уникально, а конкретный набор собственных векторов - нет. Здесь слишком много объяснений, поэтому я бы порекомендовал ответ на math.se

PS: Обратите внимание, что вы имеете дело с ковариационной матрицей 3x3, и вы можете представить собственные векторы как векторы в 3D с осями x, y, z. Затем вы должны заметить, что ваш numpy answer vs sklearn answer находятся в прямо противоположном направлении для 2 векторов и в том же направлении для 1 вектора.

person adrtam    schedule 25.06.2020