使用并行编程在{R}编程50000回归

时间:2015-11-15 21:17:58

标签: r performance parallel-processing

我有以下作业问题,我已经完成但似乎要花费相当长的时间才能完成:

假设Y,X1,···,X1000都是具有均值0和标准差1的正态随机变量,并且它们彼此独立。生成30个Y,X1,...,X1000样本。现在重复以下50000次:从X1中随机拾取十个变量。 。 。,X1000,对这十个变量进行Y的线性回归并记录R2。计算50000 R2的最大值。

这是我的代码,适用于8000次回归(对我的macbook pro的每个核心进行1000次回归),但似乎无法完成每个核心上的6250次回归(总计50000次回归)。这是我的代码:

    library(snow)
    cl <- makeCluster(8, type = "SOCK")
    invisible(clusterEvalQ(cl, reg_cluster <- function(rep, samples, n) {
     X <- list()
      R <- rep(0, rep)
      for (k in 1:rep) {
        Y <- rnorm(samples)
        for (j in 1:n) {
          X[[j]] <- rnorm(samples)
    }
   X_1 <- sample(X, 10, replace = FALSE)
   X_1_unlist <- unlist(X_1)
   X.1 <- matrix(X_1_unlist[1:30], ncol = 1)
   X.2 <- matrix(X_1_unlist[31:60], ncol = 1)
   X.3 <- matrix(X_1_unlist[61:90], ncol = 1)
   X.4 <- matrix(X_1_unlist[91:120], ncol = 1)
   X.5 <- matrix(X_1_unlist[121:150], ncol = 1)
   X.6 <- matrix(X_1_unlist[151:180], ncol = 1)
   X.7 <- matrix(X_1_unlist[181:210], ncol = 1)
   X.8 <- matrix(X_1_unlist[211:240], ncol = 1)
   X.9 <- matrix(X_1_unlist[241:270], ncol = 1)
   X.10 <- matrix(X_1_unlist[271:300], ncol = 1)
   X_data <- cbind(X.1, X.2, X.3, X.4, X.5, X.6, X.7, X.8, X.9, X.10)
   X_data <- as.data.frame (X_data)
   names(X_data) <- c("X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10")
   attach(X_data)
   reg <- lm(Y ~ X1 + X2 + X3 + X4 + X5 + X6 + X7 + X8 + X9 + X10)
   R[k] <- summary(reg)$r.squared
  }
return(max(R))
}))
results <- clusterEvalQ(cl, reg_cluster(1000, 30, 1000))
results <-clusterEvalQ(cl, reg_cluster(6250, 30, 1000))
stopCluster(cl)
max_results <- c(results[[1]], results[[2]], results[[3]], results[[4]],
                 results[[5]], results[[6]], results[[7]], results[[8]])
max(max_results)

此处应注意其他事项。每次运行新回归时,Y和所有X都会再次生成。没有随机变量从一个回归延续到下一个回归。

所以我的问题是,如何让这次运行更快?

此外,任何人都可以告诉我为什么它在完成8000次回归后12分钟后完成,但在2.5小时后仍然没有完成50000次回归?

编辑:教授已确认以下程序:

1)生成Y,X1,...,X1000各30个随机标准正态变量。对于Y,我总共有30个随机正态变量,并且对于所有X,总共30 x 1,000 = 30,000个随机正态变量(每个30个)

2)随机选择X的1000个选项中的10个(例如X726,X325,X722,X410,X46,X635,X822,X518,X773,X187)

3)使用R中的lm函数运行线性回归Y~10 X.Y将有30个观测值,而每个X也有30个观测值。基本上我们试图拟合Y = B0 + B1 * X1 + B2 * X2 + ... + B10 * X10,其中每个X代表第2部分中随机选择的一个。

4)在矢量中记录R2值

5)重复步骤1-4 50,000次

6)找到50,000记录的最大R2

1 个答案:

答案 0 :(得分:0)

这是一个似乎可以解决您问题的替代代码。

ns <- 30

rvals <- replicate(50000, {
  y <- rnorm(ns)
  xvals <- replicate(1000, rnorm(ns))
  selecteds <- xvals[,sample(1:1000, 10)]
  df <- data.frame(y = ys, selecteds)
  summary(lm(paste("y ~", paste0("X", 1:10, collapse = "+")), data = df))$r.squared
})

我对群集不是很有经验,但这里有一些原因可能导致您的代码太慢:

  • 你有嵌套的foor循环来创建X,我使用replicate,这可能比使用列表稍快。
  • 您正在制作一个空列表,X,这非常糟糕。 (检查The R inferno - Circle 2
  • 您不再列出几个列表元素,只是为了使它们成为1列矩阵,然后将它们全部绑定,最后命名列。虽然这些步骤似乎是必要的,但我认为一次一个地做这个步骤可能很慢。例如,colnames会自动设置为X1:X10。
  • 使用attach并非必要,可能会减慢速度。
  • 如果打开/关闭太多群集,会消耗大量处理,并且可能比非并行更慢。虽然看起来不是这样的。

作为最后一点,请确保我和你一样,因为这个问题对我来说仍然有点混乱。