我尝试比较多达数千个估计的β分布。每个β分布的特征在于两个形状参数α和β。公测。 我现在抽取每个分布的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()
感谢任何帮助!
答案 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)