¿Los componentes de PCA realmente representan el porcentaje de varianza? ¿Pueden sumar más del 100%?

13

"Machine Learning For Hackers" de O'Reilly dice que cada componente principal representa un porcentaje de la variación. He citado la parte relevante de la página a continuación (capítulo 8, p. 207). Hablando con otro experto, acordaron que es el porcentaje.

Sin embargo, los 24 componentes suman 133.2095%. ¿Como puede ser?

Habiéndonos convencido de que podemos usar PCA, ¿cómo lo hacemos en R? Nuevamente, este es un lugar donde R brilla: la totalidad de PCA se puede hacer en una línea de código. Usamos la función princomp para ejecutar PCA:

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

Si solo escribimos pca en R, veremos un resumen rápido de los componentes principales:

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.

En este resumen, las desviaciones estándar nos dicen cuánto de la varianza en el conjunto de datos se explica por los diferentes componentes principales. El primer componente, llamado Comp.1, representa el 29% de la varianza, mientras que el siguiente componente representa el 20%. Al final, el último componente, Comp.24, representa menos del 1% de la varianza. Esto sugiere que podemos aprender mucho sobre nuestros datos con solo mirar el primer componente principal.

[El código y los datos se pueden encontrar en github .]

Darren Cook
fuente
66
Creo que la interpretación del autor de la Standard deviationses un poco fuera de lugar. Dado que las desviaciones estándar son de hecho desviaciones estándar, debemos ajustarlas al cuadrado para ver cuánta varianza representa cada componente. El primer componente representaría por ciento de la varianza total. 100×29.1001249229.10012492++0.43479832
asumido normal
44
Me temo que esta pregunta surge de dos errores básicos: (1) pierde el encabezado que anuncia que los números son "Desviaciones estándar" y los confunde con variaciones y (2) supone que esos números son porcentajes, pero no lo son. (Sus unidades son lo que sea que midan las existencias: dólares o cambio porcentual por año o lo que sea.) No hay ningún error aquí en absoluto: el comentario de @Max explica cómo encontrar el porcentaje de la varianza total.
whuber
1
@whuber ¿Quizás debería haber usado "error tipográfico" en lugar de "error"? :-) " Comp.1, representa el 29% de la variación " está mal y debería leer " Comp.1, representa el 46% de la variación "
Darren Cook
1
Gracias, Darren: no entendí que la confusión estaba presente en el libro y tomé "error" para referirme al Rsoftware en sí. Encontrar ese error fue una buena captura (¡espero que te haya resultado gratificante descubrir qué está pasando realmente con PCA)!
whuber
55
Sí, este es sin duda un error en el libro. Hay algunos lugares donde utilicé mal las desviaciones estándar en lugar de las variaciones. (Por ejemplo, hay un punto en el que usamos RMSE en lugar de MSE para calcular R-cuadrado.) Espero que tengamos tiempo para sentarnos y corregir este tipo de errores en el futuro cercano.
John Myles White

Respuestas:

11

Use summary.princomppara ver la "Proporción de varianza" y la "Proporción acumulativa".

pca <- princomp(date.stock.matrix[,2:ncol(date.stock.matrix)])
summary(pca)
Joshua Ulrich
fuente
1
Gracias Joshua Entonces, el primer componente es en realidad el 46% de la varianza. Enviaré un informe de error al libro.
Darren Cook
¿Cómo se calcula la "Proporción de varianza"? El número que se muestra es 0.4600083. Pero sqrt(pca$sdev[1]/sum(pca$sdev))(aproximadamente sqrt(29.1/133.2)) da 0.4673904.
Darren Cook
3
@DarrenCook: sdevimplica que estás viendo la desviación estándar , es decir, la raíz cuadrada de la varianza (o , usando la notación de mi respuesta), lo que debería explicar la diferencia. Intenta en sulugar. λipca$sdev[1]^2/sum(pca$sdev^2)
MånsT
2
@DarrenCook: use la fuente ... le stats:::print.summary.princompmuestra que cuadra el sdevcomponente, que stats:::princomp.defaultmuestra sqrtel valor propio.
Joshua Ulrich
11

Deberían sumar el 100 %.

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
fuente
1
¿Vio el comentario (más reciente) de @Max a la pregunta? Clavó la respuesta.
whuber
@whuber: No lo había visto, así que gracias. Hice un comentario similar en un comentario a la respuesta de Joshua.
MånsT
4

Aquí hay un código R para complementar las respuestas anteriores ( pca[["sdev"]]generalmente se escribe pca$sdev, pero causa un mal formato en el fragmento a continuación).

# 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)

Entonces, como señala @Max, trabajar con la varianza en lugar de la desviación estándar y no olvidar dividir por la varianza total resuelve el problema.

gui11aume
fuente