標籤:

R 如何解決R在大樣本回歸中,內存不足問題?


ps:中文不好請見諒。

好問題!

最簡短的回答就是不要用R!

原因(據我的了解,可能有誤,但八九不離十):任何數據類型在R中都和雙精度等價的。比如說你想保存一個boolean,但其實佔用的內存和double是一樣的。其次R是copy by memory。如果matrix A用了1G內存,那麼B=A就會佔用2G內存。(這個問題我在使用parralel 作fork並行的時候尤為明顯。不知為何如果一個函數引用一個變數,會把那個變數在內存中複製一邊。最後我的解決方法是用了很多全局變數,然後函數不申明引用那個變數,在運算的時候直接調用。這樣做很危險,很難debug~)

解決方案:用C,python,(julia?)

他們都是copy by reference。 B=A後內存只會多一個指針。而且他們對內存有更精確的控制,作並行運算的時候可以共享主要的數據。甚至你可以用或者自己實現運算不一定那麼快但是需要內存少的演算法。

偷懶的辦法:既然是大樣本,假設你的sample size 很大。那麼可以取一個subsample(隨機取一個子集,能放進內存就好)。 子集的結果和全部大樣本的結果應該差別不大。因為回歸的收斂速度還是挺快的么:)。


如果,必須用R不能用別的語言,還不能升級硬體,那麼你可以藉助一下bootstrap這種奇技淫巧:

1. 隨機採樣200次,每一次採樣20%的數據(當然200次和20%是我隨便說的,你自己看情況定)

2. 給每個小樣本作回歸,這樣你有200組參數

3. 取這200組參數的中位數作為解


回歸演算法會比較花費時間,而且針對不同的數據還有不同的優化方式。

常見優化的思路:

1. 考慮演算法層面的優化,比如是否正定,用cholesky分解代替原生的QR分解等。

2. 考慮模型的優化,比如是否寫成MapReduce,或者採用 @伊首衡 提到的boostrap的方式等等。

3. 考慮計算引擎的優化,是否使用SparkR, BLAS/LAPACK

4. 考慮外部環境層面的優化,是否有足夠的內存配置。

5. 考慮內存管理的優化,是否使用gc、Rcpp等內存控制方式。

也可以參考陳雁平老師的文章:用R處理大數據集下面是一些節選:分析大數據集的包

R提供了幾種分析大數據集的包:

  • biglmspeedglm 包可以針對大數據集有效地擬合線性和廣義線性模型。在處理大規模數據集時,這兩個包提供了類似lm()和glm()的功能。
  • bigmemory 包可產生大規模矩陣,一些包可以提供分析這些大規模矩陣的函數。bigannalytics 包提供了k-means聚類、行統計量(column statistics)和一個對biglm()的封裝。bigtabulate 包提供了table()、split()和tapply()的功能,bigalgebra 包提供了高等線性代數的函數。
  • biglars 包提供了最小角回歸(least-angle regression)、lasso以及針對大數據集的逐步回歸,數據集因太大而不能讀入到內存中,這時候要配合 ff 包使用。
  • Brobdingnag 包可以用來處理大數字(大於2^1024)

處理從GB到TB級的數據對於任何數據都是極大的挑戰。如果想查看R的更多方法,請看CRAN task View: High-Performance and Parallel Computing with R (http://cran.r-project.org/web/view)。

譯者注

李艦曾經在第四屆R語言會議(北京會場)上做了題為《 R與高性能運算 》的報告,報告slides及代碼請見會議紀要


CRAN - Package bigmemory

Michael Kane on Bigmemory

這個作者的一系列包,可以用shared memory來解決大數據集在R中的存儲分析問題。當然SparkR在伺服器上也是解決方法,但是應該對於單機個人用戶big系列包應該是一個很好的解決方案。

同時請參考CRAN上的task view

CRAN Task View: High-Performance and Parallel Computing with R

中的Large memory and out-of-memory data一節,其中介紹了很多關於大數據集分析方法工具的軟體包。


插一張超大的閃存, 調成虛擬內存來用

超超超大的樣本, 就在aws雲端開個Spark集群, 用SparkR, 賦予每個橫列(row)一個隨機數後grouping可以實現抽樣出數個子集, 把要用的模型套到MapReduce, 看不同子集所擬合的參數分佈

SparkR (R on Spark)


R語言和大數據的結合,有hadoopR、hiveR,sparkR,做的比較完善的是sparkR,採用了分散式 df和spark-ml 演算法,能夠將基本操作都在R中進行處理


結合mysql一起使用,導入自己需要的那一部分就行,實在不行就只有換python了


請用h2o


換其他編程語言的方案已經有人提了

我給你個實際可行的方法就是,

租用Google或者Amazon的計算平台,對於新用戶都有免費。比如我用Google,可以建一個虛擬機,用200G內存,總該滿足你需求了。

當然,這是短期的,如果經常要處理大規模數據,確實R並不是很合適。


推薦閱讀:

在《one.一個》改版前,你一直念念不忘的文章是哪篇?

TAG:R編程語言 | R |