R 함수 'princomp'와 'prcomp'가 다른 고유 값을 제공하는 이유는 무엇입니까?


22

decathlon 데이터 셋 {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
차이는 비교적 작지만 단순한 수치 문제로는 너무 클 수 있습니다. 이 정규화에 의해 차이가있을 수 또는 N - 1 , 예를 들면, 이전 SVD 또는 고유 분해를 계산의 공분산의 추정을 계산할 때? 1
추기경

7
@ 추기경 좋은 추측! 서로 다른 두 고유 값 시퀀스는 동일한 연속 비율을 갖습니다 . 따라서 한 세트는 다른 세트의 상수 배수입니다. 배수는 1.025 = 41/40 ( 정확히 )입니다. 어디에서 왔는지 불분명합니다. 데이터 세트에 41 개의 요소가 있고 OP가 처음 10 개만 공개하고 있습니까?
whuber

7
@cardinal Indeed : 도움말 페이지 princomp: "기본 계산에서는 공분산 행렬에 제수 N을 사용합니다." 도움말 페이지에 대해 prcomp"달리 princomp, 차이는 일반적인 제수 N-1로 계산됩니다."
caracal

2
@ caracal, 당신은 당신의 의견을 답변에 복사하고 (아마도 CW로 만들어야) 받아 들일 수 있고 질문이 해결 된 것으로 표시 될 수 있습니다.
추기경

답변:


16

princompprcompcov1

이것은 다음의 세부 사항 섹션 모두에서 언급됩니다 help(princomp).

기본 계산에서는 공분산 행렬에 제수 'N'이 사용됩니다.

세부 사항 섹션 help(prcomp):

와 달리 princomp분산은 일반적인 제수 N-1로 계산됩니다.

princompn.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에 대한 답변의 근거를 설명 할 수 있습니까? 이에 대한 규칙 / 지침은 무엇입니까?
Joshua Ulrich

아무도 왜 코드가 단순히 cv <- cov.wt(z, method="ML")2 개의 다음 줄을 불필요 하게 만들지 않는지 추측 할 수 있습니까 ?
caracal

2
@Joshua : CW 답변에 대한 나의 제안은 답변이 일련의 의견을 통해 나타나고 "커뮤니티"토론에 의해 생성되었다는 사실 때문입니다. 의견에서 해결되었으므로 내 의견은이 협업을 나타 내기 위해 CW로 표시 된 답변으로 재구성하는 것이 가장 합리적이며 답변을 수락하고 질문을 해결 된 것으로 표시 할 수 있습니다. (그렇지 않으면 일정 시간이 지나면 소프트웨어에 의해 자동으로 백업됩니다.)
Cardinal

1
@amoeba 편집 의견에 언급하는 것이 도움이 될 것입니다. ~ 450 자 답변에 "보디에 860 자 추가됨"은 편집이 합리적인지 평가하는 데 도움이되지 않습니다.
Joshua Ulrich
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.