Está de moda usar caret
para estas cosas, pero yo estoy todavía acostumbrado a hacerlas a mano. Creo, además, que es poco instructivo ocultar estas cuestiones detrás de funciones de tipo caja-negra-maravillosa a quienes se inician en el mundo de la construcción y comparación de modelos. Muestro, por tanto, código bastante simple para la validación cruzada de un modelo con R:
# genero ids
ids <- rep(1:10, length.out = nrow(cars))
# Nota: da igual si nrow(df) no es múltiplo de 10
# los aleatorizo
ids <- sample(ids)
# esto devuelve una lista de dfs:
preds.cv <- lapply(unique(ids), function(i){
preds <- predict(lm(dist ~ speed,
data = cars[ids != i,]), cars[ids == i,])
data.frame(
preds = preds,
real = cars[ids == i,]$dist)
})
# "apilo" los dfs:
preds.cv <- do.call(rbind, preds.cv)
# calculo el rmse
rmse <- sqrt(mean((preds.cv$preds - preds.cv$real)^2))
Estoy sin tiempo, así que os suelto el código y me largo a casa a no cenar. Es así:
library(parallel)
cl <- makeCluster(8)
# solo si hay aleatorización
# clusterSetRNGStream(cl, 123)
clusterEvalQ(cl,
{
# las librerías necesarias tienen que cargarse
# en cada esclavo
library(rpart)
# en la práctica, hay que cargar los datos
# (¿desde fichero?) en cada esclavo
my.data <- iris
# lo mismo con las funciones necesarias
foo <- function(x, dat){
train <- 1:nrow(dat) %% 10 != 1
mod <- rpart(Species ~ ., data = dat[train,])
res <- predict(mod, dat[!train,])
}
})
res <- parSapply(cl, 0:9,
function(x) foo(x, my.data), simplify = F)