izquierdo - Modelos paralelos completamente reproducibles utilizando el cursor
mi click derecho no funciona laptop (2)
Entonces, caret usa el paquete foreach para paralelizar. Probablemente haya una manera de establecer la semilla en cada iteración, pero tendríamos que configurar más opciones en el train
.
Alternativamente, puede crear una función de modelado personalizada que imite la función interna para bosques aleatorios y establecer la semilla usted mismo.
Max
Cuando ejecuto 2 bosques aleatorios en caret, obtengo exactamente los mismos resultados si configuro una semilla aleatoria:
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
Sin embargo, si registro un back-end paralelo para acelerar el modelado, obtengo un resultado diferente cada vez que ejecuto el modelo:
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"
¿Hay alguna manera de arreglar este problema? Una sugerencia fue utilizar el paquete doRNG , pero train
utiliza bucles anidados, que actualmente no son compatibles:
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.
ACTUALIZACIÓN: pensé que este problema podría resolverse utilizando doSNOW
y clusterSetupRNG
, pero no pude llegar allí.
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)
¿Qué tiene de especial foreach, y por qué no usa las semillas que inicié en el clúster? los objetos a
y b
son idénticos, ¿por qué no model1
y model2
?
Una forma fácil de ejecutar un modelo completamente reproducible en modo paralelo utilizando el paquete caret
es usar el argumento de semillas al llamar al control del tren. Aquí se resuelve la pregunta anterior, consulte la página de ayuda de trainControl para obtener más información.
library(doParallel); library(caret)
#create a list of seed, here change the seed for each resampling
set.seed(123)
#length is = (n_repeats*nresampling)+1
seeds <- vector(mode = "list", length = 11)
#(3 is the number of tuning parameter, mtry for rf, here equal to ncol(iris)-2)
for(i in 1:10) seeds[[i]]<- sample.int(n=1000, 3)
#for the last model
seeds[[11]]<-sample.int(1000, 1)
#control list
myControl <- trainControl(method=''cv'', seeds=seeds, index=createFolds(iris$Species))
#run model in parallel
cl <- makeCluster(detectCores())
registerDoParallel(cl)
model1 <- train(Species~., iris, method=''rf'', trControl=myControl)
model2 <- train(Species~., iris, method=''rf'', trControl=myControl)
stopCluster(cl)
#compare
all.equal(predict(model1, type=''prob''), predict(model2, type=''prob''))
[1] TRUE