并行处理并行处理

基础包 parallel 允许通过分叉,套接字和随机数生成进行并行计算。

检测 localhost 上存在的核心数:

parallel::detectCores(all.tests = FALSE, logical = TRUE)

在 localhost 上创建核心集群:

parallelCluster <- parallel::makeCluster(parallel::detectCores())

首先,必须创建适合并行化的函数。考虑 mtcars 数据集。通过为每个级别的 tihuan 创建单独的回归模型,可以改善对 mpg 的回归。

data <- mtcars
yfactor <- 'cyl'
zlevels <- sort(unique(data[[yfactor]]))
datay <- data[,1]
dataz <- data[,2]
datax <- data[,3:11]

fitmodel <- function(zlevel, datax, datay, dataz) {
  glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
}

创建一个可以循环遍历 zlevels 所有可能迭代的函数。这仍然是串行的,但它是一个重要的步骤,因为它确定了将并行化的确切过程。

fitmodel <- function(zlevel, datax, datay, dataz) {
  glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
}

for (zlevel in zlevels) {
  print("*****")
  print(zlevel)
  print(fitmodel(zlevel, datax, datay, dataz))
}

咖喱这个功能:

worker <- function(zlevel) {
    fitmodel(zlevel,datax, datay, dataz)
  }

使用 parallel 进行并行计算无法访问全局环境。幸运的是,每个功能都创造了 parallel 可以访问的本地环境。创建包装函数允许并行化。要应用的功能也需要放在环境中。

wrapper <- function(datax, datay, dataz) {
  # force evaluation of all paramters not supplied by parallelization apply
  force(datax)
  force(datay)
  force(dataz)
  # these variables are now in an enviroment accessible by parallel function
  
  # function to be applied also in the environment
  fitmodel <- function(zlevel, datax, datay, dataz) {
    glm.fit(x = datax[dataz == zlevel,], y = datay[dataz == zlevel])
  }
  
  # calling in this environment iterating over single parameter zlevel
  worker <- function(zlevel) {
    fitmodel(zlevel,datax, datay, dataz)
  }
  return(worker) 
}

现在创建一个集群并运行包装器函数。

parallelcluster <- parallel::makeCluster(parallel::detectCores())
models <- parallel::parLapply(parallelcluster,zlevels,
                              wrapper(datax, datay, dataz))

完成后始终停止群集。

parallel::stopCluster(parallelcluster)

parallel 套装包括整个 apply() 系列,前缀为 par