Различные результаты с PCA и SVD для данных с одинаковыми единицами - PullRequest
0 голосов
/ 23 апреля 2020

В начале у меня было 400 000 нормализованных изображений (увеличение значения серого). После этого я сделал DFT для каждого изображения и получил данные 400000 выборок с 3200 абсолютными коэффициентами Фурье.

Теперь я хотел бы сделать PCA и SVD. Поскольку мои данные уже нормализованы и все значения имеют одинаковые единицы , я подумал, что могу использовать «необработанные данные» для расчета. Однако собственные значения PCA и сингулярные значения SVD различны. (показать изображение / ссылку)

Что я делаю не так? Как данные должны быть доступны для PCA и SVD? нормализованный, стандартизированный, сырой?

Пожалуйста, помогите мне! Спасибо

Мой код:

# samples 400000x3200
# SVD
U,S,VT = svd(samples, full_matrices=False) 

tot_S = sum(S)
var_exp_S = [(i / tot_S) for i in S]
cum_var_exp_S = np.cumsum(var_exp_S)

# PCA
cov_mat = np.cov(samples.T)
eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)
eigen_vals = np.asarray(sorted(eigen_vals,reverse=True))

tot = sum(eigen_vals)
var_exp = [(i / tot) for i in eigen_vals]
cum_var_exp = np.cumsum(var_exp)


num= 3200
plt.figure(figsize=(10,5))
plt.subplot(121)
plt.title('PCA')
plt.step(range(1,num+1),cum_var_exp[:num], where='mid',color='r')
plt.ylabel('share of variance')
plt.xlabel('principal components')
plt.legend()
plt.grid()

plt.subplot(122)
plt.title('SVD')
plt.step(range(1,num+1),cum_var_exp_S[:num], where='mid',color='r')
plt.ylabel('share of variance')
plt.xlabel('principal components')
plt.legend()
plt.grid()

Ответы [ 3 ]

1 голос
/ 23 апреля 2020

Есть некоторые «нормализации» в PCA. Вот код из моей собственной библиотеки PCA:


//normalize to center
centred = center( samples );
//normalize to square matrix
matrix = cov( centred );
//eigenvalue decomposition
vectors = evd( matrix );
//get normalized eigenvectors:
eigenvectors = get_eigenvectors( vectors );
//get eigenvalues:
eigenvalues = get_eigenvalues( vectors );

Отношение между SVD и PCA описывается так: Собственные значения M * M - это квадраты сингулярных значений M.

0 голосов
/ 23 апреля 2020

Эти изображения из набора данных (400000x3200):

PCA

SVD

0 голосов
/ 23 апреля 2020

Вот пример:

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

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,V = svd(X_train)
eigen_vals_S2 = (eigen_vals_S**2)

print('\nEigenvalues \n%s' % eigen_vals)
print('\nS \n%s' %eigen_vals_S)
print('\nS**2 \n%s' %eigen_vals_S2)re

Вывод (Собственные значения и S ** 2 различны):

Собственные значения [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('\nEigenvalues \n%s' % eigen_vals)
print('\nS \n%s' %eigen_vals_S)
print('\nS**2 \n%s' %eigen_vals_S2)

Выход:

Собственные значения [3.02805358e + 03 1.13862132e + 01 6.36793643e + 00 8.21679822e-02]

S [55.02775284 3.37434634 2.52347705 0.2866495

S ** 2 [3.02805358e + 03 1.13862132e + 01 6.36793643e + 00 8.21679822e-02]

И вот чего я не понимаю. Путь со стандартизацией и cov () - это метод для PCA. Но, как вы можете видеть, есть разные результаты, в зависимости от того, как я вычисляю собственные значения ....

Я что-то не так или почему это так?

...