( EDITED с дополнительной информацией из комментариев)
Хотя реализация PCA в целом нормальна, вы можете либо вычислить ее на основе транспонированных данных, либо сделать убедитесь, что вы указали np.cov()
по какой оси ваша размерность через параметр rowvar
.
Следующее будет работать так, как вы ожидаете:
import numpy as np
def __PCA_fixed(data, rowvar=False):
# Normalize data
data_cent = data - np.mean(data)
# calculate covariance (pass `rowvar` to `np.cov()`)
covarianceMatrix = np.cov(data_cent, rowvar=rowvar, bias=True)
# Find eigenvector and eigenvalue
eigenvalue, eigenvector= np.linalg.eigh(covarianceMatrix)
# Sorting the eigenvectors and eigenvalues:
PCevals = eigenvalue[::-1]
PCevecs = eigenvector[:,::-1]
return PCevals, PCevecs
Тестирование это с некоторыми случайными числами:
data = np.random.randint(0, 100, (100, 10))
PCevals, PCevecs = __PCA_fixed(data)
print(PCevecs.shape)
# (10, 10)
Также обратите внимание, что, в более общих чертах, разложение по сингулярным значениям (np.linalg.svd()
в NumPy) может быть лучшим подходом для анализа главных компонентов (с простой взаимосвязью с разложением собственных значений , которое вы используете и транспонируете).
Как общий стиль кодирования обратите внимание, что может быть хорошей идеей следовать советам PEP-8 , многие из которых можно легко проверить с помощью какого-либо автоматизированного инструмента, например, autopep8
.