lunes, 10 de noviembre de 2014

Paralelizar una Optimizacion de K-Means

Si se quiere comparar las diferentes variaciones de k-means para luego usar el mejor (ver ejemplo con detalle publicado AQUI) , es posible que el tiempo de ejecución sea muy alto si existen muchos datos. Una de las causas de esto es que R no hace ejecución en paralelo por defecto.

Una forma de mejorar los tiempos de ejecución es "Paralelizando los Procesos", donde se asigna a cada núcleo del procesador una tarea distinta y luego se unen los diferentes resultado de cada proceso.

El siguiente script paraleliza 4 ejecuciones de k-means que corresponden a sus 4 variaciones (Hartigan-Wong, Lloyd, Forgy y MacQueen). Si se ejecuta este proceso sin paralelizar en un procesador i7, el tiempo aproximado es de 1 minuto. Luego de paralelizar, se el tiempo de ejecución es de 5 segundos.


#--------------------------------------------------------------------------------
# PASO 1: Inicio y fin de Paralelizacion de procesos
tiempo_inicio<-Sys.time() # guarda tiempo de inicio de ejecucion
suppressMessages(library(snow) )       # carga libreria snow que para paralelizar
Cluster  <- makeCluster(3,type="SOCK") # inicia clusterizacion de CPU
NoImprir <- clusterEvalQ(Cluster, 
   {  # Carga package en cada cluster del CPU
    suppressMessages(library(C50)); data(churn); 
     datos <- churnTrain[,6:19]  # Crea data.frame en cada cluster del CPU
   })
# Ejecuta los 4 algoritmos de kmean distribuidos entre los cluster
Modelos   <- clusterApply(Cluster,c("Hartigan-Wong","Lloyd","Forgy","MacQueen"),
                    function(algoritmo)
                      kmeans(datos,
                                  centers     =    3, 
                                  iter.max    =  100, 
                                  nstart      =  100, 
                                  algorithm   =  algoritmo))
stopCluster(Cluster) # fin del proceso en paralelo
 
 
#--------------------------------------------------------------------------------
#  PASO 2: Crea tabla de "Iteraciones" con resultados de cada algoritmo
Iteraciones  <- data.frame(Intraclase=NULL,Algoritmo=NULL)
algoritmo    <- c("Hartigan-Wong","Lloyd","Forgy","MacQueen")
for (i in 1:4)
    {
    Iteraciones<-rbind(Iteraciones,
                       data.frame(Intraclase = Modelos[[i]]$betweenss,
                                  Algoritmo  = algoritmo[i]))
    }
 
#------------------------------------------------------------------------------
#  PASO 3: Identifica algoritmo con mejor resultado
Iteraciones      <- Iteraciones[order(Iteraciones$Intraclase),] 
Resultados       <- tapply(Iteraciones$Intraclase,Iteraciones$Algoritmo,mean)
Resultados       <- sort(Resultados,decreasing = T)
AlgoritmoGanador <- names(Resultados[1])
 
 
#-------------------------------------------------------------------------------
#  PASO 4: Ejecuta kmeans con algoritmo ganador
library(C50); data(churn);
datos  <- churnTrain[,6:19]
 
KmeansOptimizado <- kmeans(datos,
                        centers      =  3, 
                        iter.max     =  100, 
                        nstart       =  100, 
                        algorithm    =   AlgoritmoGanador)
datos$Grupo      <- KmeansOptimizado$cluster
 
 
#-----------------------------------------------------------------------------
#  PASO 5: crea Analisis de Componenetes principales para graficar Kmeans
ACP<-prcomp(datos)
DatosGrafico  <- data.frame(Componente_1=ACP$x[,1],
                         Componente_2=ACP$x[,2],
                         Grupos=datos$Grupo)
 
 
#-----------------------------------------------------------------------------
#  PASO 6: Crear graficon algoritmo ganador
plot(DatosGrafico[,1:2],col=DatosGrafico[,3])
title(main=paste("Algoritmo ganador:",AlgoritmoGanador),cex.main=.9)
 
tiempo_fin <- Sys.time()     # guarda tiempo de fin de ejecucion
tiempo_fin-tiempo_inicio     # calcula duracion total de procesos






Referencia:
https://www.youtube.com/watch?v=-JqwQ5OW-2w
http://hernanresnizky.com/2014/01/10/quick-guide-to-parallel-r-with-snow/
http://www.glennklockwood.com/di/R-para.php
http://cran.r-project.org/web/views/HighPerformanceComputing.html

1 comentario:

  1. Hola Enmanuel genial trabajo, se que parece evidente pero:

    como sería para usar el codigo con un dataframe cargado de un csv?

    Gracias

    ResponderEliminar