在 R 中所有可能的排列上使用 'foreach' 到 运行
Using 'foreach' to run on all possible permutations in R
我无法理解如何使我的代码并行化。我的愿望是从 20 个矩阵中找到 3 个向量,这些向量产生与我的测量变量最接近的线性回归(这意味着总共有 1140 种不同的组合)。目前,我能够使用 3 个嵌套 foreach
循环,return 最好的向量。但是,我的愿望是使外循环(或所有外循环?)并行工作。如有任何帮助,我们将不胜感激!
这是我的代码:
NIR= matrix(rexp(100, rate=0.01),ncol=20, nrow = 4) #Creating the matrix with 20 vectors
colnames(NIR)=c(1:20)
S.measured=c(7,9,11,13) #Measured variable
bestvectors<-matrix(data=NA,ncol = 3+1, nrow= 1) #creating a vector to save in it the best results
###### Parallel stuff
no_cores <- detectCores() - 1
cl<-makeCluster(no_cores)
registerDoParallel(cl)
#nested foreach loop to exhaustively find the best vectors
foreach(i=1:numcols) %:%
foreach(j=i:numcols) %:%
foreach(k=j:numcols) %do% {
if(i==j|i==k|j==k){ #To prevent same vector from being used twice
}
else{
lm<-lm(S.measured~NIR[,c(i,j,k)]-1) # package that calculates the linear regression
S.pred<-as.matrix(lm$fitted.values) # predicted vector to be compared with the actual measured one
error<-sqrt(sum(((S.pred-S.measured)/S.measured)^2)) # The 'Error' which is the product of the comparison which we want to minimize
#if the error is smaller than the last best one, it replaces it. If not nothing changes
if(error<as.numeric(bestvectors[1,3+1])|is.na(bestvectors[1,3+1])){
bestvectors[1,]<-c(colnames(NIR)[i],colnames(NIR)[j],colnames(NIR)[k],as.numeric(error))
bestvectors[,3+1]<-as.numeric(bestvectors[,3+1])
}
}
}
使用 foreach
的一般建议:
如果您希望您的代码在多核上 运行,请使用 foreach(i=1:numcols) %dopar% { ... }
。 %do%
装饰器不完美地模拟了并行性,但 运行 在单核上。
在循环 运行ning 期间,由 %dopar%
生成的进程无法相互通信。因此,设置您的代码以输出 R 对象,例如 data.frame
或 vector
,然后再进行比较。在您的情况下,if(error<as.numeric ...
行中的逻辑应在主 foreach
循环之后按顺序(而非并行)执行。
嵌套 %dopar%
循环的行为在操作系统之间不一致,并且在跨内核生成进程的方式上也不清楚。为了获得最佳性能和可移植性,请在最外层循环中使用单个 foreach
循环,然后在其中使用香草 for
循环。
我无法理解如何使我的代码并行化。我的愿望是从 20 个矩阵中找到 3 个向量,这些向量产生与我的测量变量最接近的线性回归(这意味着总共有 1140 种不同的组合)。目前,我能够使用 3 个嵌套 foreach
循环,return 最好的向量。但是,我的愿望是使外循环(或所有外循环?)并行工作。如有任何帮助,我们将不胜感激!
这是我的代码:
NIR= matrix(rexp(100, rate=0.01),ncol=20, nrow = 4) #Creating the matrix with 20 vectors
colnames(NIR)=c(1:20)
S.measured=c(7,9,11,13) #Measured variable
bestvectors<-matrix(data=NA,ncol = 3+1, nrow= 1) #creating a vector to save in it the best results
###### Parallel stuff
no_cores <- detectCores() - 1
cl<-makeCluster(no_cores)
registerDoParallel(cl)
#nested foreach loop to exhaustively find the best vectors
foreach(i=1:numcols) %:%
foreach(j=i:numcols) %:%
foreach(k=j:numcols) %do% {
if(i==j|i==k|j==k){ #To prevent same vector from being used twice
}
else{
lm<-lm(S.measured~NIR[,c(i,j,k)]-1) # package that calculates the linear regression
S.pred<-as.matrix(lm$fitted.values) # predicted vector to be compared with the actual measured one
error<-sqrt(sum(((S.pred-S.measured)/S.measured)^2)) # The 'Error' which is the product of the comparison which we want to minimize
#if the error is smaller than the last best one, it replaces it. If not nothing changes
if(error<as.numeric(bestvectors[1,3+1])|is.na(bestvectors[1,3+1])){
bestvectors[1,]<-c(colnames(NIR)[i],colnames(NIR)[j],colnames(NIR)[k],as.numeric(error))
bestvectors[,3+1]<-as.numeric(bestvectors[,3+1])
}
}
}
使用 foreach
的一般建议:
如果您希望您的代码在多核上 运行,请使用
foreach(i=1:numcols) %dopar% { ... }
。%do%
装饰器不完美地模拟了并行性,但 运行 在单核上。在循环 运行ning 期间,由
%dopar%
生成的进程无法相互通信。因此,设置您的代码以输出 R 对象,例如data.frame
或vector
,然后再进行比较。在您的情况下,if(error<as.numeric ...
行中的逻辑应在主foreach
循环之后按顺序(而非并行)执行。嵌套
%dopar%
循环的行为在操作系统之间不一致,并且在跨内核生成进程的方式上也不清楚。为了获得最佳性能和可移植性,请在最外层循环中使用单个foreach
循环,然后在其中使用香草for
循环。