Tại sao các hàm R 'Princeomp' và 'prcomp' đưa ra các giá trị riêng khác nhau?


22

Bạn có thể sử dụng bộ dữ liệu decathlon {FactoMineR} để sao chép này. Câu hỏi là tại sao các giá trị riêng được tính toán khác với các ma trận hiệp phương sai.

Dưới đây là các giá trị riêng sử dụng 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 

Và sử dụng tương tự 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

Bạn có thể giải thích cho tôi tại sao các giá trị riêng được tính trực tiếp khác với giá trị đó không? (các hàm riêng giống nhau):

> 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

Ngoài ra, prcompphương pháp thay thế cho các giá trị riêng giống như tính toán trực tiếp:

> 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

Tại sao làm PCA/ princompprcompđưa ra các giá trị riêng khác nhau?


PCA sẽ cung cấp cho bạn các kết quả khác nhau tùy thuộc vào việc bạn sử dụng ma trận hiệp phương sai hay ma trận tương quan.
charles.y.zheng

7
Sự khác biệt có vẻ tương đối nhỏ, mặc dù có lẽ quá lớn để trở thành các vấn đề số đơn giản. Nó có thể là sự khác biệt giữa chuẩn hóa bởi hoặc , ví dụ, khi tính toán ước tính hiệp phương sai trước khi tính toán phân tách SVD hoặc giá trị bản địa? n - 1nn1
Đức hồng y

7
@cardinal Đoán đẹp! Lưu ý rằng hai chuỗi khác nhau của giá trị riêng có tỷ lệ liên tiếp giống hệt nhau. Do đó, một bộ là bội số không đổi của bộ kia. Bội số là 1.025 = 41/40 ( chính xác ). Nó không rõ ràng với tôi nơi này đến từ đâu. Có lẽ bộ dữ liệu có 41 yếu tố và OP chỉ tiết lộ 10 yếu tố đầu tiên?
whuber

7
@cardinal Thật: Trang trợ giúp cho princomp: "Lưu ý rằng phép tính mặc định sử dụng ước số N cho ma trận hiệp phương sai." Trang trợ giúp cho prcomp: "Không giống như Princeomp, phương sai được tính toán với ước số thông thường N-1."
caracal

2
@caracal, bạn nên sao chép nhận xét của mình vào câu trả lời (và có thể đưa ra CW) để có thể chấp nhận và câu hỏi có thể được đánh dấu là đã được giải quyết.
hồng y

Câu trả lời:


16

Như đã chỉ ra trong các ý kiến, đó là vì princompsử dụngN - 1 NN cho số chia, nhưng prcompvà tính toán trực tiếp sử dụng covcả hai sử dụng thay vì .N1N

Điều này được đề cập trong cả phần Chi tiết của help(princomp):

Lưu ý rằng phép tính mặc định sử dụng ước số 'N' cho ma trận hiệp phương sai.

và phần Chi tiết của help(prcomp):

Không giống như princomp, phương sai được tính với ước số N - 1 thông thường.

Bạn cũng có thể thấy điều này trong nguồn. Ví dụ: đoạn mã princompnguồn bên dưới cho thấy ( ) được sử dụng làm mẫu số khi tính toán .Nn.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
}

Bạn có thể tránh phép nhân này bằng cách chỉ định covmatđối số thay vì xđối số.

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

Cập nhật về điểm số PCA:

Bạn có thể đặt cor = TRUEtrong lệnh gọi của mình princompđể thực hiện PCA trên ma trận tương quan (thay vì ma trận hiệp phương sai). Điều này sẽ gây ra princompđếnNz -score dữ liệu, nhưng nó vẫn sẽ sử dụng cho mẫu số.N

Kết quả là, princomp(scale(data))$scoresprincomp(data, cor = TRUE)$scoressẽ khác nhau bởi yếu tố .(N1)/N


1
Bạn có thể xem xét thay thế "đã đoán" bằng "đã được xác nhận" (xem luồng nhận xét ở trên.) Bạn cũng có thể xem xét chỉnh sửa câu trả lời của mình để thực hiện CW. Chúc mừng.
Đức hồng y

@cardinal Tôi không thấy những bình luận đó. Tôi chỉ thấy những người đã được bình chọn. Cảm ơn. Ngoài ra, bạn có thể giải thích lý do đằng sau việc đưa ra câu trả lời CW không? Các quy tắc / hướng dẫn cho điều đó là gì?
Joshua Ulrich

Có ai có thể đoán tại sao mã không chỉ đơn giản là cv <- cov.wt(z, method="ML")làm cho 2 dòng follwing không cần thiết không?
caracal

2
@Joshua: Đề xuất của tôi về việc đưa ra câu trả lời CW là do thực tế là câu trả lời xuất hiện thông qua một luồng ý kiến ​​và được tạo ra bởi một cuộc thảo luận "cộng đồng". Vì nó đã được giải quyết trong các bình luận, nên tôi nghĩ rằng sẽ hợp lý nhất khi cải tổ nó thành một câu trả lời, được đánh dấu là CW để chỉ ra sự hợp tác này và điều này cho phép câu trả lời được chấp nhận và câu hỏi được đánh dấu là đã được giải quyết. (Nếu không, phần mềm sẽ tự động bị sao lưu bởi phần mềm sau một khoảng thời gian nhất định.)
hồng y

1
@amoeba sẽ rất hữu ích khi đề cập đến điều đó trong bình luận chỉnh sửa của bạn. "Đã thêm 860 ký tự vào thân" vào câu trả lời ~ 450 ký tự không giúp ai đánh giá liệu chỉnh sửa có hợp lý hay không.
Joshua Ulrich
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.