Paquetes

Análisis y predicción de series temporales intermitentes

Hace tiempo me tocó analizar unas series temporales bastante particulares. Representaban la demanda diaria de determinados productos y cada día esta podía ser de un determinado número de kilos. Pero muchas de las series eran esporádicas: la mayoría de los días la demanda era cero.

Eran casos de las llamadas series temporales intermitentes.

Supongo que hay muchas maneras de modelizarlas y, así, al vuelo, se me ocurre pensar en algo similar a los modelos con inflación de ceros. Es decir, modelar la demanda como una mixtura de dos distribuciones, una, igual a 0 y otra >0, de manera que la probabilidad de la mixtura, $latex p_t$, dependa del tiempo y otras variables de interés.

DLMs

O Distributed Lag Models (véase, por ejemplo, dLagM).

Son modelos para estimar el impacto de una serie temporal sobre otra en situaciones como la siguientes:

  • Una serie mide excesos de temperaturas (en verano).
  • La otra, defunciones.

Existe un efecto causal (débil, pero medible) de la primera sobre la segunda. Pero las defunciones no ocurren el día mismo en que ocurren los excesos de temperaturas, sino que suelen demorarse unos cuantos días.

ranger (o cómo el truco para hacerlo rápido es hacerlo, subrepticiamente, mal)

