tom*_*mka 13 parallel-processing r statistics-bootstrap
我想加快我的引导功能,它本身运行得非常好.我读过,因为R 2.14有一个名为的软件包parallel
,但我觉得这对某人很难.对计算机科学知识不足以真正实现它.也许有人可以提供帮助.
所以这里有一个引导程序:
n<-1000
boot<-1000
x<-rnorm(n,0,1)
y<-rnorm(n,1+2*x,2)
data<-data.frame(x,y)
boot_b<-numeric()
for(i in 1:boot){
bootstrap_data<-data[sample(nrow(data),nrow(data),replace=T),]
boot_b[i]<-lm(y~x,bootstrap_data)$coef[2]
print(paste('Run',i,sep=" "))
}
Run Code Online (Sandbox Code Playgroud)
目标是使用并行处理/利用我的PC的多个核心.我正在Windows下运行R. 谢谢!
编辑(诺亚回复后)
以下语法可用于测试:
library(foreach)
library(parallel)
library(doParallel)
registerDoParallel(cores=detectCores(all.tests=TRUE))
n<-1000
boot<-1000
x<-rnorm(n,0,1)
y<-rnorm(n,1+2*x,2)
data<-data.frame(x,y)
start1<-Sys.time()
boot_b <- foreach(i=1:boot, .combine=c) %dopar% {
bootstrap_data<-data[sample(nrow(data),nrow(data),replace=T),]
unname(lm(y~x,bootstrap_data)$coef[2])
}
end1<-Sys.time()
boot_b<-numeric()
start2<-Sys.time()
for(i in 1:boot){
bootstrap_data<-data[sample(nrow(data),nrow(data),replace=T),]
boot_b[i]<-lm(y~x,bootstrap_data)$coef[2]
}
end2<-Sys.time()
start1-end1
start2-end2
as.numeric(start1-end1)/as.numeric(start2-end2)
Run Code Online (Sandbox Code Playgroud)
但是,在我的机器上,简单的R代码更快.这是并行处理的已知副作用之一,即它会导致开销过程,这会增加像这样的"简单任务"中的时间吗?
编辑:在我的机器上,parallel
代码比"简单"代码长约5倍.当我增加任务的复杂性(例如增加boot
或n
)时,这个因素显然不会改变.那么代码或我的机器可能存在问题(基于Windows的处理?).
试试这个boot
包.它经过了很好的优化,并且包含一个parallel
参数.这个软件包的棘手之处在于你必须编写新的函数来计算你的统计数据,它接受你正在处理的数据和一个索引向量来重新采样数据.因此,从您定义的位置开始data
,您可以执行以下操作:
# Define a function to resample the data set from a vector of indices
# and return the slope
slopeFun <- function(df, i) {
#df must be a data frame.
#i is the vector of row indices that boot will pass
xResamp <- df[i, ]
slope <- lm(y ~ x, data=xResamp)$coef[2]
}
# Then carry out the resampling
b <- boot(data, slopeFun, R=1000, parallel="multicore")
Run Code Online (Sandbox Code Playgroud)
b$t
是重采样统计量的向量,并且boot
有很多很好的方法可以很容易地用它来做 - 例如plot(b)
请注意,并行方法取决于您的平台.在您的Windows机器上,您将需要使用parallel="snow"
.
我没有测试foreach
与parallel
在Windows后台,但我相信这会为你工作:
library(foreach)
library(doSNOW)
cl <- makeCluster(c("localhost","localhost"), type = "SOCK")
registerDoSNOW(cl=cl)
n<-1000
boot<-1000
x<-rnorm(n,0,1)
y<-rnorm(n,1+2*x,2)
data<-data.frame(x,y)
boot_b <- foreach(i=1:boot, .combine=c) %dopar% {
bootstrap_data<-data[sample(nrow(data),nrow(data),replace=T),]
unname(lm(y~x,bootstrap_data)$coef[2])
}
Run Code Online (Sandbox Code Playgroud)