Eu gostaria de usar a análise de componente principal (PCA) para redução de dimensionalidade. Numpy ou scipy já o tem, ou tenho que rolar o meu próprio usandonumpy.linalg.eigh
?
Não quero apenas usar a decomposição de valor singular (SVD) porque meus dados de entrada são bem dimensionais (~ 460 dimensões), então acho que SVD será mais lento do que calcular os autovetores da matriz de covariância.
Eu esperava encontrar uma implementação pré-fabricada e depurada que já toma as decisões corretas sobre quando usar qual método e que talvez faça outras otimizações que eu não conheço.
Note that from this release MDP is in maintenance mode. 13 years after its first public release, MDP has reached full maturity and no new features are planned in the future.
Meses depois, aqui está um pequeno PCA de classe e uma foto:
fonte
Usar o PCA
numpy.linalg.svd
é super fácil. Aqui está uma demonstração simples:fonte
svd
já retornas
ordenado em ordem decrescente, de acordo com a documentação. (Talvez não fosse o caso em 2012, mas hoje é)Você pode usar o sklearn:
fonte
matplotlib.mlab possui uma implementação PCA .
fonte
SVD deve funcionar bem com 460 dimensões. Demora cerca de 7 segundos no meu netbook Atom. O método eig () leva mais tempo (como deveria, ele usa mais operações de ponto flutuante) e quase sempre será menos preciso.
Se você tem menos de 460 exemplos, então o que você quer fazer é diagonalizar a matriz de dispersão (x - datamean) ^ T (x - média), assumindo que seus pontos de dados são colunas, e então multiplicando à esquerda por (x - datamean). Isso pode ser mais rápido no caso em que você tem mais dimensões do que dados.
fonte
Você pode facilmente "rolar" seu próprio usando
scipy.linalg
(assumindo um conjunto de dados pré-centradodata
):Então,
evs
são seus autovalores eevmat
sua matriz de projeção.Se você quiser manter as
d
dimensões, use os primeirosd
autovalores e os primeirosd
autovetores.Dado que
scipy.linalg
tem decomposição e numpy as multiplicações da matriz, o que mais você precisa?fonte
eig()
em uma matriz de covariância.Acabei de terminar de ler o livro Machine Learning: An Algorithmic Perspective . Todos os exemplos de código do livro foram escritos por Python (e quase com Numpy). O trecho de código da análise de componentes principais do chatper10.2 talvez valha a pena uma leitura. Ele usa numpy.linalg.eig.
A propósito, acho que o SVD pode lidar com 460 * 460 dimensões muito bem. Calculei um 6500 * 6500 SVD com numpy / scipy.linalg.svd em um PC muito antigo: Pentium III 733mHz. Para ser honesto, o script precisa de muita memória (cerca de 1.xG) e muito tempo (cerca de 30 minutos) para obter o resultado SVD. Mas acho que 460 * 460 em um PC moderno não será um grande problema, a menos que você precise fazer SVD um grande número de vezes.
fonte
Você não precisa da Decomposição de Valor Singular (SVD) completa, pois ela calcula todos os valores próprios e vetores próprios e pode ser proibitiva para matrizes grandes. scipy e seu módulo esparso fornecem funções de algrebra linear genérica trabalhando em matrizes esparsas e densas, entre as quais existe a família de funções eig *:
http://docs.scipy.org/doc/scipy/reference/sparse.linalg.html#matrix-factorizations
O Scikit-learn fornece uma implementação Python PCA que suporta apenas matrizes densas por enquanto.
Horários:
fonte
eigsh
é na verdade ~ 4x mais lento do queeigh
matrizes não esparsas. O mesmo é válido parascipy.sparse.linalg.svds
versusnumpy.linalg.svd
. Eu sempre usaria SVD sobre a decomposição de autovalor pelos motivos mencionados por @dwf e talvez usasse uma versão esparsa de SVD se as matrizes ficarem realmente grandes.eigsh
esvds
são mais rápidos do queeigh
esvd
por um fator de ~ 3, mas se A for menor, digamos 100 * 100, entãoeigh
esvd
são mais rápidos por fatores de ~ 4 e ~ 1,5 respectivamente . T ainda usaria SVD esparsa sobre decomposição de autovalor esparsa embora.Aqui está outra implementação de um módulo PCA para python usando extensões numpy, scipy e C. O módulo executa PCA usando um SVD ou o algoritmo NIPALS (Nonlinear Iterative Partial Least Squares) que é implementado em C.
fonte
Se estiver trabalhando com vetores 3D, você pode aplicar SVD de forma concisa usando o toolbelt vg . É uma camada leve em cima do entorpecido.
Também há um alias conveniente se você quiser apenas o primeiro componente principal:
Eu criei a biblioteca na minha última inicialização, onde ela foi motivada por usos como este: ideias simples que são prolixas ou opacas no NumPy.
fonte