问题设置
我有高维(4096)的数据点(图像),我试图在 2D 中可视化。为此,我以类似于 Karpathy 的以下示例代码的方式使用 t-sne。
scikit-learn 文档建议先使用 PCA 来降低数据的维度:
如果特征数量非常多,强烈建议使用另一种降维方法(例如,用于密集数据的 PCA 或用于稀疏数据的 TruncatedSVD)以将维数减少到合理的数量(例如 50)。
我正在使用 Darks.Liu 的这段代码在 Java 中执行 PCA:
//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);
它使用jblas进行线性代数运算,据我所知,这应该是最快的选择。然而,计算特征向量和特征值(第 3,4 行)被证明是一个巨大的瓶颈(大约 10 分钟,这比我在这个阶段所能承受的要长得多)。
我读过有关 Kernel PCA 的文章,它应该适用于维度非常大的情况,但它的运行时间是,这可能是有问题的,因为我还想处理维度和数量的情况的例子很大。
正如我所看到的,我的选择要么是“优化”PCA,要么是选择另一种本质上更快的降维方法。
我的问题
- 是否有希望以“离线”方式使用 PCA?即,使用大量图像数据集,对它们执行 PCA,然后使用为它们计算的主成分来减少其他(新!)数据点的维度?
- 假设我提前知道我只对前 100 个主成分感兴趣,我可以加快特征向量计算吗?
- 是否有适合我的情况的替代降维方法(即在应用 t-sne 之前)比 PCA 更快?我正在寻找可以在 Java 中轻松实现的东西。