我在R中使用princomp
來執行PCA。我的數據矩陣很大(10K x 10K,每個值最多4個小數點)。在至強2.27 GHz處理器上,需要3.5小時〜6.5 GB的物理內存。什麼是計算R中前兩個主成分的最快方法?
因爲我只想要前兩個組件,有沒有更快的方法來做到這一點?
更新:
除了速度,是否有記憶有效的方式做到這一點?
使用svd(,2,)
需要約2小時和〜6.3 GB的物理內存來計算前兩個組件。
我在R中使用princomp
來執行PCA。我的數據矩陣很大(10K x 10K,每個值最多4個小數點)。在至強2.27 GHz處理器上,需要3.5小時〜6.5 GB的物理內存。什麼是計算R中前兩個主成分的最快方法?
因爲我只想要前兩個組件,有沒有更快的方法來做到這一點?
更新:
除了速度,是否有記憶有效的方式做到這一點?
使用svd(,2,)
需要約2小時和〜6.3 GB的物理內存來計算前兩個組件。
有時您可以訪問所謂的「經濟」分解,它允許您限制特徵值/特徵向量的數量。它看起來像eigen()
和prcomp()
不提供此功能,但svd()
允許您指定要計算的最大數量。
在小矩陣,漲幅顯得謙虛:
R> set.seed(42); N <- 10; M <- matrix(rnorm(N*N), N, N)
R> library(rbenchmark)
R> benchmark(eigen(M), svd(M,2,0), prcomp(M), princomp(M), order="relative")
test replications elapsed relative user.self sys.self user.child
2 svd(M, 2, 0) 100 0.021 1.00000 0.02 0 0
3 prcomp(M) 100 0.043 2.04762 0.04 0 0
1 eigen(M) 100 0.050 2.38095 0.05 0 0
4 princomp(M) 100 0.065 3.09524 0.06 0 0
R>
但三相對於princomp()
的因素可能是值得的,同時從svd()
重建princomp()
爲svd()
讓你後兩個值停止。
N = 200我的機器的打印速度最快(不是太多,基本上等於svd(,2,),所以結果可能會因處理器和擴展而有所不同 –
「基準」功能在哪裏 –
在rbenchmark軟件包中還有一個microbenchmark軟件包 –
您可以自己編寫函數,並停止在2個組件。這並不難。我把它放在某個地方,如果我找到它,我會發布它。
可能是你可以給邏輯的功能,我可以嘗試編碼我自己! – 384X21
作爲PCA的入門書,我做了一篇博客文章,試圖用OLS來解釋這一點:http://www.cerebralmastication。com/2010/09/principal-component-analysis-pca-vs-ordinary-least-squares-ols-a-visual-explination/ 在底部有一個鏈接到我發現的Lindsay I Smith的文章很有幫助。鏈接到史密斯PDF:http://www.cs.otago.ac.nz/cosc453/student_tutorials/principal_components.pdf –
@JD龍:這是一個有趣的文章。讓我嘗試 ! – 384X21
您可以使用神經網絡方法找到主要組件。 基本描述在這裏給出.. http://www.heikohoffmann.de/htmlthesis/node26.html
第一主成分,Y = W1 * X1 + W2 * X2 和第二正交分量可以被計算爲Q = W2 * X1-W1 * X2。
power method可能是你想要的。如果你使用R編碼,這並不難,我認爲你可能會發現它不會比其他答案中提出的SVD方法更快,因爲它使用了LAPACK編譯的例程。
我建議不要這是因爲功率方法的收斂速度非常慢 –
在很多情況下都是如此,速度取決於最大特徵值對下一個特徵值的相對大小,所以它將依賴於問題。找到兩個特徵向量並且矩陣非常大。沒有嘗試就不知道的方法 –
'svd'包通過Lanczos算法提供了截斷SVD /本徵分解的例程。您可以使用它來計算前兩個主要組件。
這裏我:
> library(svd)
> set.seed(42); N <- 1000; M <- matrix(rnorm(N*N), N, N)
> system.time(svd(M, 2, 0))
user system elapsed
7.355 0.069 7.501
> system.time(princomp(M))
user system elapsed
5.985 0.055 6.085
> system.time(prcomp(M))
user system elapsed
9.267 0.060 9.368
> system.time(trlan.svd(M, neig = 2))
user system elapsed
0.606 0.004 0.614
> system.time(trlan.svd(M, neig = 20))
user system elapsed
1.894 0.009 1.910
> system.time(propack.svd(M, neig = 20))
user system elapsed
1.072 0.011 1.087
由於我的數據是方矩陣,有沒有一種方法只能輸入上/下三角矩陣到任何函數(svd,princomp,prcomp)?這將節省內存消耗步驟,將較低三角形複製爲上三角形! – 384X21
我不認爲這是可能的「常用」功能。對於來自「svd」包的東西,您可以使用所謂的「外部矩陣接口」,您只需定義如何將矩陣乘以矢量即可,就這些了。現在這個API只是C級別的,但有傳聞說一切都會很快傳播到普通的R級,所以人們可以在R中編寫自己的例程(並且肯定會利用矩陣的對稱性或稀疏性)。 –
我試過NIPALS算法的pcaMethods包的實現。默認情況下,它會計算前兩個主要組件。結果比其他建議的方法慢。
set.seed(42); N <- 10; M <- matrix(rnorm(N*N), N, N)
library(pcaMethods)
library(rbenchmark)
m1 <- pca(M, method="nipals", nPcs=2)
benchmark(pca(M, method="nipals"),
eigen(M), svd(M,2,0), prcomp(M), princomp(M), order="relative")
test replications elapsed relative user.self sys.self
3 svd(M, 2, 0) 100 0.02 1.0 0.02 0
2 eigen(M) 100 0.03 1.5 0.03 0
4 prcomp(M) 100 0.03 1.5 0.03 0
5 princomp(M) 100 0.05 2.5 0.05 0
1 pca(M, method = "nipals") 100 0.23 11.5 0.24 0
+1 - 感謝您進行經驗性比較。 –
可以使用NIPALS算法。搜索R軟件包。 –