主成分分析教程 - 将R代码转换为Matlab的问题

5
我正在尝试通过在线查找实际示例来理解PCA。遗憾的是,我发现大多数教程似乎并没有展示PCA的简单实际应用。经过长时间的搜索,我找到了这个网站:http://yatani.jp/HCIstats/PCA,它是一个不错的简单教程。我想在Matlab中重现它的结果,但是该教程使用的是R语言。我一直在尝试在Matlab中复制这些结果,但迄今为止没有成功;我对Matlab还很陌生。我已经按照以下方式创建了数组:
Price = [6,7,6,5,7,6,5,6,3,1,2,5,2,3,1,2];
Software = [5,3,4,7,7,4,7,5,5,3,6,7,4,5,6,3];
Aesthetics = [3,2,4,1,5,2,2,4,6,7,6,7,5,6,5,7];
Brand = [4,2,5,3,5,3,1,4,7,5,7,6,6,5,5,7];

然后在他的示例中,他执行了以下操作:
data <- data.frame(Price, Software, Aesthetics, Brand)

我在网上进行了快速搜索,这似乎是将向量转换为R代码中的数据表。因此,在Matlab中,我做了这个:

dataTable(:,1) = Price;
dataTable(:,2) = Software;
dataTable(:,3) = Aesthetics;
dataTable(:,4) = Brand;

现在我不确定的是接下来的部分。
pca <- princomp(data, cor=TRUE)
summary(pca, loadings=TRUE)

我尝试过使用Matlab的PCA函数

 [COEFF SCORE LATENT] = princomp(dataTable)

但是我的结果与教程中展示的完全不一样。我的结果是:
COEFF =

   -0.5958    0.3786    0.7065   -0.0511
   -0.1085    0.8343   -0.5402   -0.0210
    0.6053    0.2675    0.3179   -0.6789
    0.5166    0.2985    0.3287    0.7321


SCORE =

   -2.3362    0.0276    0.6113    0.4237
   -4.3534   -2.1268    1.4228   -0.3707
   -1.1057   -0.2406    1.7981    0.4979
   -3.6847    0.4840   -2.1400    1.0586
   -1.4218    2.9083    1.2020   -0.2952
   -3.3495   -1.3726    0.5049    0.3916
   -4.1126    0.1546   -2.4795   -1.0846
   -1.7309    0.2951    0.9293   -0.2552
    2.8169    0.5898    0.4318    0.7366
    3.7976   -2.1655   -0.2402   -1.2622
    3.3041    1.0454   -0.8148    0.7667
    1.4969    2.9845    0.7537   -0.8187
    2.3993   -1.1891   -0.3811    0.7556
    1.7836   -0.0072   -0.2255   -0.7276
    2.2613   -0.1977   -2.4966    0.0326
    4.2350   -1.1899    1.1236    0.1509


LATENT =

    9.3241
    2.2117
    1.8727
    0.5124 

然而,在这个教程中的结果是:
Importance of components:
            Comp.1    Comp.2    Comp.3     Comp.4
Standard deviation     1.5589391 0.9804092 0.6816673 0.37925777
Proportion of Variance 0.6075727 0.2403006 0.1161676 0.03595911
Cumulative Proportion  0.6075727 0.8478733 0.9640409 1.00000000

Loadings:
        Comp.1 Comp.2 Comp.3 Comp.4
Price      -0.523         0.848       
Software   -0.177  0.977 -0.120       
Aesthetics  0.597  0.134  0.295 -0.734
Brand       0.583  0.167  0.423  0.674

请问为什么我的结果与教程相差如此之大,是否使用了错误的Matlab函数?此外,如果您能提供PCA的其他简单实用应用示例,将非常有益。我仍在努力理解PCA中的所有概念,我喜欢使用可以编写代码并自己查看结果的示例,这样我就可以自由地尝试,我发现这种学习方式更容易。

非常感谢您的任何帮助!!


如果你是Matlab的新手,为什么不直接使用R呢?;) - Roland
刚开始博士学习,似乎大多数学生都使用Matlab,并且我一直在跟随的大多数示例也是用Matlab编写的。此外,我将收到与我的博士研究相关的其他示例代码,这些代码也将使用Matlab编写,因此我宁愿继续使用Matlab。 - AdamM
1个回答

4

编辑:问题纯粹是缩放。

R代码:

summary(princomp(data, cor = FALSE), loadings=T, cutoff = 0.01)

Loadings:
           Comp.1 Comp.2 Comp.3 Comp.4
Price      -0.596 -0.379  0.706 -0.051
Software   -0.109 -0.834 -0.540 -0.021
Aesthetics  0.605 -0.268  0.318 -0.679
Brand       0.517 -0.298  0.329  0.732

根据Matlab帮助,如果您想要进行缩放操作,应该使用以下代码:
Matlab代码:
princomp(zscore(X))

旧答案(一个红鲱鱼):

help(princomp)(在R中):

计算是使用由cor确定的相关或协方差矩阵上的特征值完成的。这是为了与S-PLUS结果兼容而做出的决定。首选的计算方法是在x上使用svd,就像在prcomp中一样。

请注意,默认计算使用协方差矩阵的除数N。

在R函数prcomp的文档(help(prcomp))中,您可以阅读:

通过对(居中且可能缩放的)数据矩阵进行奇异值分解来完成计算,而不是使用协方差矩阵上的特征值。这通常是数字精度的首选方法。[...]与princomp不同,使用通常的除数N - 1计算方差。

Matlab函数显然使用svd算法。如果我使用示例数据而不进行缩放(即不基于相关性)使用prcom,我会得到:

> prcomp(data)
Standard deviations:
[1] 3.0535362 1.4871803 1.3684570 0.7158006

Rotation:
                  PC1       PC2        PC3         PC4
Price      -0.5957661 0.3786184 -0.7064672  0.05113761
Software   -0.1085472 0.8342628  0.5401678  0.02101742
Aesthetics  0.6053008 0.2675111 -0.3179391  0.67894297
Brand       0.5166152 0.2984819 -0.3286908 -0.73210631

除了无关的符号外,这与Matlab输出完全相同。

我在Matlab中似乎没有找到prcomp这个函数。我需要下载哪个工具箱才能使用这个函数? - AdamM
@AdamM 我错了。问题在于你的Matlab代码中没有进行缩放。 - Roland
感谢您的代码。您能解释一下为什么在R代码中,加载示例中有些结果丢失了吗?例如,如果您查看R代码结果中的PC2,则会丢失一个结果,同样,PC4也会丢失前两个结果。此外他是如何得到累积比例的?我想获得与他相同的结果,以便我可以在Matlab中绘制图形。 - AdamM
我们来看一下summary.princomp中的cutoff参数以及打印函数的代码:getAnywhere(print.summary.princomp) - Roland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接