Configuração do problema
Eu tenho pontos de dados (imagens) de alta dimensão (4096), que estou tentando visualizar em 2D. Para esse fim, estou usando t-sne de maneira semelhante ao código de exemplo a seguir de Karpathy .
A documentação do scikit-learn recomenda o uso do PCA para diminuir primeiro a dimensão dos dados:
É altamente recomendável usar outro método de redução de dimensionalidade (por exemplo, PCA para dados densos ou TruncatedSVD para dados esparsos) para reduzir o número de dimensões para uma quantidade razoável (por exemplo, 50) se o número de recursos for muito alto.
Estou usando esse código do Darks.Liu para executar o PCA em Java:
//C=X*X^t / m
DoubleMatrix covMatrix = source.mmul(source.transpose()).div(source.columns);
ComplexDoubleMatrix eigVal = Eigen.eigenvalues(covMatrix);
ComplexDoubleMatrix[] eigVectorsVal = Eigen.eigenvectors(covMatrix);
ComplexDoubleMatrix eigVectors = eigVectorsVal[0];
//Sort sigen vector from big to small by eigen values
List<PCABean> beans = new ArrayList<PCA.PCABean>();
for (int i = 0; i < eigVectors.columns; i++) {
beans.add(new PCABean(eigVal.get(i).real(), eigVectors.getColumn(i)));
}
Collections.sort(beans);
DoubleMatrix newVec = new DoubleMatrix(dimension, beans.get(0).vector.rows);
for (int i = 0; i < dimension; i++) {
ComplexDoubleMatrix dm = beans.get(i).vector;
DoubleMatrix real = dm.getReal();
newVec.putRow(i, real);
}
return newVec.mmul(source);
Ele usa jblas para as operações de álgebra linear, que pelo que li é a opção mais rápida disponível. No entanto, calcular os autovetores e os autovalores (linhas 3,4) acaba sendo um grande gargalo (~ 10 minutos, o que é muito mais longo do que posso pagar para esta etapa).
Eu li sobre o Kernel PCA, que deveria ser bom para casos em que a dimensão é muito grande, mas seu tempo de execução é que pode ser problemático, pois também quero lidar com casos de dimensão e número. de exemplos sendo grandes.
Na minha opinião, minhas opções são "otimizar" o PCA ou optar por outro método de redução de dimensionalidade que é inerentemente mais rápido.
Minhas perguntas
- Existe alguma esperança de que o PCA possa ser usado de maneira "offline"? ou seja, usando um grande conjunto de dados de imagens, execute o PCA nelas e use os principais componentes calculados para reduzir a dimensão de outros (novos!) pontos de dados?
- Posso acelerar o cálculo dos vetores próprios, assumindo que sei antecipadamente que só estou interessado, digamos, nos 100 principais componentes principais?
- Existe um método alternativo de redução de dimensionalidade que seja apropriado no meu caso (ou seja, antes de aplicar t-sne) que seja mais rápido que o PCA? Estou procurando algo que possa ser implementado facilmente em Java.