Pca
為什麼要通過數據的 SVD 對數據進行 PCA?
這個問題是關於計算主成分的有效方法。
- 許多關於線性 PCA 的文章都提倡使用個案數據的奇異值分解。也就是說,如果我們有數據並且想用主成分替換變量(它的列),我們做 SVD:,奇異值(特徵值的平方根)佔據主對角線, 右特徵向量是軸變量到軸分量的正交旋轉矩陣,左特徵向量像, 僅適用於案例。然後我們可以將組件值計算為.
- 對變量進行 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
本文討論了 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