我想知道numpy / scipy中的哪个函数对应于MATLAB中的pcacov()。如果没有相应的那个,那么实现该功能的最佳方法是什么?
谢谢!
答案 0 :(得分:1)
NumPy和SciPy没有针对PCA的特定例程,但它们确实具有计算它所需的线性代数原语。任何语言中的任何pca函数基本上只是围绕特征值或奇异值分解的光包装,具有关于居中,归一化,矩阵维度的含义和术语(特征向量,主成分,主要向量,潜在变量等)的不同约定。同一个东西都有不同的名称,有时略有变化。)
因此,例如,给定矩阵X
,您可以使用SVD计算PCA:
import numpy as np
def pca(X):
X_centered = X - X.mean(0)
u, s, vt = np.linalg.svd(X_centered)
evals = s[::-1] ** 2 / (X.shape[0] - 1)
evecs = vt[::-1].T
return evals, evecs
np.random.seed(0)
X = np.random.rand(100, 3)
evals, evecs = pca(X)
print(evals)
# [ 0.06820946 0.08738236 0.09858988]
print(evecs)
# [[-0.49659797 0.4567562 -0.73808145]
# [ 0.34847559 0.88371847 0.31242029]
# [ 0.79495611 -0.10205609 -0.59802118]]
如果你有一个协方差矩阵,你可以使用特征值分解来计算PCA:
def pcacov(C):
return np.linalg.eigh(C)
C = np.cov(X.T)
evals, evecs = pcacov(C)
print(evals)
# [ 0.06820946 0.08738236 0.09858988]
print(evecs)
# [[-0.49659797 -0.4567562 -0.73808145]
# [ 0.34847559 -0.88371847 0.31242029]
# [ 0.79495611 0.10205609 -0.59802118]]
结果是相同的,直到特征向量列中的符号。
现在,我在这里使用了一组特定的约定,关于数据点是否在行或列中,协方差是如何规范化的等等,并且这些细节因PCA的实现而异。因此,Matlab代码可能会给出不同的结果,因为它在内部使用不同的约定。但在幕后,它做的事情与上面使用的计算非常相似。