6 nov 2019

Transformaciones de series temporales en R


Las transformaciones de series temporales en el análisis de series temporales se realizan con el objetivo de lograr mayor cumplimiento en “las suposiciones de algunas técnicas estadísticas: normalidad, linealidad, homocedasticidad, etc.” (McCune, 2002). En este hilo, la presente entrada muestra la forma de realizaar las transformaciones más frecuentes en R. Esto, usando la base de datos EuStockMarkets, disponible por default en R. Esta entrada se segmenta en diversos bloques: 1) operador de retardos y diferencias absolutas; 2) transformaciones para estabilizar la varianza; transformaciones relativas; y, 4) transformaciones para encontrar estacionariedad de las series.

1.1.  Operador de retardos

El operador de retardos (o adelantos) L, se utiliza para obtener la serie con una determinada cantidad de rezagos (o adelantos). Sea x(t) nuestra serie temporal, Lx(t)=x(t-1) (Mikusheva, 2009). La función lag en R permite obtener la serie retardada, colocándole como argumento la serie sobre la que se desea operar y la cantidad de retardos sugerida lag(serie,-nlags) con signo negativo.

# Serie en niveles x(t)

xt <- EuStockMarkets[,"DAX"]

# Serie retardada un periodo: L^1[x(t)] = x(t-1)
xt_retardo1 <- lag(xt, -1)

# Serie retardada tres periodos: L^3[x(t)] = x(t-3)
xt_retardo3 <- lag(xt, -3)

# Serie adelantada un periodo: L^-1[x(t)] = x(t+3)
xt_adelanto1 <- lag(xt, 1)

# View data
head(cbind(xt, xt_retardo1, xt_retardo3, xt_adelanto1))
Time Series:
Start = c(1991, 129)
End = c(1991, 134)
Frequency = 260
              xt xt_retardo1 xt_retardo3 xt_adelanto1
1991.492      NA          NA          NA      1628.75
1991.496 1628.75          NA          NA      1613.63
1991.500 1613.63     1628.75          NA      1606.51
1991.504 1606.51     1613.63          NA      1621.04
1991.508 1621.04     1606.51     1628.75      1618.16
1991.512 1618.16     1621.04     1613.63      1610.61

1.2.  Transformaciones para estabilizar la varianza y mejorar la normalidad

La estabilización de la varianza se alcanza mediante la transformación logarítmica, de raíz, o la de Box-Cox, transformaciones que se utilizan además para acercar la distribución de la serie al comportamiento normal. Esta es necesaria para aplicar modelos de series de tiempo como el ARIMA, ya que incluyen este supuesto en sus estimaciones. La función log permite directamente la transformación logarítmica de la serie, mientras que la transformación de Box-Cox está en función del coeficiente lambda. Para esta segunda transformación creamos una función anidada, llamada tran_box, que realiza la transformación logarítmica de la serie cuando lambda = 0 y la propuesta por Box-Cox en el resto de los casos. Luego se presenta un gráfico de serie de tiempo con las tres transformaciones.

# Transformación logarítmica
log_xt <- log(xt)

# Transformación raíz
log_xt <- sqrt(xt)

# Box Cox Transformation
library(forecast)
lamb.x <- BoxCox.lambda(xt)

tran_box <- function(xt,lambda){
  if (lamb.x == 0) {
    xt_box <- log(xt)
  } else {
    xt_box <- (xt^lamb.x - 1)/lamb.x
  }
}

xt_boxCox <- tran_box(xt, lamb.x)

data1 <- cbind(xt, log_xt, xt_boxCox)
plot(data1, col = "steelblue", lwd = 2,
     main=" ")

Verifique que la transformación logarítmica comprime el recorrido de los valores, siendo útil en caso de grandes rangos de recorrido en los valores de las series. En muchos casos, como por ejemplo las ecuaciones mancerinas donde se necesita la transformación logarítmica de seréis de ingresos o educación, se aplica la transformación log(x+1) para evitar la indefinición de log(0)

1.3.  Tasas de crecimiento y transformaciones para encontrar estacionariedad de las series

El tercer tipo de transformación usada en series temporales y presentada en esta entrada, está referida al cálculo de tasa de variación. La misma puede establecerse en términos absolutos a partir de la función diff o utilizando el operador de retardos, de forma que: diff(x) = x(t) - x(t-1).

