Pca

為什麼要通過數據的 SVD 對數據進行 PCA?

  • December 9, 2013

這個問題是關於計算主成分的有效方法。

  1. 許多關於線性 PCA 的文章都提倡使用個案數據的奇異值分解。也就是說,如果我們有數據並且想用主成分替換變量(它的),我們做 SVD:,奇異值(特徵值的平方根)佔據主對角線, 右特徵向量是軸變量到軸分量的正交旋轉矩陣,左特徵向量像, 僅適用於案例。然後我們可以將組件值計算為.
  2. 對變量進行 PCA 的另一種方法是通過分解方陣(即 可以是變量之間的 相關性協方差等)。分解可以是特徵分解或奇異值分解:對於方形對稱正半定矩陣,它們將給出相同的結果以特徵值作為對角線, 和如前所述。組件值將是.

現在,我的問題:如果數據是一個大矩陣,並且案例的數量(通常是案例)遠大於變量的數量,那麼方式(1)預計會比方式(2)慢得多,因為方式(1)適用於相當大矩陣的昂貴算法(例如 SVD);它計算和存儲巨大的矩陣在我們的例子中我們真的不需要它(變量的 PCA)。如果是這樣,那麼為什麼這麼多教科書似乎提倡或僅提及方式(1)?也許它有效的,我錯過了什麼?

這是我關於這個話題的 2ct

  • 我第一次學習 PCA 的化學計量學講座使用了解決方案 (2),但它不是面向數值的,而且我的數值講座只是一個介紹,據我記得沒有討論 SVD。
  • 如果我正確理解Holmes: Fast SVD for Large-Scale Matrices,那麼您的想法已被用於獲得長矩陣的計算快速 SVD。

這意味著如果遇到合適的矩陣,一個好的 SVD 實現可能會在內部遵循 (2)(我不知道是否還有更好的可能性)。這意味著對於高級實現,最好使用 SVD (1) 並將其留給 BLAS 來處理內部使用的算法。

  • 快速實際檢查:OpenBLAS 的 svd 似乎沒有做出這種區分,在 5e4 x 100 的矩陣svd (X, nu = 0)上,中位數為 3.5 秒,而svd (crossprod (X), nu = 0)需要 54 毫秒(從 R 調用microbenchmark)。

特徵值的平方當然很快,並且兩個調用的結果是等價的。

timing  <- microbenchmark (svd (X, nu = 0), svd (crossprod (X), nu = 0), times = 10)
timing
# Unit: milliseconds
#                      expr        min         lq    median         uq        max neval
#            svd(X, nu = 0) 3383.77710 3422.68455 3507.2597 3542.91083 3724.24130    10
# svd(crossprod(X), nu = 0)   48.49297   50.16464   53.6881   56.28776   59.21218    10


更新:看看Wu,W。Massart, D. & de Jong, S.:寬數據的內核 PCA 算法。第一部分:理論和算法,化學計量學和智能實驗室系統,36, 165 - 172 (1997)。DOI:http://dx.doi.org/10.1016/S0169-7439(97)00010-5

本文討論了 PCA 的 4 種不同算法的數值和計算特性:SVD、特徵分解 (EVD)、NIPALS 和 POWER。

它們的關係如下:

computes on      extract all PCs at once       sequential extraction    
X                SVD                           NIPALS    
X'X              EVD                           POWER

論文的上下文很廣泛 ,並且他們致力於(內核 PCA) - 這與您詢問的情況正好相反。因此,要回答有關長矩陣行為的問題,您需要交換“內核”和“經典”的含義。

性能比較

毫不奇怪,EVD 和 SVD 會根據使用的是經典算法還是內核算法而改變位置。在這個問題的上下文中,這意味著根據矩陣的形狀,一個或另一個可能更好。

但從他們對“經典”SVD 和 EVD 的討論中可以清楚地看出,是計算 PCA 的一種非常常用的方法。svd ()但是,除了使用 Matlab 的函數外,他們沒有指定使用哪種 SVD 算法。


   > sessionInfo ()
   R version 3.0.2 (2013-09-25)
   Platform: x86_64-pc-linux-gnu (64-bit)

   locale:
    [1] LC_CTYPE=de_DE.UTF-8       LC_NUMERIC=C               LC_TIME=de_DE.UTF-8        LC_COLLATE=de_DE.UTF-8     LC_MONETARY=de_DE.UTF-8   
    [6] LC_MESSAGES=de_DE.UTF-8    LC_PAPER=de_DE.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C            
   [11] LC_MEASUREMENT=de_DE.UTF-8 LC_IDENTIFICATION=C       

   attached base packages:
   [1] stats     graphics  grDevices utils     datasets  methods   base     

   other attached packages:
   [1] microbenchmark_1.3-0

loaded via a namespace (and not attached):
[1] tools_3.0.2


$ dpkg --list libopenblas*
[...]
ii  libopenblas-base              0.1alpha2.2-3                 Optimized BLAS (linear algebra) library based on GotoBLAS2
ii  libopenblas-dev               0.1alpha2.2-3                 Optimized BLAS (linear algebra) library based on GotoBLAS2

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

comments powered by Disqus