R fonksiyonları 'princomp' ve 'prcomp' neden farklı özdeğerler veriyor?


22

Bunu yeniden üretmek için dekatlon veri kümesini {FactoMineR} kullanabilirsiniz. Soru, hesaplanan özdeğerlerin kovaryans matrisininkinden farklı olmasının nedenidir.

İşte kullanarak özdeğerler 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 

Ve aynı kullanarak 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

Bana doğrudan hesaplanan özdeğerlerin neden bunlardan farklı olduğunu açıklayabilir misiniz? (özvektörler aynıdır):

> 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

Ayrıca, alternatif prcompyöntem doğrudan hesaplama ile aynı özdeğerleri verir:

> 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

Neden PCA/ princompve prcompfarklı özdeğerler veriyoruz?


PCA, kovaryans matrisini mi yoksa korelasyon matrisini mi kullandığınıza bağlı olarak size farklı sonuçlar verecektir.
charles.y.zheng

7
Farklılıklar göreceli olarak küçük görünmektedir, ancak basit sayısal konular olamayacak kadar büyüktür. Normalleştirme arasındaki fark olabilir minÖrneğin, SVD veya özdeğerlerin ayrışmasının hesaplanmasından önce, kovaryansın bir tahmininin hesaplanmasında veya mi? n1
kardinal

7
@cardinal Güzel tahmin! İki farklı özdeğer dizisinin aynı ardışık oranlara sahip olduğuna dikkat edin . Böylece, bir set diğerinin sabit bir katıdır. Çoklu 1.025 = 41/40 ( tam olarak ). Bunun nereden geldiği bana açık değil. Belki veri seti 41 elemente sahiptir ve OP sadece ilk 10'u ortaya koyuyor?
whuber

7
@ cardinal Indeed: Yardım sayfası için princomp: "Varsayılan hesaplamanın kovaryans matrisi için N bölücü N kullandığını unutmayın." Yardım sayfası için prcomp: "Princomp'tan farklı olarak, normal bölen N-1 bölücü varyanslarla hesaplanır."
caracal

2
Ayrıca, yorumunuzu bir cevaba kopyalamanız (ve belki de CW yapmalısınız) böylece kabul edilebilir ve soru çözülmüş olarak işaretlenebilir.
kardinal

Yanıtlar:


16

princompNprcompcovN1N

Bu, her iki Detaylar bölümünde de belirtilmiştir help(princomp):

Varsayılan hesaplamanın kovaryans matrisi için 'N' bölenini kullandığını unutmayın.

ve Ayrıntılar bölümü help(prcomp):

Aksine princomp, varyanslar olağan bölen N - 1 ile hesaplanır.

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
}

covmatArgüman yerine argümanı belirterek bu çarpımdan kaçınabilirsiniz x.

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

PCA puanlarına ilişkin güncelleme:

cor = TRUEprincompprincompzN

Sonuç olarak princomp(scale(data))$scoresveprincomp(data, cor = TRUE)$scores faktörüne göre değişecektir(N1)/N


1
"Tahmini" ifadesini "önceden onaylanmış" olarak değiştirmeyi düşünebilirsiniz (yukarıdaki açıklama akışına bakın.). Şerefe.
kardinal

@cardinal Bu yorumları görmedim. Sadece oy kullananları gördüm. Teşekkürler. Ayrıca, cevap CW'yi yapmanın ardındaki mantığı açıklayabilir misiniz? Bunun için kurallar / kurallar nelerdir?
Joshua Ulrich

Kodun neden sadece cv <- cov.wt(z, method="ML")2 çağrı hattını gereksiz hale getirmediğini kimse tahmin edemez mi?
caracal

2
@Joshua: Cevap CW'yi yapma konusundaki önerim, cevabın bir yorumlar akışı yoluyla ortaya çıkması ve bir "topluluk" tartışması tarafından yaratılmış olmasından kaynaklanıyordu. Yorumlarda çözüldüğü için düşüncelerim, bu işbirliğini belirtmek için CW olarak işaretlenmiş bir cevap olarak yeniden düzenlemenin en mantıklı olduğu ve bu sorunun cevabın kabul edilmesine ve sorunun çözülmüş olarak işaretlenmesine olanak sağlamasıdır. (Aksi takdirde, belirli bir süre sonra yazılım tarafından otomatik olarak geri toplanır.)
kardinal

2
@ amoeba düzenleme yorumunuzda bunu belirtmek faydalı olurdu. ~ 450 karakterlik bir cevaba "gövdeye 860 karakter eklendi", düzenlemenin makul olup olmadığını kimsenin değerlendirmesine yardımcı olmaz.
Joshua Ulrich
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.