Nuevos comentarios sobre RevoScaleR

El reto lanzado por Revolution Analytics a SAS está relacionado con el lanzamiento por parte de la primera empresa de un paquete, RevoScaleR, diseñado para permitir el análisis de conjuntos de datos grandes. La lectura más detallada de uno de los pocos documentos técnicos que circulan sobre el paquete me invita a compartir con mis lectores mis impresiones más allá de las primeras y más someras que realicé hace unos días.

La primera es que sigo sin entender claramente cómo es y cómo funciona el nuevo formato de almacenamiento de tablas, XDF. Al menos, no es público. Aunque es un tema de investigación candente (de lo que son prueba esto, esto, esto o el mismo paquete ff de R), no está claro si reaprovecha desarrollos previos o si es una implementación desde cero.

La segunda impresión es que el nuevo paquete utiliza una notación muy SAS:

    # Create function to transform data
    myTransforms <- function(data){
           data$Late    <- data$ArrDelay > 15
           data$DepHour <- as.integer(data$CRSDepTime)
           data$Night   <- data$DepHour >= 20 | data$DepHour <= 5
           return(data)
    }

    # The rxDataStepXdf function read the existing data set, performs the
    # transformations, and creates a new data set.
    rxDataStepXdf(outData="ADS2",
                  inData=dataName,
                  transformFunc=myTransforms,
                  varsToKeep=c("ArrDelay","CRSDepTime","DepTime"))

    rxShowInfoXdf("ADS2", numRows=5)
    # Run a logistic regression using the new variables
    logitObj <- rxLogit(Late~DepHour+Night, data="ADS2", verbose=TRUE)

Pensé en un primer momento que podía ser intencional y buscando facilitar la migración de un sistema a otro. Luego, preguntándome a mí mismo qué tipo de interfaz hubiese usado yo para implementar algo parecido, no se me ocurrió nada radicalmente distinto: al tener la información en disco, los ficheros de datos se leen y se escriben: ya no se cargan en memoria. Por lo tanto, es necesario especificar fuentes y destinos de datos, qué transformaciones realizar sobre ellos, etc. Sin embargo, el nombre de la función rxDataStepXdf() sí resulta sumamente revelador.

La tercera, es que hay algo en los experimentos que describe el artículo que huele a chamusquina. Se trata de un análisis para comprobar el rendimiento del paquete a la hora de realizar una regresión sobre un conjunto de datos con 123M de filas y 29 columnas y que ocupa 13GB en disco. El estudio lo realizan con un portátil con 3GB de RAM (también con un servidor, pero eso no nos preocupa en esta entrada). Los tiempos que obtienen son:

¡Curioso! En la segunda y posteriores ejecuciones, el tiempo de proceso desciende a 4 segundos desde los casi 40 de la primera. ¿Motivo? Dizque las cachés. Y yo me pregunto, ¿cómo pueden cachear 13GB con 3GB de RAM? De ser por las cachés, la mejora en tiempos sólo podría explicarse si el fichero original ocupase menos de 3GB. ¿Será que los 13GB de fichero inicial realmente ocupan muchísimo menos (incluso menos de 3GB) en formato XDF? Porque tampoco es creíble que un portátil lea 13GB en 40 segundos. Ni mi portátil ni el de nadie. Según la Wikipedia, no cabe esperar velocidades de lectura superiores a 1000Mbits por segundo; es decir, nunca más de 125MB por segundo. Únicamente leer 13GB a esta velocidad requeriría algo más de 100 segundos.

Al autor de esta entrada se le escapa algo de lo que cuenta el artículo.

Una última salvedad: sólo R (con el paquete RevoScaleR) puede leer y generar ficheros de tipo XDF. Entonces, ¿cómo generarlos? Porque si, por ejemplo, alguien te hace llegar un fichero de texto enorme, antes de poder cargarlo con R tienes que pasarlo a formato XDF. Pero para pasarlo a XDF tienes que haberlo cargado antes en R. Etc. De nuevo, ¿me pierdo algo?

¡Quién sabe si Revolution Analytics estará usando mi paquete colbycol (a propósito, ¿lo conocéis? ¿lo habéis probado?) para realizar la primera lectura!