ranger llegó para hacerlo mismo que [randomForest](https://cran.r-project.org/package=randomForest), solo que más deprisa y usando menos memoria.

Lo que no nos contaron es que lo consiguió haciendo trampas. En particular, en el tratamiento de las variables categóricas. Si no andas con cuidado, las considera ordenadas (y ordenadas alfabéticamente).

[Si te da igual ocho que ochenta, no te preocupará el asunto. Tranquilo: hay muchos como tú.]

El diagnóstico dado (por eso lo omito) está contado aquí. La solución, a pesar de la aparente pretensión de los autores, no.

Cartogramas con recmap

R

He construido

que, obviamente no es la gran maravilla, basándome en Rectangular Statistical Cartograms in R: The recmap Package y usando

library(rgdal)
library(pxR)
library(recmap)

provs <- readOGR(dsn = "provincias/",
    layer = "Provincias")

pobl <- as.data.frame(read.px("2852.px",
    encoding = "latin1"), use.codes = T)
pobl2 <- as.data.frame(read.px("2852.px",
    encoding = "latin1"))

pobl$nombre <- pobl2$Provincias

pobl <- pobl[, c("Provincias", "nombre", "value")]
colnames(pobl) <- c("COD_PROV", "nombre", "poblacion")
pobl <- pobl[pobl$COD_PROV != "null",]

pobl <- pobl[!pobl$COD_PROV %in%
    c("51", "52", "38", "07", "35"),]


dat <- merge(provs, pobl,
    by = "COD_PROV", all.x = FALSE)
dat@data$NOM_PROV <- NULL
dat$z <- dat$poblacion

tmp <- as.recmap(dat)

tmp$name <- dat@data$nombre
tmp$ccaa <- dat@data$COD_CCAA

res <- recmapGA(tmp, popSize = 300,
    maxiter = 30, run = 10)

cartogram <- res$Cartogram

ccaa <- tmp[, c("name", "ccaa")]
ccaa$ccaa <- as.numeric(factor(ccaa$ccaa))
cartogram <- merge(cartogram, ccaa)

plot.recmap(cartogram, col.text = "black",
    main = "cartograma -- población\n  españa peninsular",
    col = cartogram$ccaa)

Como los datos los he bajado de por ahí y no recuerdo dónde, dejo como referencia el objeto arriba llamado tmp aquí.

1 3 6 19 30 34 2 7 18 31 33 16 9 27 22 14 11 25 24 12 13 23 26 10 15 21 28 8 17 32 4 5 20 29 35

R

Son los enteros del 1 al 35 ordenados de forma que dos consecutivos en la serie suman un cuadrado perfecto. Los he obtenido así:

library(adagio)

foo <- function(n){
    desde <- 1:n
    hasta <- 1:n
    todos <- expand.grid(desde, hasta)
    todos <- todos[todos$Var1 < todos$Var2,]
    todos$sqrt <- sqrt(todos$Var1 + todos$Var2)
    todos <- todos[todos$sqrt == round(todos$sqrt),]
    todos$sqrt <- NULL
    vertices <- as.vector(t(todos))
    hamiltonian(vertices)
}

foo(35)

Notas:

  • Esta entrada está inspirada en algo que he visto en Twitter (pero cuya referencia he olvidado guardar).
  • Puedes probar con otros números, aunque no siempre existe un ciclo hamiltoniano.

¿Qué puede colgar de un árbol?

R

Predicciones puntuales:

O (sub)modelos:

Y parece que ahora también distribuciones:

Notas:

  • Obviamente, la clasificación anterior no es mutuamente excluyente.
  • La tercera gráfica está extraída de Transformation Forests, un artículo donde se describe el paquete trtf de R.
  • Los autores dicen que [r]egression models for supervised learning problems with a continuous target are commonly understood as models for the conditional mean of the target given predictors. ¿Vosotros lo hacéis así? Yo no, pero ¡hay tanta gente rara en el mundo!
  • Y añaden que [a] more general understanding of regression models as models for conditional distributions allows much broader inference from such models. Que era lo que creía que todos hacíamos. Menos, tal vez, algún rarito.

Elecciones e índice (supernaíf) de Shapley

Aprovechando que el paquete GameTheoryAllocation ha emergido de mi FIFO de pendientes a los pocos días de conocerse los resultados de las [adjetivo superlativizado omitidísimo] elecciones generales, voy a calcular de la manera más naíf que se me ocurre el índice de Shapley de los distintos partidos. Que es:

Al menos, de acuerdo con el siguiente código:

library(GameTheoryAllocation)

partidos <- c(123, 66, 57, 35, 24, 15, 7, 7,
              6, 4, 2, 2, 1, 1)
names(partidos) <- c("psoe", "pp", "cs", "iu",
                      "vox", "erc", "epc", "ciu",
                      "pnv", "hb", "cc", "na",
                      "compr", "prc")

coaliciones <- coalitions(length(partidos))
tmp <- coaliciones$Binary

profit <- tmp %*% partidos
profit <- 1 * (profit > 175)

res <- Shapley_value(profit, game = "profit")

res <- as.vector(res)
names(res) <- names(partidos)
res <- rev(res)

dotchart(res, labels = names(res),
          main = "naive shapley index \n elecciones 2019")

Lo del índice de Shapley, de ignorarlo, lo tendréis que consultar por vuestra cuenta. Al menos, para saber por qué no debería usarse tan frecuentemente (en problemas de atribución, entre otros).

Simulación de procesos de Poisson no homogéneos y autoexcitados

Fueron mis modelos favoritos un tiempo, cuando modelaba visitas y revisitas de usuarios a cierto malhadado portal.

Si las visitas fuesen aleatorias (en cierto sentido), tendrían un aspecto no muy distinto del que se obtiene haciendo

library(IHSEP)

suppressWarnings(set.seed(exp(pi * complex(imaginary = 1))))

tms <- simPois(int = function(x) .1, cens = 1000)
hist(tms, breaks = 100, main = "Proceso homogéneo de Poisson",
      xlab = "", ylab = "frecuencia")

Es decir,

o bien una distribución uniforme en el tiempo. Pero bien puede ocurrir que una visita incremente la probabilidad de otra inmediatamente después, por lo que las visitas tenderían a arracimarse en determinados momentos. Con el paquete [IHSEP](https://cran.r-project.org/package=IHSEP) de R pueden simularse (y ajustarse) este tipo de modelos. Por ejemplo,

Análisis (clasificación, etc.) de textos muy cortos

Nlp, R

Uno de mis proyectos permanentemente pospuestos es el del análisis de textos muy cortos. Se citarán Twitter y similares, aunque el € está en otros sitios, como los mensajes asociados a transferencias bancarias, reseñas o keywords.

Pero parece que no soy el único interesado en el tema. Otros con más tiempo y talento han desarrollado BTM, que parece ser una versión modificada de LDA para el análisis de textos cortos.

El artículo en el que está basado el paquete también es una buena referencia de técnicas y trucos cuando toca analizar este tipo de conjuntos de datos.

vecpart: modelización de moderadores con árboles

En un GLM (aún más generalizado que la G de las siglas) puede haber coeficientes moderados. Usando una terminología muy ad hoc, en el modelo pueden entrar predictores y moderadores. Lo cual quiere decir que la parte lineal puede ser de la forma

$$\sum_i X_i \beta_i(Z_i),$$

donde las $latex X_i$ son los predictores propiamente dichos y las variables $latex Z_i$ son moderadoras, es decir, que modifican el efecto de los predictores a través de una función arbitraria $latex \beta_i$.

Una cosa buena, una cosa mala

Que son la misma: esta.

Comienzo por lo malo: ¿realmente necesitamos 17+1 INEs publicando la vistas de la misma información a través de 17+1 APIs, 17+1 paquetes de R y (17+1)*N mantenedores y desarrolladores?

Lo bueno: tiene buena pinta y es encomiable tanto el esfuerzo de los autores como su vocación de servicio público.

Nota: Espero que no enfaden demasiado el 50% de los juicios que he emitido a quien me ha enviado el enlace para su evaluación y posible difusión. Sepa que lo tengo en grande estima y que me consta responsable de mucho de la parte buena y casi nada de la mala.

Demasiados colores (para el hijo de un daltónico)

R

Mi padre me enseñó muchas cosas (leer, sumar, etc.). Pero mi infancia fue monocromática porque era daltónico. Siempre dibujé con lápiz (primero) y tinta (después). Las témperas y los rotuladores fueron mi tormento.

R tiene colores. Un montón. Y paletas de colores. Demasiadas. Una búsqueda entre los paquetes disponibles actualmente en CRAN de color proporciona 88 coincidencias, a las que deben sumarse las 35 adicionales de colour. Algunos de esos paquetes se refieren a asuntos tales como “Optimal Block Designs for Two-Colour cDNA Microarray Experiments”, pero los más ofrecen cosas tales como: