当我在caret中运行两个随机森林时,如果我设置一个随机种子,我会得到完全相同的结果:
当我在caret中运行两个随机森林时,如果我设置一个随机种子,我得到的结果是完全一样的。
library(caret)
library(doParallel)
set.seed(42)
myControl <- trainControl(method='cv', index=createFolds(iris$Species))
set.seed(42)
model1 <- train(Species~., iris, method='rf', trControl=myControl)
set.seed(42)
model2 <- train(Species~., iris, method='rf', trControl=myControl)
> all.equal(predict(model1, type='prob'), predict(model2, type='prob'))
[1] TRUE
但是,如果我注册一个并行的后端来加速建模,每次运行模型时我会得到不同的结果:
cl <- makeCluster(detectCores())
registerDoParallel(cl)
set.seed(42)
myControl <- trainControl(method='cv', index=createFolds(iris$Species))
set.seed(42)
model1 <- train(Species~., iris, method='rf', trControl=myControl)
set.seed(42)
model2 <- train(Species~., iris, method='rf', trControl=myControl)
stopCluster(cl)
> all.equal(predict(model1, type='prob'), predict(model2, type='prob'))
[1] "Component 2: Mean relative difference: 0.01813729"
[2] "Component 3: Mean relative difference: 0.02271638"
有没有办法解决这个问题? 有一个建议是使用doRNG包,但是train
使用了嵌套循环,当前不支持:
library(doRNG)
cl <- makeCluster(detectCores())
registerDoParallel(cl)
registerDoRNG()
set.seed(42)
myControl <- trainControl(method='cv', index=createFolds(iris$Species))
set.seed(42)
> model1 <- train(Species~., iris, method='rf', trControl=myControl)
Error in list(e1 = list(args = seq(along = resampleIndex)(), argnames = "iter", :
nested/conditional foreach loops are not supported yet.
See the package's vignette for a work around.
更新:
我认为可以使用doSNOW
和clusterSetupRNG
来解决这个问题,但我没能完全搞定。
set.seed(42)
library(caret)
library(doSNOW)
cl <- makeCluster(8, type = "SOCK")
registerDoSNOW(cl)
myControl <- trainControl(method='cv', index=createFolds(iris$Species))
clusterSetupRNG(cl, seed=rep(12345,6))
a <- clusterCall(cl, runif, 10000)
model1 <- train(Species~., iris, method='rf', trControl=myControl)
clusterSetupRNG(cl, seed=rep(12345,6))
b <- clusterCall(cl, runif, 10000)
model2 <- train(Species~., iris, method='rf', trControl=myControl)
all.equal(a, b)
[1] TRUE
all.equal(predict(model1, type='prob'), predict(model2, type='prob'))
[1] "Component 2: Mean relative difference: 0.01890339"
[2] "Component 3: Mean relative difference: 0.01656751"
stopCluster(cl)
foreach有什么特殊之处,为什么它不使用我在集群上初始化的种子?对象a
和b
是相同的,那么为什么model1
和model2
不是呢?
snow
需要修改caret
源代码,而使用doRNG
则失败了。 - Zachlibrary(doMC)
- 参见 http://caret.r-forge.r-project.org/parallel.html - Stéphane Laurent