# Diferencia absoluta diaria
Dxt <- diff(xt, lag = 1)
Dxt1 <- xt - lag(xt, -1)

# Prueba si son iguales
all(Dxt==Dxt1)
[1] TRUE

data0 <- cbind(xt, Dxt)
plot(data0, col = "steelblue", lwd = 2, main=" ")

Al generalizar el uso del operador en diferencia, modificando el valor restado en el operador de diferencia, podemos crear diferencias de otras frecuencias, siendo el operador en diferencia d igual a diff(x,d) = x(t) - x(t-d) (Newton, 1999).

# Diferencia absoluta "Mensual"
Dmxt <- diff(xt, lag = 26)
Dmxt1 <- xt - lag(xt, -26)

all(Dmxt==Dmxt1)
[1] TRUE

par(mfrow=c(1,2))
plot(Dxt, col = "steelblue", lwd = 2, main="Diferencia diaria")

plot(Dmxt1, col = "darkred", lwd = 2, main="Diferencia mensual")

Sin embargo, dado que la diferencia absoluta está en función de la escala de medición de las variables, es más común utilizar diferencias relativas: estas se pueden expresar tanto en logaritmo como en términos discretos. El siguiente ejemplo muestra como estimar una tasa de crecimiento discreta sobre una serie temporal y posteriormente se muestran ambas variables:

# Tasa de crecimiento discreta
tcXt <- (xt-lag(xt, -1))/lag(xt, -1)
tcXt1 <- diff(xt, lag = 1)/lag(xt, -1)

all(tcXt==tcXt1)
[1] TRUE

# Tasa de crecimiento en logarítmica
tclogXt <- diff(log(xt))

par(mfrow=c(2,2))
plot(xt, col = "steelblue", lwd = 2, main="Nivel")
plot(Dxt, col = "darkred", lwd = 0.5, main="Diff absoluta")
plot(tcXt, col = "orange", lwd = 0.5, main="tc discreta")
plot(tclogXt, col = "darkgreen", lwd = 0.5, main="tc continua")


La diferenciación logarítmica permite determinar el orden de integración de la serie, en el sentido de saber cuántas veces se debe repetir el proceso de diferenciación hasta que la serie se vuelve estacionaria. En tal sentido, si diferenciamos la serie una vez antes de que esta se vuelva estacionaria diremos que es integrada de orden 1 (x(t)~I(d=1)).

1.4.  Relativizaciones de series de tiempo

Antes vimos la tasa de variación relativa como forma de transformar la serie, sin embargo, existen otras estrategias para relativizar series, entre estas, las que permiten presentar series de tiempo de distintos órdenes de escala. En los próximos ejemplos se grafican distintas series en un mismo gráfico (a); y luego, (b) se hace la misma representación, pero en términos relativizado [Es recomendado ver tutorial del paquete antes de continuar dplyr avanzando].

library(dplyr) # %>%
library(tidyr) # gather
library(ggplot2)

data.frame(EuStockMarkets) %>%             # Convierte el objeto en df
  mutate(date = time(EuStockMarkets)) %>%  # recupera las fechas
  gather(id, value, -date) %>%             # Reshape base
ggplot(aes(x = date, y = value)) +         # crea el gráfico
  geom_line(aes(color = id), size = 1)+
  theme_minimal()


Nota que el segundo ejemplo utiliza la librería dplyr para realizar el ejercicio por variable (group_by(id) %>%) y posteriormente crea una variable relativizada al dividir cada valor de las series entre el primer valor observado de dicha serie (mutate(value2 = value/head(value,1))). Este parte del código crea una variable nueva llamada value2, que guarda el valor relativo de cada observación respecto al primer valor observado. Note que esta representación es sumamente útil pare representar series de diversas escalas de medición. 

data.frame(EuStockMarkets) %>%
  mutate(date = time(EuStockMarkets)) %>%
  gather(id, value, -date) %>%
  group_by(id) %>%
  mutate(value2 = value/head(value,1)) %>%
  ggplot(aes(x = date, y = value2)) +
  geom_line(aes(color = id), size = 1)+

  theme_minimal()


En la línea de código donde se creó la variable value2 pudo colocarse “= scale(value)” para obtener una normalización de las series. Esto es equivalente hacer (x-mean(x))/sd(x) para cada una de las series de forma simultaneas. Esta variable modifica la escala de cualquier variable para indicar el numero de desviaciones estándar en que se encuentra cada observación de su media.

En general, otras medidas de relativazación pueden obtenerse insertándola (separada por comas) en la función mutate, serian (McCune and Grace, 2002):

Relativización por máximo: value/max(value)
Relativización por mínimo: value/max(value)
Relativización por totales: value/sum(value)
Relativización euclidiana: value/(sum(value^2)^(1/2))
Relativización binaria: as.numeric(value>mean(value))
Variable normalizada: (value-mean(value))/sd(value)

Algunos autores plantean obtener el coeficiente de variación para cada una de las variables para poder determinar el efecto que tienen la relativización de las variables. El siguiente código muestra cómo obtener el coeficiente de variación para cada una de las variables en la data.

data.frame(EuStockMarkets) %>%
  gather(id, value) %>%
  group_by(id) %>%
  summarise("Coef. Var." = sd(value)/mean(value))

# A tibble: 4 x 2
  id    `Coef. Var.`
  <chr>        <dbl>
1 CAC          0.260
2 DAX          0.429
3 FTSE         0.274
4 SMI          0.493

1.5.  Varianza histórica

El cuadrado de la tasa de variación logarítmica suele asumirse como primer proxy de la evolución histórica de la volatilidad de las series.

var_xt <- tclogXt^2
plot(var_xt, col = "steelblue", lwd = 2, main="varianza")

Note que esta transformación corresponde a una de potencia, donde la serie transformada tx(t) = x(t)^p, por lo que, a menor valor de p mayor seria la compresión de la escala de la serie original.

# ----------
xt2 <- seq(1,10,length.out = 20)
xt2_0 <- xt2^0.75
xt2_1 <- xt2^0.5
xt2_2 <- xt2^0.1

plot(xt2, type="b", pch=18, col="red", xlab="x", ylab="y")
lines(xt2_0, pch=18, col="blue", type="b", lty=2)
lines(xt2_1, pch=18, col="steelblue", type="b", lty=2)
lines(xt2_2, pch=18, col="lightblue", type="b", lty=2)

Referencias

·         Delieutraz, P. (2008). Transformaciones estabilizadoras de la varianza para datos de experimentos de microarreglos. Universidad de Buenos Aires. Facultad de Ciencias Exactas y Naturales. Consultada 6/11/19. Disponible en: http://cms.dm.uba.ar/academico/carreras/licenciatura/tesis/delieutraz.pdf.
·         Mangiafico, S. (nd). Transforming Data. Consulted in 6/11/2019. available in: https://rcompanion.org/handbook/I_12.html.
·         McCune and Grace (2002). Ajustes de datos: transformación de datos. Consulted in 6/11/2019. available in: http://academic.uprm.edu/~jchinea/cursos/comunidades/transformacion.pdf.
·         Mikusheva, A. (2009). Stationarity, Lag Operator, ARMA, and Covariance Structure. Time Series Analysis, Fall 2007. MIT. Consulted in 6/11/2019. available in: https://ocw.mit.edu/courses/economics/14-384-time-series-analysis-fall-2013/lecture-notes/MIT14_384F13_lec1.pdf.
·         Newton, H. (1999). : Transforming Time Series. Consulted in 6/11/2019. available in: https://www.stat.tamu.edu/~jnewton/stat626/topics/topics/topic5.pdf.
·         STHDA (2017). Plot Time Series Data Using GGPlot.  Consulted in 6/11/2019. available in: http://www.sthda.com/english/articles/32-r-graphics-essentials/128-plot-time-series-data-using-ggplot/.

·       Walter, T. (2017). Time Series Analysis in R Part 2: Time Series Transformations. Consulted in 6/11/2019. available in: https://datascienceplus.com/time-series-analysis-in-r-part-2-time-series-transformations/.  

Creando variables por grupos en dplyr (group_by + mutate)

  Simulemos una base de hogares, donde se identifica el hogar, el sexo (1 mujer) y provincia y edad para cada miembro.   # Definir la lista ...