sábado, 22 de noviembre de 2014

Paralelizacion de Validacion Cruzada


Si se quiere saber qué tan eficiente es la predicción de un algoritmo, una forma es usar la tecnica de Validacion Cruzada (ver ejemplo AQUI). Esta técnica consiste en hacer varios modelos de forma iterada, usando diferentes arreglos del set de Entrenamiento y del set de Test en cada iteracion.

Cuando se tienen muchos datos, la Validación Cruzada puede tardar mucho tiempo de ejecución, y una forma de mejorar esto es paralelizando las iteraciones.

Conceptualmente seria algo como lo siguiente:





El siguiente script usa el package SNOW para paralelizar las iteraciones de una Validación Cruzada del algoritmo Random Forest.


El Script:
#Paralelizacion de Validacion Cruzada
 
# Carga libreria y tiempo de inicio
#=====================================================
tiempo_inicio  <- Sys.time()  # tiempo de inicio de ejecucion
library(snow)                 # libreria snow para paralelizar
 
 
# PARALELIZACION 
#=====================================================
 
# Definine cantidad procesadores a usar
#---------------------------------------------------
Cluster         <- makeCluster(4, type = "SOCK")  
 
# Carga los objetos a utilizar en cada procesador
#---------------------------------------------------
NoPrint  <- clusterEvalQ(Cluster, 
                       {   
                       # LIBRERIAS a usar en cada procesador ----------------- 
                       library(C50); data(churn); set.seed(3456);library(randomForest)
 
                       # DATOS a usar en cada procesador ----------------------
                       Datos         <- rbind(churnTrain,churnTest)
                       n             <- nrow(Datos)  
                       Datos         <- Datos[sample(n, n*10, replace = T),]
                       Iteraciones   <- data.frame(iteracion = NULL, acierto = NULL)
 
                       # FOLDS/GRUPOS a usar en cada procesador ---------------
                       Folds         <- 10 # Cantidad de grupos a dividir el dataset (k-fold)
                       Datos$kfold   <- sample(1:Folds, nrow(Datos), replace = T)
 
                       # FIN Asignacion objetos a procesadores
                       }) 
 
# Modelos
#---------------------------------------------------
Modelos   <- clusterApply(Cluster, c(1:10), function(i) 
  {
  Modelo  <- randomForest(churn ~ ., data=subset(Datos,!kfold == i), ntree = 30)
  }
  )
 
# FIN del proceso en paralelo
#-------------------------------------------------------------
stopCluster(Cluster) 
 
 
# PREDICCION  
#=====================================================
 
# Carga librerias y fija aleatorios
#----------------------------------------------------
library(C50); data(churn); library(randomForest); set.seed(1)
 
# Carga datos para validar el modelo
#----------------------------------------------------------
Datos                <- rbind(churnTrain,churnTest)
n                    <- nrow(Datos)  
Datos                <- Datos[sample(n, n*10, replace = T),]
 
 
# Crea tabla para guardar iteraciones y define los Folds
#----------------------------------------------------------
Iteraciones             <- data.frame(iteracion = NULL, Acierto = NULL)
Folds                   <- 10
Datos$kfold             <- sample(1:Folds, nrow(Datos), replace = T)
 
# Prediccion en cada iteracion
#----------------------------------------------------------
for (i in 1:Folds)
{
 Prediccion  <- predict(Modelos[[i]], subset(Datos, kfold == i), type = "class")
 MC          <- table( subset(Datos, kfold == i)[, "churn"], Prediccion) 
 Aciertos    <- MC[1,1]/(MC[1,1]+MC[2,1])
 Iteraciones <- rbind(Iteraciones, data.frame(iteracion = i, acierto = Aciertos))  
}
 
 
# GRAFICO
#=====================================================
promedio<-format(mean(Iteraciones$acierto, na.rm=TRUE)*100,digits = 4)
plot(Iteraciones,type="b",main="% Prediccion en Cada Iteracion",
     cex.axis=.7,cex.lab=.7,cex.main=.8, xlab="No. de Iteraciones", 
     ylab="% Prediccion")
abline(h=mean(Iteraciones$acierto),col="blue",lty = 2)
legend("topright",
       legend = paste("Eficiencia de Prediccion =",promedio,"%"),
       col = "blue", lty = 2, lwd = 1,cex=.7,bg=NULL)
Sys.time()-tiempo_inicio # Calcula tiempo total ejecucion


2 comentarios:

  1. Como podriamos ajustar el codigo para que en vez de 10 arboles se envie a cada cluster un algoritmo diferente, por ejemplo svm, ada, arboles, etc??

    ResponderEliminar
    Respuestas
    1. hola Joel.
      Fijate si el paquete hybridEnsemble te puede servir (habria que paralelizarlo):
      http://www.rdocumentation.org/packages/hybridEnsemble/functions/predict.hybridEnsemble

      suerte!

      Eliminar