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]