Esta pergunta é sobre uma maneira eficiente de calcular os componentes principais.
Muitos textos sobre PCA linear advogam o uso da decomposição de valor singular dos dados casewise . Ou seja, se temos dados e queremos substituir as variáveis (suas colunas ) por componentes principais, fazemos SVD: , valores singulares (raízes quadradas dos valores próprios) que ocupam a diagonal principal de , os autovetores direitos são a matriz de rotação ortogonal dos eixos-variáveis em eixos-componentes; os autovetores esquerdos são como , apenas para os casos. Podemos então calcular os valores dos componentes como .
Outra maneira de realizar o PCA de variáveis é via decomposição da matriz quadrada (isto é, R pode ser correlações ou covariâncias etc., entre as variáveis). A decomposição pode ser uma decomposição autônoma ou decomposição de valor singular: com matriz semidefinida positiva simétrica quadrada, eles obterão o mesmo resultado R = V L V ′ com valores próprios na diagonal de L e V, conforme descrito anteriormente. Os valores dos componentes serão C = X V .
Agora, minha pergunta: se os dados são uma matriz grande e o número de casos é (geralmente um caso) muito maior que o número de variáveis, então o caminho (1) deve ser muito mais lento que o caminho (2), porque a maneira (1) aplica um algoritmo bastante caro (como SVD) a uma grande matriz; ele calcula e armazena uma enorme matriz U que realmente não precisamos no nosso caso (o PCA de variáveis). Se sim, então por que tantos livros didáticos parecem advogar ou apenas mencionar a única maneira (1)? Talvez seja eficiente e estou perdendo alguma coisa?
fonte
R
svd
Joliffe, Principal component analysis, 2nd ed.
verdade, Joliffe descreve os dois lados, mas no capítulo principal do PCA ele diz apenas o modo 1, tanto quanto me lembro.Respostas:
Aqui estão os meus 2ct no tópico
A aula de quimiometria onde eu aprendi o PCA usou a solução (2), mas não era orientada numericamente, e minha aula numérica era apenas uma introdução e não discutia SVD até onde me lembro.
Se eu entendo Holmes: SVD rápido para matrizes de grande escala corretamente, sua ideia foi usada para obter um SVD computacionalmente rápido de matrizes longas.
Isso significaria que uma boa implementação de SVD pode seguir internamente (2) se encontrar matrizes adequadas (não sei se ainda existem melhores possibilidades). Isso significaria que, para uma implementação de alto nível, é melhor usar o SVD (1) e deixar para o BLAS cuidar de qual algoritmo usar internamente.
Verificação prática rápida: o DVD do OpenBLAS parece não fazer essa distinção, em uma matriz de 5e4 x 100,
svd (X, nu = 0)
assume mediana de 3,5 s, enquantosvd (crossprod (X), nu = 0)
leva 54 ms (chamado de R commicrobenchmark
).A quadratura dos valores próprios, é claro, é rápida e, até o momento, os resultados das duas chamadas são equivalentes.
atualização: Dê uma olhada em Wu, W .; Massart, D. & de Jong, S .: Os algoritmos PCA do kernel para dados amplos. Parte I: Teoria e algoritmos, Chemometrics and Intelligent Laboratory Systems, 36, 165 - 172 (1997). DOI: http://dx.doi.org/10.1016/S0169-7439(97)00010-5
Este artigo discute propriedades numéricas e computacionais de 4 algoritmos diferentes para PCA: SVD, decomposição de eigen (EVD), NIPALS e POWER.
Eles estão relacionados da seguinte maneira:
O contexto do trabalho é amplo e funciona em X X ′ (kernel PCA) - essa é exatamente a situação oposta à que você pergunta. Portanto, para responder sua pergunta sobre o comportamento da matriz longa, você precisa trocar o significado de "kernel" e "clássico".X(30×500) XX′
Não é de surpreender que EVD e SVD mudem de lugar, dependendo se os algoritmos clássicos ou de kernel são usados. No contexto desta pergunta, isso significa que um ou outro pode ser melhor dependendo da forma da matriz.
Porém, a partir da discussão sobre SVD e EVD "clássicos", fica claro que a decomposição de é uma maneira muito usual de calcular o PCA. No entanto, eles não especificam qual algoritmo SVD é usado, exceto o uso da função Matlab .X′X
svd ()
fonte
svd (X'X)
para matrizes de comprimento.)microbenchmark(X <- matrix(rnorm(5e6), ncol=100), Y <- t(X), svd(X), svd(Y), control=list(order="inorder"), times = 5)
pode ser interessante.O SVD é mais lento, mas geralmente é considerado o método preferido devido à sua maior precisão numérica.
Aqui está o que está escrito na
pca()
função de ajuda do MATLAB :A última frase destaca o compromisso crucial de precisão e velocidade que está em jogo aqui.
Considere uma matriz de dados
obtenção de resultados idênticos:
Mas agoraϵ = 10- 10 podemos observar como o SVD ainda funciona bem, mas o EIG se decompõe:
O que acontece aqui é que o próprio cálculo da matriz de covariância quadratura o número da condição deX , especialmente no caso em que X possui algumas colunas quase colineares (ou seja, alguns valores singulares muito pequenos), primeiro calculando a matriz de covariância e depois calculando sua composição automática resultará em perda de precisão em comparação com o SVD direto.
I should add that one is often happy to ignore this potential [tiny] loss of precision and rather use the faster method.
fonte
eig()
approach? (Readers will benefit: there is a point of trade-off between speed and stability. How one may decide in a concrete practical situation?)3 0 -3.3307e-16
eigen in spss returned me3 0 0
. It looks as if the function has some in-built and fixed tolerance value beyond which it zero-offs. In this example, the function appeared as if to hack the knot of numerical instability by zeroing both tiny eigenvalues, the "0" and the "-16".