首先:这是什么意思?在四维空间中有三个点。它们跨越一个二维平面。PCA找到这个平面的一个基,以及你的点在这个基上的系数。使用Matlab的[C, S] = pca(x)进行比较:我们得到C =
0.4028 0.1082
0.7895 -0.3198
-0.4560 -0.5881
-0.0806 0.7349
以及
^{pr2}$
它们是具有S*C'恢复中心数据的属性的矩阵(在您的符号中是X)。C的列是2D子空间的基向量,S的行是该子集中三个点的坐标。在
Sklearn返回[[ -5.86525831e-01 5.82485371e+00 -2.65147201e-16]
[ -8.96738194e+00 -3.18911605e+00 1.41061647e-16]
[ 9.55390777e+00 -2.63573766e+00 -5.28988843e-16]]
其中第三列是噪声(基本上是零),反映了点位于二维平面上;没有第三个主分量可供找到。前两列与Matlab中的S匹配,但符号选择除外。在
你对“numpywithcov”的计算与sklearn相同,只是第3列中的随机噪声不同。顺便说一句,对于这种计算,您不需要将数据居中;cov会自行进行。cov = np.cov(x.T)也可以。在[[ -5.86525831e-01 -5.82485371e+00 5.26721273e-16]
[ -8.96738194e+00 3.18911605e+00 3.83725073e-15]
[ 9.55390777e+00 2.63573766e+00 -3.35763132e-15]]
“特征面”法
这里的主要思想是,与计算np.dot(X.T, X)(本质上是协方差,直到一个常数因子)不同,我们将使用更小的C = np.dot(X, X.T)。我们需要的基向量将通过将C的特征向量乘以X.T得到(如果你跟随Wikipedia's article,注意它们的T与X的方向不同)。但是,与np.linalg.eig返回的向量不同,这些向量不是标准化的。在使用之前,我们必须将它们规范化:X = x - np.mean(x, axis = 0)
C = np.dot(X, X.T)
evals , evecs = np.linalg.eig(C)
idx = np.argsort(evals)[::-1]
evecs = evecs[:,idx]
evals = evals[idx]
v = np.dot(X.T, evecs)
v /= np.linalg.norm(v, axis=0)
res3 = X.dot(v)
这就回来了[[-0.58652583 -5.82485371 5.05711518]
[-8.96738194 3.18911605 1.72266002]
[ 9.55390777 2.63573766 -6.7797752 ]]
前两列是正确的。同样,第三列是noise,但是现在是noise,经过了正规化,所以它一点也不小。我们必须明白第三栏毫无意义。在