Esta pregunta trata sobre una manera eficiente de calcular los componentes principales.
Muchos textos sobre PCA lineal abogan por el uso de la descomposición de valores singulares de los datos de casos . Es decir, si tenemos datos y queremos reemplazar las variables (sus columnas ) por componentes principales, hacemos SVD: , valores singulares (raíces cuadradas de los valores propios) que ocupan la diagonal principal de , los vectores propios derechos son la matriz de rotación ortogonal de las variables de los ejes en componentes de los ejes, los vectores propios izquierdos son como , solo para los casos. Entonces podemos calcular los valores de los componentes como .
Otra forma de hacer PCA de variables es mediante la descomposición de matriz cuadrada (es decir, pueden ser correlaciones o covarianzas , etc., entre las variables). La descomposición puede ser descomposición propia o descomposición de valores singulares: con una matriz semidefinida positiva simétrica cuadrada, darán el mismo resultado con valores propios que la diagonal de y como se describió anteriormente. Los valores de los componentes serán .
Ahora, mi pregunta: si data es una matriz grande, y el número de casos es (que a menudo es un caso) mucho mayor que el número de variables, entonces se espera que way (1) sea mucho más lento que way (2 ), porque way (1) aplica un algoritmo bastante costoso (como SVD) a una matriz grande; calcula y almacena una matriz enorme que realmente no necesitamos en nuestro caso (el PCA de las variables). Si es así, ¿ por qué tantos libros de texto parecen abogar o solo mencionar la única forma (1)? ¿Quizás es eficiente y me falta algo?
fuente
R
svd
Joliffe, Principal component analysis, 2nd ed.
realidad, Joliffe describe ambas formas, pero en el capítulo central sobre PCA dice sobre la manera 1, por lo que puedo recordar.Respuestas:
Aquí están mis 2ct sobre el tema
La conferencia de quimiometría donde aprendí por primera vez que PCA usaba la solución (2), pero no estaba orientada numéricamente, y mi conferencia de numérica fue solo una introducción y no discutí SVD hasta donde recuerdo.
Si entiendo Holmes: SVD rápida para matrices de gran escala correctamente, su idea se ha utilizado para obtener una SVD computacionalmente rápida de matrices largas.
Eso significaría que una buena implementación de SVD puede seguir internamente (2) si encuentra matrices adecuadas (no sé si todavía hay mejores posibilidades). Esto significaría que para una implementación de alto nivel es mejor usar SVD (1) y dejar que BLAS se encargue de qué algoritmo usar internamente.
Comprobación práctica rápida: el svd de OpenBLAS no parece hacer esta distinción, en una matriz de 5e4 x 100,
svd (X, nu = 0)
toma una mediana de 3.5 s, mientras quesvd (crossprod (X), nu = 0)
toma 54 ms (llamado desde R conmicrobenchmark
).La cuadratura de los valores propios, por supuesto, es rápida, y hasta eso los resultados de ambas llamadas son equivalentes.
actualización: Echa un vistazo a Wu, W .; Massart, D. y de Jong, S .: Los algoritmos de kernel PCA para datos amplios. Parte I: Teoría y algoritmos, Chemometrics and Intelligent Laboratory Systems, 36, 165 - 172 (1997). DOI: http://dx.doi.org/10.1016/S0169-7439(97)00010-5
Este artículo discute las propiedades numéricas y computacionales de 4 algoritmos diferentes para PCA: SVD, descomposición propia (EVD), NIPALS y POWER.
Están relacionados de la siguiente manera:
El contexto del documento es amplio , y funcionan en X X ' (kernel PCA): esta es la situación opuesta a la que usted pregunta. Entonces, para responder a su pregunta sobre el comportamiento de la matriz larga, debe intercambiar el significado de "núcleo" y "clásico".X(30×500) XX′
No es sorprendente que EVD y SVD cambien de lugar dependiendo de si se usan los algoritmos clásico o del núcleo. En el contexto de esta pregunta, esto significa que uno u otro puede ser mejor dependiendo de la forma de la matriz.
Pero a partir de su discusión sobre SVD y EVD "clásica", está claro que la descomposición de es una forma muy habitual de calcular el PCA. Sin embargo, no especifican qué algoritmo SVD se usa más que el que usan la función de Matlab .X′X
svd ()
fuente
svd (X'X)
matrices largas).microbenchmark(X <- matrix(rnorm(5e6), ncol=100), Y <- t(X), svd(X), svd(Y), control=list(order="inorder"), times = 5)
puede ser interesante.SVD es más lento, pero a menudo se considera el método preferido debido a su mayor precisión numérica.
Esto es lo que está escrito en la ayuda de la
pca()
función de MATLAB :La última oración destaca la compensación crucial de velocidad y precisión que está en juego aquí.
obteniendo resultados idénticos:
Pero tomando ahoraϵ = 10- 10 Podemos observar cómo SVD todavía funciona bien pero EIG se descompone:
Lo que sucede aquí es que el mismo cálculo de la matriz de covarianza cuadra el número de condición deX , especialmente en caso de que X tiene algunas columnas casi colineales (es decir, algunos valores singulares muy pequeños), primero calcula la matriz de covarianza y luego calcula su descomposición propia dará como resultado una pérdida de precisión en comparación con la SVD directa.
Debo agregar que a menudo uno se alegra de ignorar esta potencial [pequeña] pérdida de precisión y más bien usar el método más rápido.
fuente
eig()
enfoque? (Los lectores se beneficiarán: hay un punto de compensación entre velocidad y estabilidad. ¿Cómo se puede decidir en una situación práctica concreta?)3 0 -3.3307e-16
eigen en spss me devolvió3 0 0
. Parece que la función tiene un valor de tolerancia incorporado y fijo más allá del cual se pone a cero. En este ejemplo, la función parecía cortar el nudo de la inestabilidad numérica al poner a cero ambos pequeños valores propios, el "0" y el "-16".