Чому 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
nn1

7
@cardinal Приємна здогадка! Зауважте, що дві різні послідовності власних значень мають однакові послідовні співвідношення. Таким чином, один набір є постійним кратним іншого. Множина 1,025 = 41/40 ( рівно ). Мені незрозуміло, звідки це походить. Можливо, набір даних має 41 елемент, а ОП виявляє лише перші 10?
whuber

7
@cardinal Дійсно: Сторінка довідки для princomp: "Зверніть увагу, що для обчислення за замовчуванням використовується дільник N для матриці коваріації." Сторінка довідки prcomp: "На відміну від princomp, відхилення обчислюються зі звичайним дільником N-1."
каракал

2
@caracal, ви повинні скопіювати свій коментар у відповідь (і, можливо, зробити це CW), щоб його можна було прийняти, а питання можна позначити як вирішене.
кардинал

Відповіді:


16

princompNprcompcovN1N

Про це йдеться в обох розділах " Деталі " 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(N-1)/N


1
Ви можете замінити "здогадався" на "вже підтверджений" (див. Потік коментарів вище.) Ви також можете відредагувати свою відповідь, щоб зробити її CW. Ура.
кардинал

@cardinal Я не бачив цих коментарів. Я бачив лише тих, хто був підкреслений. Спасибі. Також ви могли б пояснити обґрунтування того, як відповісти на відповідь CW? Які правила / вказівки для цього є?
Джошуа Ульріх

Чи може хтось здогадатися, чому код не просто cv <- cov.wt(z, method="ML")робить 2 наступні лінії непотрібними?
каракал

2
@Joshua: Моя пропозиція щодо відповіді на відповідь CW була пов'язана з тим, що відповідь з'явилася через потік коментарів і була сформована дискусією "громади". Оскільки це було вирішено в коментарях, мої думки полягають у тому, що для цього співпраці має найбільш сенс переформулювати його як відповідь, позначений як CW, і це дозволяє прийняти відповідь, а питання відзначити як вирішене. (Інакше програмне забезпечення автоматично завантажиться програмним забезпеченням через певний проміжок часу.)
кардинал

2
@amoeba, було б корисно згадати це у вашому коментарі до редагування. "Додано 860 символів до тіла" до відповіді ~ 450 символів нікому не допомагає оцінити, чи правильне редагування.
Джошуа Ульріх
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.