Problem Setup
I have data points (images) of high dimension (4096), which I'm trying to visualize in 2D. To this end, I'm using t-sne in a manner similar to the following example code by Karpathy.
The scikit-learn documentation recommends using PCA to first lower the dimension of the data:
It is highly recommended to use another dimensionality reduction method (e.g. PCA for dense data or TruncatedSVD for sparse data) to reduce the number of dimensions to a reasonable amount (e.g. 50) if the number of features is very high.
I'm using this code by Darks.Liu to perform PCA in 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);
It uses jblas for the linear algebra operations, which from what I've read is supposed to be the fastest option out there. However, calculating the eigenvectors and eigenvalues (lines 3,4) turns out to be a huge bottleneck (~10 minutes, which is much longer than I can afford for this stage).
I've read about Kernel PCA which is supposed to be good for cases in which the dimension is very large, but its runtime is $O(n^3)$ which could be problematic since I also want to deal with cases of both dimension and number of examples being large.
As I see it, my options are either to "optimize" PCA or to opt for another dimensionality reduction method which is inherently faster.
My Questions
- Is there any hope that PCA can be used in an "offline" fashion? i.e, using a large data set of images, perform PCA on them, and then use the principal components computed for them to reduce the dimension of other (new!) data points?
- Can I speed up the eigenvectors calculation, assuming I know ahead of time that I'm only interested in, say, the top 100 principal components?
- Is there an alternative dimensionality reduction method that is appropriate in my case (i.e, before applying t-sne) which will be faster than PCA? I'm looking for something which can be implemented easily in Java.