Почему PCA на ковариационной матрице? - PullRequest
0 голосов
/ 24 апреля 2020

Мне интересно, зачем выбирать ковариационную матрицу для проведения PCA. Смотрите мой код ниже. Зависимость между PCA и SVD состоит в том, что собственные значения являются квадратом сингулярных значений SVD в Python. Но дело в том, что только если я вычислю собственные значения с помощью:

eigen_vals, eigen_vecs = np.linalg.eigh((X_train.T).dot(X_train))

вместо

sc = StandardScaler()
X_train_std = sc.fit_transform(X_train)
cov_mat = np.cov(X_train_std.T)
eigen_vals, eigen_vecs = np.linalg.eigh(cov_mat)
eigen_vals = np.asarray(sorted(eigen_vals, reverse=True))

, я получу те же результаты, что и с SVD. (См. Выходные собственные значения и S ** 2 ниже в Коде)

Но первая НЕ является ковариационной матрицей, потому что она без масштабирования 1 / (N-1). Я уже прочитал этот пост Отношения между SVD и PCA. Как использовать SVD для выполнения PCA? , особенно пост от amoeba, но я не понимаю, почему здесь разные результаты без использования ковариационной матрицы.

Может кто-нибудь помочь мне с этой проблемой пожалуйста?

Мой код:

import numpy as np
from scipy.linalg import svd
from sklearn.preprocessing import StandardScaler
from matplotlib import pyplot as plt



X_train = np.asarray([[13.71,1.86,2.36,16.6],[12.22,1.29,1.94,19],
           [13.27,4.28,2.26,20],[13.16,3.57,2.15,21],
           [13.86,1.51,2.67,25]])


#PCA
sc = StandardScaler()
X_train_std = sc.fit_transform(X_train)

cov_mat = np.cov(X_train_std.T)
eigen_vals, eigen_vecs = np.linalg.eigh(cov_mat)
eigen_vals = np.asarray(sorted(eigen_vals, reverse=True))

#SVD
U,eigen_vals_S,Vt = svd(X_train)
eigen_vals_S2 = (eigen_vals_S**2)

print('Eigenvalues \n%s' % eigen_vals)
print('S \n%s' %eigen_vals_S)
print('S**2 \n%s' %eigen_vals_S2)


#Eigenvalues 
#[2.79331043 1.28393579 0.90313734 0.01961644]
#
#S 
#[55.02775284  3.37434634  2.52347705  0.28664958]
#
#S**2 
#[3.02805358e+03 1.13862132e+01 6.36793643e+00 8.21679822e-02]



#Same eigenvalues
eigen_vals, eigen_vecs = np.linalg.eigh((X_train.T).dot(X_train))
eigen_vals = np.asarray(sorted(eigen_vals, reverse=True))

#SVD
U,eigen_vals_S,V = svd(X_train)
eigen_vals_S2 = (eigen_vals_S**2)

print('\n\nSAME RESULTS:')
print('Eigenvalues \n%s' % eigen_vals)
print('S \n%s' %eigen_vals_S)
print('S**2 \n%s' %eigen_vals_S2)


# OUTPUT
#Eigenvalues 
#[3.02805358e+03 1.13862132e+01 6.36793643e+00 8.21679822e-02]
#
#S 
#[55.02775284  3.37434634  2.52347705  0.28664958]
#
#S**2 
#[3.02805358e+03 1.13862132e+01 6.36793643e+00 8.21679822e-02]
...