Czy składniki PCA naprawdę reprezentują procent wariancji? Czy suma może przekroczyć 100%?

13

O'Reilly's „Machine Learning For Hackers” mówi, że każdy główny składnik reprezentuje procent wariancji. Cytowałem odpowiednią część poniższej strony (rozdział 8, s.207). W rozmowie z innym ekspertem zgodzili się, że jest to procent.

Jednak 24 składniki sumują się do 133,2095%. Jak to możliwe?

Przekonawszy się, że możemy korzystać z PCA, jak to zrobić w R? Znowu jest to miejsce, w którym świeci R: całość PCA może być wykonana w jednym wierszu kodu. Używamy funkcji princomp do uruchamiania PCA:

pca <- princomp(date.stock.matrix[,2:ncol(date.stock.matrix)])

Jeśli po prostu wpiszemy pca w R, zobaczymy krótkie podsumowanie głównych składników:

Call:
princomp(x = date.stock.matrix[, 2:ncol(date.stock.matrix)])
Standard deviations:
Comp.1 Comp.2 Comp.3 Comp.4 Comp.5 Comp.6 Comp.7
29.1001249 20.4403404 12.6726924 11.4636450 8.4963820 8.1969345 5.5438308
Comp.8 Comp.9 Comp.10 Comp.11 Comp.12 Comp.13 Comp.14
5.1300931 4.7786752 4.2575099 3.3050931 2.6197715 2.4986181 2.1746125
Comp.15 Comp.16 Comp.17 Comp.18 Comp.19 Comp.20 Comp.21
1.9469475 1.8706240 1.6984043 1.6344116 1.2327471 1.1280913 0.9877634
Comp.22 Comp.23 Comp.24
0.8583681 0.7390626 0.4347983
24 variables and 2366 observations.

W tym podsumowaniu odchylenia standardowe mówią nam, ile wariancji w zbiorze danych stanowią różne główne składniki. Pierwszy składnik, zwany Comp.1, stanowi 29% wariancji, podczas gdy następny składnik stanowi 20%. Do końca ostatni składnik, Comp.24, stanowi mniej niż 1% wariancji. Sugeruje to, że możemy się wiele dowiedzieć o naszych danych, patrząc tylko na pierwszy główny składnik.

[Kod i dane można znaleźć na github .]

Darren Cook
źródło
6
Myślę, że interpretacja autora Standard deviationsjest nieco niepoprawna. Ponieważ odchylenia standardowe są w rzeczywistości odchyleniami standardowymi, musimy je wyrównać, aby zobaczyć, ile wariancji reprezentuje każdy składnik. Pierwszy składnik reprezentowałby procent całkowitej wariancji. 100×29.1001249229.10012492++0.43479832
zakładano, że jest nietypowy
4
Obawiam się, że to pytanie wynika z dwóch podstawowych błędów: (1) pomija nagłówek, ogłaszając, że liczby są „odchyleniami standardowymi”, i błędnie je interpretuje, oraz (2) zakłada, że ​​liczby te są procentami, ale nie są. (Ich jednostki to, bez względu na to, w jakich akcje są mierzone: zmiana w dolarach lub procentach rocznie lub cokolwiek innego.) Tu nie ma żadnego błędu: komentarz @Max wyjaśnia, jak znaleźć procent całkowitej wariancji.
whuber
1
@whuber Być może powinienem był użyć „literówki” zamiast „błędu”? :-) „ Komp. 1, stanowi 29% wariancji ” jest niepoprawna i powinien brzmieć „ Komp. 1, stanowi 46% wariancji
Darren Cook
1
Dziękuję, Darren: źle zrozumiałem, że zamieszanie było obecne w książce i wziąłem „błąd”, aby odnieść się do samego Roprogramowania. Znalezienie tego błędu było dobrym chwytem (mam nadzieję, że odkrywanie, co naprawdę dzieje się w PCA, było satysfakcjonujące)!
whuber
5
Tak, to niewątpliwie błąd w książce. Jest kilka miejsc, w których niewłaściwie użyłem standardowych odchyleń zamiast odchyleń. (Na przykład istnieje punkt, w którym używamy RMSE zamiast MSE do obliczenia R-kwadrat.) Mam nadzieję, że mamy czas, aby usiąść i poprawić tego rodzaju błędy w najbliższej przyszłości.
John Myles White

Odpowiedzi:

11

Użyj, summary.princompaby zobaczyć „Proporcję wariancji” i „Skumulowaną proporcję”.

pca <- princomp(date.stock.matrix[,2:ncol(date.stock.matrix)])
summary(pca)
Joshua Ulrich
źródło
1
Dzięki Joshua. Tak więc pierwszy składnik to w rzeczywistości 46% wariancji. Wyślę raport o błędzie do książki.
Darren Cook
Jak oblicza się „Proporcję wariancji”? Pokazana liczba to 0,4600083. Ale sqrt(pca$sdev[1]/sum(pca$sdev))(z grubsza sqrt(29.1/133.2)) daje 0,4673904.
Darren Cook
3
@DarrenCook: sdevoznacza, że ​​patrzysz na odchylenie standardowe , tj. Pierwiastek kwadratowy wariancji (lub , używając zapisu z mojej odpowiedzi), co powinno wyjaśnić różnicę. Spróbuj zamiast tego. λipca$sdev[1]^2/sum(pca$sdev^2)
MånsT
2
@DarrenCook: użyj źródła ... stats:::print.summary.princomppokazuje, że kwadrat komponuje do kwadratu sdev, co stats:::princomp.defaultpokazuje , że jest to sqrtwartość własna.
Joshua Ulrich
11

Powinny one sumować się do100 %.

Całkowitą wariancję zmiennej losowej zmiennej z macierzą kowariancji określa się jakoX ΣpXΣ

tr(Σ)=σ11+σ22++σpp.

λ1λ2λp.

tr(Σ)=λ1++λp
λiΣλp0

eiXeii1λi

Var(eiX)=eiΣei=λieiei=λi
k
(λ1++λkλ1++λp100) %
100 %k=p
MånsT
źródło
1
Czy widziałeś (najnowszy) komentarz @Max do pytania? Przybił odpowiedź.
whuber
@whuber: Nie widziałem tego, więc dziękuję. Podobną uwagę wypowiedziałem w komentarzu do odpowiedzi Jozuego.
MånsT
4

Oto część kodu R, który uzupełnia poprzednie odpowiedzi ( pca[["sdev"]]jest zwykle zapisywany pca$sdev, ale powoduje nieprawidłowe formatowanie we fragmencie poniżej).

# Generate a dummy dataset.
set.seed(123)
x <- matrix(rnorm(400, sd=3), ncol=4)
# Note that princomp performs an unscaled PCA.
pca1 <- princomp(x)
# Show the fraction variance of each PC.
pca1[["sdev"]]^2
cumsum(pca1[["sdev"]]^2)/sum(pca1[["sdev"]]^2)
# Perform a scaled PCA.
pca2 <- princomp(x, cor=TRUE)
pca2[["sdev"]]^2
cumsum(pca2[["sdev"]]^2)/sum(pca2[["sdev"]]^2)

Jak wskazuje @Max, praca z wariancją zamiast odchylenia standardowego i nie zapominanie o podzieleniu przez całkowitą wariancję rozwiązuje problem.

gui11aume
źródło