R en Nada Es Gratis

R

Jesús Fernández Villaverde escribió en Nada es Gratis sobre R el otro día. Publicó cuatro vídeos:

Todos muy interesantes.

Pero todavía lo es más que desde unas páginas del impacto de Nada es Gratis tengan a bien contribuir al conocimiento (¡y al uso!) de R.

Componentes conexas (de grafos) en Spark

Uno de mis últimos pet projects tiene que ver con el análisis de las componentes conexas de unos grafos muy grandes. Como aquí pero con datos de un tamaño muchos órdenes de magnitud mayores. Usando Spark, claro. Y ya que lo cito, aprovecho la ocasión para regalar un consejo a mis lectores más jóvenes: no esperéis a los cuarenta para aprender Scala y Spark.

Voy a limitarme a copiar el código para referencia mía y de otros. Creo que se autoexplica:

Bajo el capó del particionamiento recursivo basado en modelos

Una de las mayores contrariedades de estar sentado cerca de alguien que es más matemático que un servidor (de Vds., no de silicio) es que oye siempre preguntar por qué. Una letanía de preguntas me condujo a leer papelotes que ahora resumo.

Primero, unos datos:

set.seed(1234)

n <- 100

x1 <- rnorm(n)
x2 <- rnorm(n)
x3 <- rnorm(n)

y <- 0.3 + 0.2 * x1 + 0.5 * (x2 > 0) + 0.2 * rnorm(n)

Luego, un modelo:

modelo <- lm(y ~ x1)
summary(modelo)

# Call:
#   lm(formula = y ~ x1)
#
# Residuals:
#   Min      1Q  Median      3Q     Max
# -0.9403 -0.2621  0.0420  0.2299  0.6877
#
# Coefficients:
#   Estimate Std. Error t value Pr(>|t|)
# (Intercept)  0.55632    0.03364  16.538  < 2e-16 ***
#   x1           0.21876    0.03325   6.579 2.34e-09 ***
#   ---
#   Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
# Residual standard error: 0.3323 on 98 degrees of freedom
# Multiple R-squared:  0.3063,  Adjusted R-squared:  0.2992
# F-statistic: 43.28 on 1 and 98 DF,  p-value: 2.341e-09

Pocos que no entiendan cómo se han generado los datos advertirían lo malo de su especificación: hemos omitido una variable explicativa cuyo efecto ha ido a incrementar el error de manera que los tests habituales de bondad de ajuste no advierten.

Missing

Dos motivos me han tenido missing estas últimas semanas. Uno es una estancia en la Universidad de Santa Catalina del Burgo de Osma. Oportunamente ubicada en las estribaciones de la muy generosa en caldos de calidad Ribera del Duero, ha sido reconvertida a la sazón en un hotel propicio para la evasión y la agrafía.

vim_package

