Matlab和Python为PCA产生不同的结果

use*_*228 0 python matlab pca scikit-learn

我正在使用PCA,我在Python中发现了sklearn中的PCA,而在Matlab中发现了pca()产生了不同的结果.这是我正在使用的测试矩阵.

a = np.array([[-1,-1], [-2,-1], [-3, -2], [1,1], [2,1], [3,2]])
Run Code Online (Sandbox Code Playgroud)

对于Python sklearn,我得到了

p = PCA()
print(p.fit_transform(a))

[[-1.38340578  0.2935787 ]
[-2.22189802 -0.25133484]
[-3.6053038   0.04224385]
[ 1.38340578 -0.2935787 ]
[ 2.22189802  0.25133484]
[ 3.6053038  -0.04224385]]
Run Code Online (Sandbox Code Playgroud)

对于Matlab,我得到了

pca(a', 'Centered', false)

[0.2196    0.5340
0.3526   -0.4571
0.5722    0.0768
-0.2196   -0.5340
-0.3526    0.4571
-0.5722   -0.0768]
Run Code Online (Sandbox Code Playgroud)

为什么观察到这种差异?


谢谢Dan的回答.结果现在看起来很合理.但是,如果我使用随机矩阵进行测试,似乎Matlab和Python正在产生的结果不是彼此的标量倍数.为什么会这样?

test matrix a:

[[ 0.36671885  0.77268624  0.94687497]
[ 0.75741855  0.63457672  0.88671836]
[ 0.20818031  0.709373    0.45114135]
[ 0.24488718  0.87400025  0.89382836]
[ 0.16554686  0.74684393  0.08551401]
[ 0.07371664  0.1632872   0.84217978]]
Run Code Online (Sandbox Code Playgroud)

Python结果:

p = PCA()
p.fit_transform(a))

[[ 0.25305509 -0.10189215 -0.11661895]
[ 0.36137036 -0.20480169  0.27455458]
[-0.25638649 -0.02923213 -0.01619661]
[ 0.14741593 -0.12777308 -0.2434731 ]
[-0.6122582  -0.08568121  0.06790961]
[ 0.10680331  0.54938026  0.03382447]]
Run Code Online (Sandbox Code Playgroud)

Matlab结果:

pca(a', 'Centered', false)

0.504156973865138   -0.0808159771243340 -0.107296852182663
0.502756555190181   -0.174432053627297  0.818826939851221
0.329948209311847   0.315668718703861   -0.138813345638127
0.499181592718705   0.0755364557146097  -0.383301081533716
0.232039797509016   0.694464307249012   -0.0436361728092353
0.284905319274925   -0.612706345940607  -0.387190971583757
Run Code Online (Sandbox Code Playgroud)

感谢Dan的帮助.实际上我发现它是对Matlab函数的误用.Matlab默认返回主成分系数.使用[〜,score] = pca(a,'Centered',true)将获得与Python相同的结果.

Dan*_*Dan 7

PCA处理特征向量.只要向量是平行的,幅度就无关紧要(只是一个不同的标准化).

在你的情况下,这两个是彼此的标量倍数.试试(在MATLAB中)

Python = [-1.38340578  0.2935787 
          -2.22189802 -0.25133484
          3.6053038   0.04224385
          1.38340578 -0.2935787 
          2.22189802  0.25133484
          3.6053038  -0.04224385]

Matlab = [ 0.2196    0.5340
           0.3526   -0.4571
           0.5722    0.0768
          -0.2196   -0.5340
          -0.3526    0.4571
          -0.5722   -0.0768]
Run Code Online (Sandbox Code Playgroud)

现在注意到B(:,1)*-6.2997基本上等于A(:,1).或换一种方式

A(:,n)./B(:,n)
Run Code Online (Sandbox Code Playgroud)

给你(大致)每行的相同数字.这意味着两个向量具有相同的方向(即它们只是彼此的标量倍数),因此您获得相同的主成分.

请看这里的另一个例子:https://math.stackexchange.com/a/1183707/118848