Pca

當 n,p 都很大時,PCA 太慢:替代方案?

  • March 21, 2017

問題設置

我有高維(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 分鐘,這比我在這個階段所能承受的要長得多)。

我讀過關於內核 PCA 的文章,它應該適用於維度非常大的情況,但它的運行時間是這可能是有問題的,因為我還想處理維度示例數量都很大的情況。

正如我所看到的,我的選擇要么是“優化”PCA,要么是選擇另一種本質上更快的降維方法。

我的問題

  1. 是否有希望以“離線”方式使用 PCA?即,使用大量圖像數據集,對它們執行 PCA,然後使用為它們計算的主成分來減少其他(新!)數據點的維度?
  2. 假設我提前知道我只對前 100 個主成分感興趣,我可以加快特徵向量計算嗎?
  3. 是否有適合我的情況的替代降維方法(即在應用 t-sne 之前)比 PCA 更快?我正在尋找可以在 Java 中輕鬆實現的東西。

問題 1:假設您觀察到了一個數據矩陣. 由此您可以計算特徵分解. 現在的問題是:如果我們從同一人群中獲得新數據,也許會收集到一個矩陣中, 將要接近理想的正交旋轉? 戴維斯-卡漢定理和一般的矩陣微擾理論解決了這類問題(如果你能拿到副本,斯圖爾特和孫 1990 年的教科書是標準參考)。

問題2:如果你知道你只需要頂部,你肯定可以加快速度特徵向量。在 RIrARPACK中用於此;我確信有一個 Java 等價物,因為無論如何它們都是 fortran 包裝器。

問題 3:我對 Java 實現一無所知,但是這個線程討論加速 PCA 和這個CV 線程一樣。有大量關於這類事情的研究,並且有大量使用低秩近似或隨機化等方法的方法。

引用自:https://stats.stackexchange.com/questions/268935

comments powered by Disqus