Configuración del problema
Tengo puntos de datos (imágenes) de alta dimensión (4096), que estoy tratando de visualizar en 2D. Para este fin, estoy usando t-sne de manera similar al siguiente código de ejemplo de Karpathy .
La documentación de scikit-learn recomienda usar PCA para reducir primero la dimensión de los datos:
Se recomienda encarecidamente utilizar otro método de reducción de dimensionalidad (por ejemplo, PCA para datos densos o TruncatedSVD para datos dispersos) para reducir el número de dimensiones a una cantidad razonable (por ejemplo, 50) si el número de características es muy alto.
Estoy usando este código de Darks.Liu para realizar 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);
Utiliza jblas para las operaciones de álgebra lineal, que por lo que he leído se supone que es la opción más rápida que existe. Sin embargo, calcular los vectores propios y los valores propios (líneas 3, 4) resulta ser un gran cuello de botella (~ 10 minutos, que es mucho más largo de lo que puedo permitirme para esta etapa).
He leído sobre Kernel PCA, que se supone que es bueno para casos en los que la dimensión es muy grande, pero su tiempo de ejecución es que podría ser problemático ya que también quiero tratar casos de dimensión y número de ejemplos siendo grandes.
Tal como lo veo, mis opciones son "optimizar" PCA u optar por otro método de reducción de dimensionalidad que sea inherentemente más rápido.
Mis preguntas
- ¿Hay alguna esperanza de que PCA se pueda usar de manera "fuera de línea"? es decir, utilizando un gran conjunto de datos de imágenes, realice PCA en ellas y luego utilice los componentes principales calculados para reducir la dimensión de otros puntos de datos (¡nuevos!)
- ¿Puedo acelerar el cálculo de los vectores propios, suponiendo que sepa de antemano que solo estoy interesado en, por ejemplo, los 100 componentes principales principales?
- ¿Existe un método alternativo de reducción de dimensionalidad que sea apropiado en mi caso (es decir, antes de aplicar t-sne) que será más rápido que PCA? Estoy buscando algo que se pueda implementar fácilmente en Java.