2012-01-09 96 views
1

我正在努力研究如何將「數據挖掘與R - 學習案例研究」中的一些代碼並行化,以便在我的Macbook Pro上運行得更快。問題中的特定代碼如下。該代碼基本上使用相同的數據(DS),並將6個不同的學習者(例如svm,nnet用於迴歸和分類等)和少量變體應用。R - 如何並行化蒙特卡洛模擬的for循環?

完整的代碼是HERE(靠近底部,在「模型評估和選擇」部分)。

for(td in TODO) { 
    assign(td, 
    experimentalComparison(
     DSs,   
     c(
     do.call('variants', 
       c(list('singleModel',learner=td),VARS[[td]], 
        varsRootName=paste('single',td,sep='.'))), 
     do.call('variants', 
       c(list('slide',learner=td, 
         relearn.step=c(60,120)), 
        VARS[[td]], 
        varsRootName=paste('slide',td,sep='.'))), 
     do.call('variants', 
       c(list('grow',learner=td, 
         relearn.step=c(60,120)), 
        VARS[[td]], 
        varsRootName=paste('grow',td,sep='.'))) 
     ), 
     MCsetts) 
    ) 
    # save the results 
    save(list=td,file=paste(td,'Rdata',sep='.')) 
} 

大多數我找到了並行化的信息,似乎更適用於像「應用」,東西的地方同樣的功能應用到數據的不同子集。這段代碼的作用恰恰相反 - 不同的功能應用了相同的數據。

平行外部FOR循環會更好嗎?這樣可以同時爲多個學習者運行代碼,而不是平行循環內的代碼,以便不同的窗口方法與單個學習者並行。

在我的MacBook上,一次迭代的執行時間超過2小時,其中只有2個核心似乎在做任何事情(其他兩個只是閒置)。鏈接中的實際代碼被設置爲20次迭代......使用我的空閒內核來減少這種情況會很棒

+1

對於廣泛的蒙特卡洛模擬,無論您如何平行化,R可能都太慢。獲得小的(1-5倍)加速的簡單方法是使用編譯器函數來編譯主函數(例如'variantsCMP < - cmpfun(variants)'),但是爲了更快的加速,您可以最好地使用編譯語言。通過'Rcpp'軟件包可以很容易地在R中實現C++ – 2012-01-09 19:21:51

+2

並行計算的一種快速和骯髒的方法是使用'lapply(1:N,some_function)',其中'N'是你想要的次數來計算'some_function'在Unix/Linux上,你可以用'parallel'軟件包中的'mclapply'來代替'lapply'(假設你有一個以上的內核)。如果你在Windows上,看看'snow 'package。 – 2012-01-09 20:13:15

+0

所以,像lapply(1:6,code_as_function())這樣的函數?函數使用所有全局變量而不是傳遞給它的任何東西?這似乎是有道理的,因爲TODO變量是隻是一個更精簡的名稱列表適用於整個數據集 – 2012-01-09 20:25:44

回答

2

在不平行的情況下,將函數傳遞到lapply循環很簡單。

lapply(c(mean, sum), function(f) f(1:5)) 

這是幾個不同的系統用於R並行編程。下一個示例使用snow

library(snow) 
cl <- makeCluster(c("localhost","localhost"), type = "SOCK") 
clusterApply(cl, c(mean, sum), function(f) f(1:5)) 
stopCluster(cl) 

你應該在每種情況下得到相同的答案!

+0

我在mac上,所以像t此刻的加利福尼亞州 - 無雪 – 2012-01-09 21:58:23

+0

CRAN上有一個Mac二進制代碼用於'snow'。你確定它不會起作用嗎? http://cran.r-project.org/web/packages/snow/index.html – 2012-01-09 22:06:58

+0

無論如何,使用哪種並行方式並沒有對概念產生影響:你需要像'lapply'這樣的函數,並且通過它的功能列表(功能的名稱也將起作用)。 – 2012-01-09 22:09:26