Уменьшение размерности анализа главных компонентов в python - PullRequest
0 голосов
/ 27 июня 2018

Я должен реализовать свою собственную функцию PCA Y, V = PCA (данные, M, отбеливание), которая вычисляет первый M-принципал компоненты и преобразует данные, так что y_n = U ^ T x_n. Функция должна далее возврат V, который объясняет величину дисперсии, которая объясняется преобразованием.

Мне нужно уменьшить размерность данных от D = 4 до M = 2> с учетом функции ниже <</p>

def PCA(data,nr_dimensions=None, whitening=False):
""" perform PCA and reduce the dimension of the data (D) to nr_dimensions
Input:
    data... samples, nr_samples x D
    nr_dimensions... dimension after the transformation, scalar
    whitening... False -> standard PCA, True -> PCA with whitening

Returns:
    transformed data... nr_samples x nr_dimensions
    variance_explained... amount of variance explained by the the first nr_dimensions principal components, scalar"""
if nr_dimensions is not None:
    dim = nr_dimensions
else:
    dim = 2

я сделал следующее:

import numpy as np
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
import scipy.stats as stats

from scipy.stats import multivariate_normal
import pdb

import sklearn
from sklearn import datasets

#covariance matrix
mean_vec = np.mean(data)
cov_mat = (data - mean_vec).T.dot((data - mean_vec)) / (data.shape[0] - 1)
print('Covariance matrix \n%s' % cov_mat)

#now the eigendecomposition of the cov matrix
cov_mat = np.cov(data.T)
    eig_vals, eig_vecs = np.linalg.eig(cov_mat)
    print('Eigenvectors \n%s' % eig_vecs)
    print('\nEigenvalues \n%s' % eig_vals)

# Make a list of (eigenvalue, eigenvector) tuples
eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:,i]) for i in range(len(eig_vals))]

В этот момент я не знаю, что делать сейчас и как уменьшить размерность.

Любая помощь будет приветствоваться! :)

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

PCA фактически аналогичен разложению по единственному значению, поэтому вы можете использовать либо numpy.linalg.svd:

import numpy as np
def PCA(U,ndim,whitening=False):
    L,G,R=np.linalg.svd(U,full_matrices=False)
    if not whitening:
        L=L @ G
    Y=L[:,:ndim] @ R[:,:ndim].T
    return Y,G[:ndim]

Если вы хотите использовать проблему собственных значений, то, если предположить, что число выборок больше, чем количество объектов (или ваши данные будут недостаточно подходящими), неэффективно напрямую вычислять пространственные корреляции (левые собственные векторы). Вместо этого, используя SVD, используйте правильные собственные функции:

def PCA(U,ndim,whitening=False):
    K=U.T @ U               # Calculating right eigenvectors
    G,R=np.linalg.eigh(K)
    G=G[:,::-1]
    R=R[::-1]
    L=U @ R                 # reconstructing left ones
    nrm=np.linalg.norm(L,axis=0,keepdims=True)  #normalizing them
    L/=nrm
    if not whitening:
        L=L @ G
    Y=L[:,:ndim] @ R[:,:ndim].T
    return Y,G[:ndim]
0 голосов
/ 27 июня 2018

Вот простой пример for the case, где исходная матрица A, которая содержит образцы и элементы, имеет shape=[samples, features]

from numpy import array
from numpy import mean
from numpy import cov
from numpy.linalg import eig

# define a matrix
A = array([[1, 2], [3, 4], [5, 6]])
print(A)

# calculate the mean of each column since I assume that it's column is a variable/feature
M = mean(A.T, axis=1)
print(M)

# center columns by subtracting column means
C = A - M
print(C)

# calculate covariance matrix of centered matrix
V = cov(C.T)
print(V)

# eigendecomposition of covariance matrix
values, vectors = eig(V)
print(vectors)
print(values)

# project data
P = vectors.T.dot(C.T)
print(P.T)
...