Entendo a relação entre Análise de Componentes Principais e Decomposição de Valor Singular em um nível algébrico / exato. Minha pergunta é sobre a implementação do scikit-learn .
A documentação diz: " [TruncatedSVD] é muito semelhante ao PCA, mas opera diretamente em vetores de amostra, em vez de em uma matriz de covariância. ", O que refletiria a diferença algébrica entre as duas abordagens. No entanto, mais tarde, ele diz: " Este estimador [TruncatedSVD] suporta dois algoritmos: um solucionador SVD aleatório rápido e um algoritmo" ingênuo "que usa o ARPACK como um resolvedor automático em (X * XT) ou (XT * X), o que for mais eficiente. " Em relação ao PCA, diz: "Redução linear da dimensionalidade usando a decomposição de valor singular dos dados para projetá-lo ...". E a implementação do PCA suporta os mesmos dois solucionadores de algoritmos (randomizados e ARPACK), além de outro, o LAPACK. Examinando o código, vejo que o ARPACK e o LAPACK no PCA e no TruncatedSVD fazem svd nos dados de amostra X, sendo o ARPACK capaz de lidar com matrizes esparsas (usando svds).
Portanto, além dos diferentes atributos e métodos, e que o PCA também pode decompor exatamente o valor singular usando as implementações de aprendizado de truque LAPACK, PCA e TruncatedSVD, parece ser exatamente o mesmo algoritmo. Primeira pergunta: isso está correto?
Segunda pergunta: mesmo que o LAPACK e o ARPACK usem scipy.linalg.svd (X) e scipy.linalg.svds (X), sendo X a matriz da amostra, eles calculam a decomposição de valor singular ou decomposição de ou internamente. Enquanto o solucionador "randomizado" não precisa calcular o produto. (Isso é relevante em relação à estabilidade numérica, consulte Por que o PCA de dados por meio do SVD dos dados? ). Isso está correto?
Código relevante: linha 415 do PCA . Linha 137 truncada do SVD .
fonte
Xtimes()
Xt_times()
Respostas:
Não: o PCA é SVD (truncado) em dados centralizados (por subtração média por recurso). Se os dados já estiverem centralizados, essas duas classes farão o mesmo.
Na prática,
TruncatedSVD
é útil em grandes conjuntos de dados esparsos que não podem ser centralizados sem fazer explodir o uso da memória.numpy.linalg.svd
escipy.linalg.svd
ambos contam com o LAPACK _GESDD descrito aqui: http://www.netlib.org/lapack/lug/node32.html (dividir e conquistar driver)scipy.sparse.linalg.svds
depende do ARPACK para fazer uma decomposição de valor próprio de XT. X ou X. XT (dependendo da forma dos dados) através do método de iteração Arnoldi. O guia do usuário HTML do ARPACK possui uma formatação quebrada que oculta os detalhes computacionais, mas a iteração Arnoldi está bem descrita na wikipedia: https://en.wikipedia.org/wiki/Arnoldi_iterationAqui está o código para o SVD baseado em ARPACK no scipy:
https://github.com/scipy/scipy/blob/master/scipy/sparse/linalg/eigen/arpack/arpack.py#L1642 (procure a string "def svds" no caso de alteração de linha no código fonte )
fonte