El segundo es que en horas intempestivas he estado purgando de missings unas matrices enormes y de la, se conoce, mayor trascendencia. Es un asunto delicado, jamás bien resuelto, para el que el paquete [VIM](http://cran.r-project.org/web/packages/VIM/index.html) puede proporcionar ayuda. Sobre todo en los aspectos gráficos.

Modelos, mascotas y rebaños en el DataBeers de Madrid

El próximo día 18 de septiembre hablaré de modelos, mascotas y rebaños en el DataBeers de Madrid.

Los detalles (incluido el enlace para registrarse) están disponibles aquí.

Haréis mal en faltar porque, con la excepción de un servidor, el resto del cartel es de primera:

Factorización de enteros con grid

Vi esto y me dije: yo también quiero. Así que dicho y hecho:

100

Por si acaso, cada diagrama representa la descomposición en números primos de un número del 1 al 100.

El código (que no he adecentado lo que suelo) es un pequeño ejercicio con el paquete grid y unos elementos de recursividad (como en Grid, Scala y arbolitos fractales):

library(grid)
library(gmp)

plot.factors <- function(n, new.plot = TRUE){

  if(new.plot)
    grid.newpage()

  divisors <- sort(as.integer(factorize(n)), decreasing = T)

  foo <- function(divs){
    if(length(divs) == 0){
      grid.circle(x = 0.5, y = 0.5, r = 0.5,
                  gp=gpar(fill="black"))
      return()
    }

    n <- divs[1]

    x <- (Re(exp( 2 * pi *(1:n) * 1i /n))) / 4 + 0.5
    y <- (Im(exp( 2 * pi *(1:n) * 1i /n))) / 4 + 0.5

    for(i in 1:n){
      tmp <- viewport(x = x[i], y = y[i],
                      w = 2/(3 + n), h = 2/(3 + n))
      pushViewport(tmp)
      #grid.rect(gp = gpar(col = "grey"))
      foo(divs[-1])
      popViewport()
    }
  }

  foo(divisors)
}

plot.factors(25)


grid.newpage()

nrow <- 10
ncol <- 10

for(y in 1:nrow){
  for(x in 1:ncol){
    tmp <- viewport(x = x / (1 + ncol), y = 1 - y / (1 + nrow),
                    w = 1/(1 + ncol), h = 1/(1+ncol))
    pushViewport(tmp)
    #grid.rect(gp = gpar(col = "grey"))
    plot.factors(x + y * ncol - ncol, new.plot = FALSE)
    popViewport()
  }
}

Tres citas para los amantes del análisis de datos públicos

En estos días van a celebrarse tres eventos (de los que tengo noticia) relacionados con el análisis de datos. El primero es la Segunda Edición del Taller de Periodismo de Datos, en Madrid. Extraigo de su convocatoria lo siguiente:

Durante dos fines de semana largos (octubre 24-26 y diciembre 12-14 desarrollaremos proyectos para seguir la traza del dinero público con la ayuda de expertos tales como Ben Welsh (Los Angeles Times), Mariano Zafra (El País), Juan Elosúa (España en Llamas) y el equipo de periodismo de datos de El Confidencial.

Mascotas y rebaños

Muchos cuidamos de nuestro ordenador casi como una mascota: le ponemos un nombre (a menudo escribo desde tiramisu), le hacemos algo de mantenimiento, etc. Hay quienes, incluso, decoran sus máquinas con pegatinas.

Pero llega un momento en que hay que comenzar a tratar a las máquinas no tanto como mascotas sino como rebaños. Desde una pantalla aneja a esta en la que escribo estoy manejando un clúster de más de 200 GB y 50 núcleos distribuido en varias máquinas que ni sé dónde están. Además, solo espero que crezca. Ya no cuido de una mascota; cuido de un rebaño.

(Mis) procesos puntuales con glm

Lo que escribí hace un par de días sobre procesos puntuales, ahora me doy cuenta, podía haberse resuelto con nuestro viejo amigo glm.

Ejecuto el código del otro día y obtengo (para un caso nuevo)

          mu       alfa verosimilitud delta
    1  0.4493158 0.50000000      340.6141     1
    2  0.2675349 0.40457418      307.3939     2
    3  0.1894562 0.28917407      293.4696     3
    4  0.1495654 0.22237707      287.0784     4
    5  0.1243791 0.18079703      281.3900     5
    6  0.1142837 0.14913172      284.9227     6
    7  0.1217504 0.12150745      288.5448     7
    8  0.1214365 0.10424818      289.3282     8
    9  0.1204605 0.09148817      290.9081     9
    10 0.1315896 0.07857330      295.3935    10</code>

que significa que el parámetro óptimo es delta = 5, mu = 0.124 y alfa = 0.18.

Ahora hago

    cuantos.previos <- function(i, muestra, delta){
      indices <- Filter(function(x) x < i & x > i - delta, 1:n)
      cuantos <- sum(muestra[indices])
    }

    fit.glm <- function(delta){
      prev <- sapply(1:length(muestra),
                     cuantos.previos, muestra, delta)
      dat  <- data.frame(muestra = muestra, prev = prev)

      res.glm <- glm(muestra ~ prev, data = dat,
                     family = poisson(link = "identity"))
      c(delta, res.glm$coefficients, summary(res.glm)$aic)
    }

    res.glm <- sapply(1:10, fit.glm)
    res.glm <- as.data.frame(t(res.glm))
    colnames(res.glm) <- c("delta", "mu", "alfa", "aic")

y obtengo

¿Tienen sentido las tasas municipales de desempleo?

Sigo los artículos de periodismo de datos de El Confidencial. Los recomiendo, de hecho. Es bueno que alguien se encargue de divulgar noticias que tienen que ver con números.

Y ahora llega el pero. Una parte —y sus autores la consideran importante porque la elevan al titular— de lo que se discute en Nueve de cada diez municipios tienen más paro ahora que antes de comenzar la crisis es amarillismo numérico. Que quiero pensar que involuntario. El nivel municipal, y más habida cuenta del micromunicipalismo español, es demasiado fino para capturar algo que no sea ruido.