为什么R函数'princomp'和'prcomp'给出不同的特征值?


22

您可以使用十项全能数据集{FactoMineR}重现该数据。问题是为什么计算出的特征值与协方差矩阵的特征值不同。

以下是使用的特征值princomp

> library(FactoMineR);data(decathlon)
> pr <- princomp(decathlon[1:10], cor=F)
> pr$sd^2
      Comp.1       Comp.2       Comp.3       Comp.4       Comp.5       Comp.6 
1.348073e+02 2.293556e+01 9.747263e+00 1.117215e+00 3.477705e-01 1.326819e-01 
      Comp.7       Comp.8       Comp.9      Comp.10 
6.208630e-02 4.938498e-02 2.504308e-02 4.908785e-03 

和使用相同PCA

> res<-PCA(decathlon[1:10], scale.unit=FALSE, ncp=5, graph = FALSE)
> res$eig
          eigenvalue percentage of variance cumulative percentage of variance
comp 1  1.348073e+02           79.659589641                          79.65959
comp 2  2.293556e+01           13.552956464                          93.21255
comp 3  9.747263e+00            5.759799777                          98.97235
comp 4  1.117215e+00            0.660178830                          99.63252
comp 5  3.477705e-01            0.205502637                          99.83803
comp 6  1.326819e-01            0.078403653                          99.91643
comp 7  6.208630e-02            0.036687700                          99.95312
comp 8  4.938498e-02            0.029182305                          99.98230
comp 9  2.504308e-02            0.014798320                          99.99710
comp 10 4.908785e-03            0.002900673                         100.00000

您能向我解释为什么直接计算出的特征值不同于那些特征值吗?(特征向量相同):

> eigen(cov(decathlon[1:10]))$values
 [1] 1.381775e+02 2.350895e+01 9.990945e+00 1.145146e+00 3.564647e-01
 [6] 1.359989e-01 6.363846e-02 5.061961e-02 2.566916e-02 5.031505e-03

另外,替代prcomp方法给出的特征值与直接计算相同:

> prc <- prcomp(decathlon[1:10])
> prc$sd^2
 [1] 1.381775e+02 2.350895e+01 9.990945e+00 1.145146e+00 3.564647e-01
 [6] 1.359989e-01 6.363846e-02 5.061961e-02 2.566916e-02 5.031505e-03

为什么PCA/ princompprcomp给出不同的特征值?


根据您使用协方差矩阵还是相关矩阵,PCA将为您提供不同的结果。
charles.y.zheng 2011年

7
差异似乎相对较小,但可能太大而无法成为简单的数值问题。它可以通过以下方式正火之间的差ñ - 1,例如,之前计算SVD或本征值分解来计算协方差的估计时?ññ-1个
主教

7
@cardinal好猜!注意,两个不同的特征值序列具有相同的连续比率。 因此,一组是另一组的常数倍。倍数是1.025 = 41/40(正好)。我不清楚这是从哪里来的。也许数据集包含41个元素,而OP仅显示前10个元素?
whuber

7
@cardinal实际上:帮助页面princomp:“请注意,默认计算使用除数N作为协方差矩阵。” 帮助页面prcomp:“与princomp不同,使用通常的除数N-1计算方差。”
caracal

2
@caracal,您应该将您的评论复制到答案中(并可能将其设为CW),以便将其接受并可以将问题标记为已解决。
主教

Answers:


16

princompñprcompcovñ-1个ñ

在以下两个的“ 详细信息”部分都提到了这一点help(princomp)

请注意,默认计算使用除数“ N”作为协方差矩阵。

细节的部分help(prcomp)

与不同princomp,方差使用通常的除数N-1计算。

princompñn.obscv

else if (is.null(covmat)) {
    dn <- dim(z)
    if (dn[1L] < dn[2L]) 
        stop("'princomp' can only be used with more units than variables")
    covmat <- cov.wt(z)
    n.obs <- covmat$n.obs
    cv <- covmat$cov * (1 - 1/n.obs)
    cen <- covmat$center
}

您可以通过指定covmat参数而不是参数来避免这种乘法x

princomp(covmat = cov(iris[,1:4]))$sd^2

有关PCA分数的更新:

cor = TRUEprincompprincompžñ

princomp(scale(data))$scoresprincomp(data, cor = TRUE)$scoresñ-1个/ñ


1
您可以考虑将“猜测”替换为“已确认”(请参见上面的评论流。)您还可以考虑编辑答案以使其成为CW。干杯。
主教

@cardinal我没看到这些评论。我只看到那些被投票赞成的人。谢谢。另外,您能否解释做出答案CW的基本原理?有哪些规则/准则?
约书亚·乌尔里希

有人能猜出为什么代码不是简单地cv <- cov.wt(z, method="ML")使两条跟随行变得不必要吗?
caracal

2
@Joshua:我对做出CW答案的建议是因为,答案是通过评论流出现的,并且是由“社区”讨论产生的。由于在评论中已解决该问题,因此我认为将其重新配置为答案是最有意义的,标记为CW表示此合作,并且可以接受该答案并将该问题标记为已解决。(否则,它会在一段时间后自动被软件备份。)
主教

1
@amoeba,在您的编辑评论中提到它会很有帮助。〜450个字符的答案中“在正文中增加了860个字符”并不能帮助任何人评估编辑是否合理。
约书亚·乌尔里希
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.