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

7
差は比較的小さいように見えますが、おそらく単純な数値の問題には大きすぎます。たとえば、SVDまたは固有値分解を計算する前に共分散の推定値を計算する場合、またはで正規化することの違いでしょうか?nn1
枢機

7
@cardinalいいね!固有値の2つの異なるシーケンスは、同じ連続した比率を持っていることに注意してください したがって、1つのセットは他のセットの定数倍です。倍数は1.025 = 41/40(正確に)です。これがどこから来たのかは私には不明です。データセットには41個の要素があり、OPは最初の10個のみを公開していますか?
whuber

7
Indeedのヘルプ・ページ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(N1)/N


1
「推測」を「確認済み」に置き換えることを検討することもできます(上記のコメントストリームを参照してください)。答えを編集してCWにすることも検討できます。乾杯。
枢機

@cardinalこれらのコメントは見ませんでした。投票されたものだけを見ました。ありがとう。また、答えをCWにする理由を説明してください。そのためのルール/ガイドラインは何ですか?
ジョシュアウルリッヒ

コードが単に次cv <- cov.wt(z, method="ML")の2行を不要にしているのではない理由を誰でも推測できますか?
カラカル

2
@Joshua:答えをCWにすることに関する私の提案は、答えがコメントのストリームを介して現れ、「コミュニティ」ディスカッションによって生成されたという事実によるものでした。コメントで解決されたので、私の考えは、このコラボレーションを示すためにCWとしてマークされた回答としてそれを再定式化することが最も理にかなっていると思います。これにより、回答が受け入れられ、質問が解決済みとしてマークされることができます。(それ以外の場合、一定の時間が経過すると、ソフトウェアによって自動的にバックアップされます。)
枢機

1
@amoeba編集コメントでそれを言及しておくと役に立ちました。450文字の回答に「本文に860文字を追加」しても、編集が妥当かどうかを評価するのに役立ちません。
ジョシュアウルリッヒ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.