Una fina, tenue, somera capa de sintaxis

Estuve el otro día en una charla de José Luis Cañadas en el grupo de usuarios de R de Madrid sobre sparklyr. Hoy en otra de Juan Luis Rivero sobre, esencialmente, lo mismo, pero esta vez con Python. Y podría escribir “etc.”. Me centraré en la de José Luis, aunque podría decir lo mismo de cualquiera de las otras. No había trabajado con sparklyr. No soy siquiera fan de dplyr (aunque no es que no se lo recomiende a otros; es simplemente, como tantas cosas, que soluciona problemas que no tengo). Pero la seguí sin mayores problemas. Lo que tenía de nuevo era una fina, somera capa de sintaxis que enlazaba fundamentos con fundamentos. ...

15 de noviembre de 2016 · Carlos J. Gil Bellosta

¿Cuánto tarda en ejecutarse este código?

Es: library(future) plan(multiprocess, workers = 4) system.time({ a1 <- future({Sys.sleep(7); 1}) a2 <- future({Sys.sleep(1); 1}) a3 <- future({Sys.sleep(1); 1}) a4 <- future({Sys.sleep(1); 1}) a5 <- future({Sys.sleep(1); 1}) a6 <- future({Sys.sleep(1); 1}) a7 <- future({Sys.sleep(1); 1}) res <- sapply(list(a1, a2, a3, a4, a5, a6, a5), value) }) Piensa antes las posibles opciones: ~8 segundos: ejecuta primero a1-a4 en 7 segundos y luego a5-a7 en un segundo adicional. ~7 segundos: ejecuta primero a1-a4, pero cuando acaban a2-a4, lanza a5-a7, que terminan antes que a1 ¿Otras? Vosotros mismos. (Pensad que si la respuesta fuese ~7 segundos, podría hacerse esto directamente con future).

11 de noviembre de 2016 · Carlos J. Gil Bellosta

R en paralelo (pero ahora, con futuros)

Esta entrada extiende y mejora una homónima de 2014. El problema de entonces consistía en calcular por separado y en paralelo objetos A, B y C para combinarlos después. Cuando, por supuesto, el cálculo de A, B y C es pesado. El muy reciente paquete future incorpora a R un mecanismo disponible en otros lenguajes de programación: un cierto tipo de datos, los futuros, que contienen promesas de valores que se calculan fuera del hilo principal del programa. Se usan, por ejemplo, para realizar llamadas a APIs, operaciones de IO o (y esto es más pertinente para usuarios de R) cálculos que llevan su tiempico. ...

4 de noviembre de 2016 · Carlos J. Gil Bellosta

Recordatorio: las VIII Jornadas de Usuarios de R

Que tendrán lugar en Albacete los días 17 y 18 de noviembre de 2016. Más información (toda la información, de hecho), aquí.

7 de octubre de 2016 · Carlos J. Gil Bellosta

Barómetros del CIS con R

El CIS realiza barómetros todos los meses menos uno. Pasado un tiempo (es octubre y el último publicado es de julio) coloca los microdatos en su banco de datos. Aparte de ficheros .pdf que lo explican todo (pero que no dejan de ser .pdf), publica dos ficheros. Uno de datos en ancho fijo (prefijo DA) y otro con código SPSS (prefijo ES) con los consabidos (¿lo son? ¡felicidades si no!) encabezados DATA LIST, VARIABLE LABELS, VALUE LABELS, y MISSING VALUES. ...

5 de octubre de 2016 · Carlos J. Gil Bellosta

Votos en la ONU con R

Inspirado por esto he generado usando library(unvotes) library(reshape2) library(gplots) dat <- un_votes levels(dat$vote) <- c("0", "-1", "1") dat$vote <- as.numeric(as.character(dat$vote)) dat <- dcast(dat, rcid ~ country, value.var = "vote") dat$rcid <- NULL dat <- as.matrix(dat) res <- cov(dat, use = "pairwise.complete.obs") heatmap(res) Se me olvidaba: el gráfico se refiere a los votos de los distintos países en la ONU. Tal vez alguien quiera poner la lupa en algún país concreto. O explorar esos grupos de países que se ven tan bien avenidos. O, usando otros conjuntos de datos alternativos contenidos en el paquete unvotes, hacer un estudio por años o por temas concretos. O… ...

21 de septiembre de 2016 · Carlos J. Gil Bellosta

Un curso de 15 horas de introducción a la programación

Hoy comienzo a enseñar un curso de introducción a la programación para recién graduados que comenzarán un máster de matemáticas aplicadas con incursiones en la llamada ciencia de datos. Serán 4 sesiones con el siguiente contenido: Sesión 1, programación imperativa: variables, condicionales y bucles. Sesión 2, programación orientada a objetos. Sesión 3, colecciones: listas, tuplas, conjuntos, diccionarios, etc. Sesión 4, programación funcional: map, reduce, fold, foldLeft, scan, filter, etc. Los lenguajes a utilizar serán R y Python (via Jupyter). No me he atrevido a añadir Scala (como ejemplo de cómo deben hacerse las cosas, además de ser un lenguaje, para variar, tipado y no interpretado) por falta de tiempo. ...

