Почему функции 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/ princompи prcompдают разные собственные значения?

Джордж Донтас
источник
PCA даст вам разные результаты в зависимости от того, используете ли вы ковариационную матрицу или корреляционную матрицу.
charles.y.zheng
7
NN-1
7
@ Cardinal Хорошая догадка! Обратите внимание, что две разные последовательности собственных значений имеют идентичные последовательные отношения. Таким образом, один набор является постоянным кратным другого. Мультипликатор равен 1,025 = 41/40 ( точно ). Мне неясно, откуда это. Может быть, в наборе данных 41 элемент, а ОП показывает только первые 10?
whuber
7
@cardinal Действительно: страница справки для princomp: «Обратите внимание, что при расчете по умолчанию для ковариационной матрицы используется делитель N». Страница справки для prcomp: «В отличие от princomp, дисперсии вычисляются с помощью обычного делителя N-1».
Каракал
2
@caracal, вы должны скопировать свой комментарий в ответ (и, возможно, сделать его CW), чтобы он мог быть принят, и вопрос мог быть помечен как решенный.
кардинал

Ответы:

16

princompNprcompcovN-1N

Это упоминается в разделе « Детали » help(princomp):

Обратите внимание, что для расчета по умолчанию используется делитель N для ковариационной матрицы.

и раздел Подробностиhelp(prcomp) :

В отличие от princomp, дисперсии вычисляются с обычным делителем N - 1.

princompNn.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 = TRUEprincompprincompzN

princomp(scale(data))$scoresprincomp(data, cor = TRUE)$scores(N1)/N

Джошуа Ульрих
источник
1
Вы можете подумать о замене «угаданного» на «уже подтвержденный» (см. Поток комментариев выше). Вы также можете рассмотреть возможность редактирования своего ответа, чтобы сделать его CW. Приветствия.
кардинал
@cardinal Я не видел эти комментарии. Я видел только тех, за кого проголосовали. Спасибо. Кроме того, не могли бы вы объяснить обоснование принятия ответа CW? Каковы правила / руководящие принципы для этого?
Джошуа Ульрих
Кто-нибудь может догадаться, почему код не просто cv <- cov.wt(z, method="ML")делает ненужными следующие две строки?
Каракал
2
@ Джошуа: Мое предложение относительно ответа CW было связано с тем, что ответ появился через поток комментариев и был получен в результате обсуждения в сообществе. Поскольку это было решено в комментариях, я думаю, что имеет смысл переформулировать его как ответ, помеченный как CW, чтобы обозначить это сотрудничество, и это позволяет принять ответ и пометить вопрос как решенный. (В противном случае оно будет автоматически восстановлено программным обеспечением через определенное время.)
Кардинал
2
@amoeba было бы полезно упомянуть об этом в вашем комментарии редактирования. «Добавлены 860 символов к телу» в ответе ~ 450 символов не помогает никому оценить, является ли редактирование разумным.
Джошуа Ульрих