Configuration du problème
J'ai des points de données (images) de grande dimension (4096), que j'essaie de visualiser en 2D. À cette fin, j'utilise t-sne d'une manière similaire à l' exemple de code suivant de Karpathy .
La documentation de scikit-learn recommande d'utiliser PCA pour réduire d'abord la dimension des données:
Il est fortement recommandé d'utiliser une autre méthode de réduction de dimensionnalité (par exemple PCA pour les données denses ou TruncatedSVD pour les données clairsemées) pour réduire le nombre de dimensions à une quantité raisonnable (par exemple 50) si le nombre de caractéristiques est très élevé.
J'utilise ce code de Darks.Liu pour effectuer PCA en 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);
Il utilise des jblas pour les opérations d'algèbre linéaire, qui d'après ce que j'ai lu est censé être l'option la plus rapide. Cependant, le calcul des vecteurs propres et des valeurs propres (lignes 3,4) s'avère être un énorme goulot d'étranglement (~ 10 minutes, ce qui est beaucoup plus long que ce que je peux me permettre pour cette étape).
J'ai lu sur Kernel PCA qui est censé être bon pour les cas dans lesquels la dimension est très grande, mais son exécution est ce qui pourrait être problématique car je veux également traiter les cas à la fois de dimension et de nombre d'exemples étant grand.
Selon moi, mes options sont soit «d'optimiser» l'ACP, soit d'opter pour une autre méthode de réduction de dimensionnalité qui est intrinsèquement plus rapide.
Mes questions
- Y a-t-il un espoir que l'ACP puisse être utilisée de manière "hors ligne"? c'est-à-dire, en utilisant un grand ensemble de données d'images, effectuer une ACP sur celles-ci, puis utiliser les principaux composants calculés pour eux afin de réduire la dimension d' autres (nouveaux!) points de données?
- Puis-je accélérer le calcul des vecteurs propres, en supposant que je sache à l'avance que je ne suis intéressé que, disons, par les 100 principaux composants principaux?
- Existe-t-il une autre méthode de réduction de la dimensionnalité appropriée dans mon cas (c'est-à-dire avant d'appliquer le t-sne) qui sera plus rapide que l'ACP? Je cherche quelque chose qui peut être implémenté facilement en Java.
la source
Si votre objectif est simplement d'effectuer une réduction de dimension d'une manière simple et directe, vous pouvez essayer une technique des moindres carrés alternés (ALS). Par exemple, Apache Sparkn×K K×p K×p
mlib
a une implémentation ALS et je crois qu'il propose une API Java. Cela devrait vous donner une matrice et une matrice . La matrice contiendra des vecteurs de ligne visualisables.la source