19 de septiembre de 2016 · Carlos J. Gil Bellosta

Selección de variables con bosques aleatorios

Desde el principio de mis tiempos he seleccionado variables relevantes como subproducto de los árboles primero y de los bosques aleatorios después. Cierto que he hecho casi inconfesables incursiones en los métodos stepwise, pero han sido marginales y anecdóticas. La idea es casi siempre la misma, se haga a mano o con ayuda de paquetes ad hoc: las variables importantes tienden a aparecer en el modelo (o submodelos), las otras no. Todo se reduce a contar y ponderar. Hay que discurrir un poco más cuando se sospecha (o consta) que existen variables altamente correlacionadas. ...

6 de septiembre de 2016 · Carlos J. Gil Bellosta

Tod[rep('a', 831)]s y tod[rep('o', 6450)]s los autores de paquetes de R

En los últimos tiempos se ha puesto de moda un subgénero periodístico que es una manera de generar artículos de acuerdo con el siguiente algoritmo: Se toma una lista de personas. Se cuenta en ella el número de mujeres (a) y de hombres (b). Si a >= b, GOTO 1; si no, se copipega y se mutatismutandea un manido argumento. No sabiéndome sustraer al encanto del último grito, he escrito y corrido ...

31 de agosto de 2016 · Carlos J. Gil Bellosta

La Consejería de Empleo de la Función General de la Comunidad Autónoma de Ordenación Provincia de la Audiencia Profesional

Ese es el nombre agramatical de una nueva consejería pergeñada por una red neuronal recurrente que he ajustado usando un año de BOEs. El código, adaptado de aquí y sustancialmente mejorado, es library(mxnet) batch.size <- 32 seq.len <- 64 num.hidden <- 128 num.embed <- 8 num.lstm.layer <- 1 num.round <- 1 learning.rate <- 0.1 wd <- 0.00001 clip_gradient <- 1 update.period <- 1 make.data <- function(dir.boe, seq.len = 32, max.vocab=10000, dic = NULL) { text <- lapply(dir(dir.boe), readLines) text <- lapply(text, paste, collapse = "\n") text <- paste(text, collapse = "\n") char.lst <- strsplit(text, '')[[1]] chars <- unique(char.lst) num.seq <- floor(length(char.lst) / seq.len) char.lst <- char.lst[1:(num.seq * seq.len)] data <- matrix(match(char.lst, chars) - 1, seq.len, num.seq) dic <- as.list(1:length(chars)) names(dic) <- chars lookup.table <- as.list(chars) return (list(data = data, dic = dic, lookup.table = lookup.table)) } ret <- make.data(".", seq.len=seq.len) X <- ret$data dic <- ret$dic lookup.table <- ret$lookup.table vocab <- length(dic) train.val.fraction <- 0.9 train.cols <- floor(ncol(X) * train.val.fraction) drop.tail <- function(x, batch.size) { nstep <- floor(ncol(x) / batch.size) x[, 1:(nstep * batch.size)] } get.label <- function(X) matrix(c(X[-1], X[1]), nrow(X), ncol(X)) X.train.data <- X[, 1:train.cols] X.train.data <- drop.tail(X.train.data, batch.size) X.train.label <- get.label(X.train.data) X.train <- list(data=X.train.data, label=X.train.label) X.val.data <- X[, -(1:train.cols)] X.val.data <- drop.tail(X.val.data, batch.size) X.val.label <- get.label(X.val.data) X.val <- list(data=X.val.data, label=X.val.label) model <- mx.lstm(X.train, X.val, ctx=mx.cpu(), num.round=num.round, update.period=update.period, num.lstm.layer=num.lstm.layer, seq.len=seq.len, num.hidden=num.hidden, num.embed=num.embed, num.label=vocab, batch.size=batch.size, input.size=vocab, initializer=mx.init.uniform(0.1), learning.rate=learning.rate, wd=wd, clip_gradient=clip_gradient) get.sample <- function(n, start = "<", random.sample = TRUE){ make.output <- function(prob, sample = FALSE) { prob <- as.numeric(as.array(prob)) if (!sample) return(which.max(as.array(prob))) sample(1:length(prob), 1, prob = prob^2) } infer.model <- mx.lstm.inference( num.lstm.layer=num.lstm.layer, input.size=vocab, num.hidden=num.hidden, num.embed=num.embed, num.label=vocab, arg.params=model$arg.params, ctx=mx.cpu()) out <- start last.id <- dic[[start]] for (i in 1:(n-1)) { ret <- mx.lstm.forward(infer.model, last.id - 1, FALSE) infer.model <- ret$model last.id <- make.output(ret$prob, random.sample) out <- paste0(out, lookup.table[[last.id]]) } out } cat(get.sample(1000, start = "A", random.sample = T)) Lo anterior genera cosas tales como: ...

29 de agosto de 2016 · Carlos J. Gil Bellosta