降雪中R的并行蒙特卡罗模拟

时间:2013-10-29 20:02:05

标签: r performance parallel-processing montecarlo

我尝试比较多达数千个估计的β分布。每个β分布的特征在于两个形状参数α和β。公测。 我现在抽取每个分布的100,000个样本。作为最终结果,我希望在每个样本抽取中获得具有最高概率的分布的顺序。 我的第一种方法是使用lapply生成N * NDRAWS数值的矩阵,当N超过10,000时,这些值消耗了太多的内存。 (10,000 * 100,000 * 8字节)

所以我决定使用顺序方法对每一次抽奖进行排序,然后按顺序绘制所有抽奖的顺序,并获得最终顺序,如下例所示:

set.seed(12345)
N=100
NDRAWS=100000
df <- data.frame(alpha=sample(1:20, N, replace=T), beta=sample(1:200, N, replace=T))  

vec    <- vector(mode = "integer", length = N )

for(i in 1:NDRAWS){
  # order probabilities after a single draw for every theta
  pos <- order(rbeta(N, shape1=df$alpha, shape2=df$beta) )

  # sum up winning positions for every theta
  vec[pos] <- vec[pos] + 1:N
}

# order thetas
ord <- order(-vec)

df[ord,]

这只消耗N * 4字节的内存,因为没有巨型矩阵而是长度为N的单个向量。我现在的问题是,如何使用降雪(或任何其他多核包)加速此操作我的4个CPU核心的优势,而不是只使用一个核心???

# parallelize using snowfall pckg
library(snowfall)
sfInit( parallel=TRUE, cpus=4, type="SOCK")
sfLapply( 1:NDRAWS, function(x) ?????? )
sfStop()

感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

这可以通过并行化随机林或引导的方式进行并行化。您只需对每个工作程序执行顺序代码,但每个工作程序使用较少的迭代次数。这比将for循环的每次迭代分成单独的并行任务要有效得多。

以下是转换为使用带有doParallel后端的foreach包的完整示例:

set.seed(12345)
N=100
NDRAWS=100000
df <- data.frame(alpha=sample(1:20, N, replace=T),
                 beta=sample(1:200, N, replace=T))
library(doParallel)
nworkers <- detectCores()
cl <- makePSOCKcluster(nworkers)
clusterSetRNGStream(cl, c(1,2,3,4,5,6,7))
registerDoParallel(cl)

vec <- foreach(ndraws=rep(ceiling(NDRAWS/nworkers), nworkers),
               .combine='+') %dopar% {
  v <- integer(N)
  for(i in 1:ndraws) {
    pos <- order(rbeta(N, shape1=df$alpha, shape2=df$beta) )
    v[pos] <- v[pos] + 1:N
  }
  v
}
ord <- order(-vec)
df[ord,]

请注意,这会产生与顺序版本不同的结果,因为工作人员会生成不同的随机数。我使用了并行包提供的并行随机数支持,因为这是一种很好的做法。

答案 1 :(得分:0)

嗯,功能就在那里。我不确定你每次迭代都会返回什么。

或许试试这个?

myFunc <- function(xx, N) {
  pos <- order(rbeta(N, shape1=df$alpha, shape2=df$beta) )
  vec[pos] + 1:N
}

使用doParallel将允许您添加结果:

require(doParallel)
registerDoParallel(cores=4)
foreach(i=1:NDRAWS, .combine='+') %dopar% myFunc(i, N)