R

Detrás de la detección de anomalías en series temporales

Por azares, me ha tocado lidiar con eso de la detección de anomalías. Que es un problema que tiene que ver con dónde colocar las marcas azules en

anomaly_detection

El anterior es el gráfico construido con los datos de ejemplo del paquete AnomalyDetection. De hecho, así:

library(AnomalyDetection)

data(raw_data)
res <- AnomalyDetectionTs(raw_data,
    max_anoms=0.02,
    direction='both', plot=TRUE)
res$plot

Aparentemente, AnomalyDetectionTs hace lo que cabría sospechar. Primero, una descomposición de la serie temporal, tal como

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.”.

evolucion_convergente

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.

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

R

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.

R en paralelo (pero ahora, con futuros)

R

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.

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.

Votos en la ONU con R

Inspirado por esto he generado

votos_onu

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…

Selección de variables con bosques aleatorios

R

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.

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

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:

  1. Se toma una lista de personas.
  2. Se cuenta en ella el número de mujeres (a) y de hombres (b).
  3. 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

Rápido y frugal: una digresión en la dirección inhabitual

Siempre (aténganse los puristas al contexto) recomiendo comenzar con un árbol de decisión para, sobre esa base, ensayar métodos más potentes. Sobre todo si la precisión conviene más que la interpretabilidad.

En la dirección opuesta se sitúan los árboles rápidos y frugales. Un árbol rápido y frugal es un tipo de árbol de decisión tal como

fast_frugal_tree

La restricción que satisface (a diferencia de los árboles de decisión más habituales) es que: