Series de tiempo

A diferencia del análisis econométrico del tipo causal, donde un conjunto de variables independientes o exógenas explican el comportamiento de una única variable dependiente o endógena, bajo el supuesto de linealidad y el cumplimiento de una serie de condiciones. El análisis de series de tiempo se centra en el estudio del comportamiento de una única variable, particularmente con propósitos predictivos o pronóstico (Cowpertwait & Metcalfe, 2009; Cryer & Chan, 2008; Racine, 2019; Woodward et al., 2017).

Además, en un modelo lineal convencional se utilizan datos de tipo corte transversal (muestra recogida en un momento del tiempo) mientras que para el análisis de series de tiempo los datos son recopilados en periodos de tiempo mucho más amplios. Así, cada elemento de una muestra corresponde a una observación tomada en un único momento del tiempo, ya sean horas, días, semanas, meses, trimestres, años, etc. De tal forma que la muestra, en su conjunto, captura el comportamiento de una variable a lo largo del tiempo.

De esta manera, si se tiene la serie de tiempo de la variable \(y_t\) donde \(t\) denota el tiempo, expresada como:

\[\large{y_1, y_2, y_3, y_4, ..., y_{t-1}, y_t}\]

La notación matemática para representar el comportamiento estimado de una serie de tiempo considerando las observaciones pasadas \(y_t\) se expresa como:

\[\large{\hat{y}^T_{t = 1} = E[Y_{T+h}|{y_t}^T_{t=1}]}\]

Por ejemplo, considere la siguiente serie de tiempo y observe su comportamiento de forma gráfica1:

dat <- read.csv("Base_Espárragos.csv", sep = ",")
head(dat)
##    Año area_cos produción precio valor        fen_niño
## 1 1993    17671     97322   1.18     2   Niño Moderado
## 2 1994    17705    131387   1.19     1      Niño débil
## 3 1995    20126    108138   1.57     6      Niña debil
## 4 1996    22582    127598   1.88     7   Niña moderado
## 5 1997    16619    144654   1.90     4 Niño muy fuerte
## 6 1998    15972    137943   2.09     3     Niño fuerte

La base de datos Base_Espárragos.csv contiene varias variables que el lector puede graficar de manera independiente, pero por ahora solo se ilustrará el comportamiento de la producción de espárragos entre los años \(1993-2019\). El lector puede acceder a la documentación de cada variable usando el comando ?nombre_de_data.

# install.packages("tidyverse")
library(tidyverse)
ggplot(data = dat, mapping = aes(x = Año, y = produción)) +
  geom_point() +
  geom_line(colour = "blue", size = 1) +
  labs(x = "AÑOS", y = "Producción", 
       title = "Producción anual de Espárragos (Tn)")

El lector debe haberse dado cuenta que la representación gráfica de las series de tiempo se realizarán en su mayoría con el paquete ggplo2 que se encuentra dentro de la librería tidyverse o puede instalarse por separado. Si el lector no se encuentra familiarizado con ggplo2 puede revisar los libros electrónicos y gratuitos de Winston Chang, Hadley Wickham y la página de ggplot2 extensions. O ir directamente a la documentación de ggplot2.

Una gráfica un poco más simple puede realizarse de la sigueinte manera

plot(dat$Año, dat$produción, xlab = "Años", ylab = "Producción", 
     main = "Producción de espárragos (Tn)", type = "l")

Una cuestión relevante en este tipo de gráficos es que la variable Año no está definida como un conjunto de fechas, por lo que podría generar inconvenientes. Además, puede ocurrir que por alguna razón solo se disponga de la base de datos y la fecha de inicio y final de la serie, pero no el vector con las fechas correspondientes a cada observación. Esto obliga a que se deba crear un vector del tipo date de forma práctica y rápida. Entonces, podemos resolver este problema de la siguiente forma:

# Solo tiene la variable Producción
Producción <- dat$produción
# La serie inicia en 1993 y es de frecuencia anual
dat2 <- ts(Producción, start = 1993, frequency = 1)
plot(dat2  , xlab = "Años", ylab = "Producción", 
     main = "Producción de espárragos (Tn)", type = "l")

En este punto, el lector debe poder distinguir la diferencia de graficar con ggplot2 y con las funciones propias de R como plot(). Y por qué es importante para el primer caso tener una variable con las fechas, mientras que en el segundo se define a la variable como una serie de tiempo. La forma más fácil de entender las diferencias es con class() y view().

Por último, si se tiene un data.frame pero no la variable con las fechas para poder realizar el gráfico con ggplo2, esta puede ser creada de la siguiente forma:

# La serie inicia inicia en 1993, es anual (12) y
# hasta 2019 hay 27 años.
Fechas <- (seq(as.Date("1993-01-01"), by = "12 months", len = 27))
class(Fechas)
## [1] "Date"
dat3 <- data.frame(Fechas, Producción)
head(dat3)
##       Fechas Producción
## 1 1993-01-01      97322
## 2 1994-01-01     131387
## 3 1995-01-01     108138
## 4 1996-01-01     127598
## 5 1997-01-01     144654
## 6 1998-01-01     137943

Análisis Clásico

Ahora bien, continuando con el análisis de la serie. La idea detrás de entender el comportamiento de una serie es poder realizar pronósticos. En este sentido, si se dispone de una serie cualquiera y se conoce una forma funcional que se ajusta o asemeja al comportamiento de la serie, se puede realizar, de alguna manera, un “pronóstico” dado que se espera que la serie mantenga su comportamiento similar a la función conocida. Sin embargo, este procedimiento resulta ser vago y no sería lo suficientemente apropiado y validado mediante alguna herramienta estadística o econométrica para realizar pronósticos. Empero, apriori este razonamiento intuitivo es suficiente para iniciarse en el análisis de series de tiempo.

Por ejemplo, tratemos de encontrar alguna forma funcional matemática conocida que se ajuste al comportamiento de la a variable Producción. Por la gráfica anterior se sabe que los valores de la producción son muy elevados generando una alta varianza, y para controlarla se puede aplicar logaritmo natural. Entonces, gráficamente:

dat3 <- data.frame(dat3[1], log(dat3[2]))
head(dat3)
##       Fechas Producción
## 1 1993-01-01   11.48578
## 2 1994-01-01   11.78590
## 3 1995-01-01   11.59116
## 4 1996-01-01   11.75664
## 5 1997-01-01   11.88210
## 6 1998-01-01   11.83460
ggplot(data = dat3, mapping = aes(x = Fechas, y = Producción)) +
  geom_point() +
  geom_line(colour = "red", size = 1) +
  labs(x = "AÑOS", y = "Producción", 
       title = "Producción anual de Espárragos (Tn)")

Como se puede observar, la serie tiene un comportamiento creciente hasta el 2011 y luego se mantiene aparentemente constante. Además, a pesar de que la serie está en logaritmos, entre 1993 y 1996 se observa un comportamiento irregular. Sin embargo, podemos intuir de la gráfica que la serie parece tener la forma de la primera mitad de una parábola invertida.

Ahora, se tratará de ajustar la serie a una función lineal del tipo \(Y = a + bX\). Es decir, con intercepto.

t <- 1:27
mod_lin <- summary(lm(dat3$Producción ~ t))
# Se observa un $R^2 = 0.91$

# creación del modelo lineal
mod_1 <- coef(mod_lin)[1] + coef(mod_lin)[2]*t
# gráfica
ggplot(data = dat3, mapping = aes(x = Fechas)) +
  geom_line(aes(y = Producción, colour = "Serie original"), size = 1) +
  geom_line(aes(y = mod_1, colour = "Modelo lineal"), size = 1) +
  labs(x = "AÑOS", y = "Producción",
       title = "Producción anual de Espárragos (Tn)") + 
  scale_color_manual("", breaks = c("Serie original", "Modelo lineal"),
                         values = c("red", "blue"))

Como se puede observar, si solo se estudia el coeficiente de determinación \(R^2 = 0.91\) se podría intuir que la serie tiene un muy buen ajuste al modelo lineal. Sin embargo, gráficamente se puede observar que aunque el modelo lineal captura la tendencia creciente al inicio de la serie, luego parece mostrar un comportamiento muy diferente a la serie original.

Ahora se realizará el mismo procedimiento pero con un modelo cuadrático y cúbico, para luego analizar cuál de estos modelo es el que mejor se ajusta a la variable Producción estableciendo como criterio de mejor ajuste al coeficiente de determinación \(R^2\).

# modelo cuadrático
t2 <- t*t
mod_cuad <- summary(lm(dat3$Producción ~ t + t2))
mod_2 <- coef(mod_cuad)[1] + coef(mod_cuad)[2]*t + coef(mod_cuad)[3]*t2

# modelo cúbico
t3 <- t*t*t
mod_cub <- summary(lm(dat3$Producción ~ t + t2 + t3))
mod_3 <- coef(mod_cub)[1] + coef(mod_cub)[2]*t + coef(mod_cub)[3]*t2 + coef(mod_cub)[4]*t3

# gráfica
ggplot(data = dat3, mapping = aes(x = Fechas)) +
  geom_line(aes(y = Producción, colour = "Serie original"), size = 1) +
  geom_line(aes(y = mod_1, colour = "Modelo lineal"), size = 1) +
  geom_line(aes(y = mod_2, colour = "Modelo cuadrático"), size = 1) +
  geom_line(aes(y = mod_3, colour = "Modelo cúbico"), size = 1) +
  labs(x = "AÑOS", y = "Producción",
       title = "Producción anual de Espárragos (Tn)") + 
  scale_color_manual("", 
      breaks = c("Serie original", "Modelo lineal",
                 "Modelo cuadrático", "Modelo cúbico"),
      values = c("red", "blue", "green", "black"))

De los resultado de la regresión se puede observar que el modelo cuadrático presenta un \(R^2 = 0.94\) mayor que el modelo linea, lo que indicaría un mejor ajuste. En el caso del modelo cúbico, se observa un \(R^2 = 0.96\) lo cual indica que es un modelo mucho mejor que el modelo lineal y el cuadrático y, por lo tanto, mejor para la predicción. Estos resultados también se corroboran de manera gráfica que refleja claramente que el modelo cúbico es el que mejor adopta el comportamiento y tendencia del la serie original. Sin embargo, ninguno de los tres modelo logra capturar el comportamiento irregular a lo largo de la serie, que es una característica relevante y particular de la variable y que debe ser considerada para realizar predicciones mucho más precisas.

Si queremos observar los errores de estimación entre la serie original y el modelo cúbico, y comprobar verificar si tiene comportamiento normal.

errores <- mod_3 - dat3$Producción

plotn <- function(x,main="Histograma de frecuencias \ny distribución normal",
                  xlab="X",ylab="Densidad") {
    min <- min(x)
    max <- max(x)
    media <- mean(x)
    dt <- sd(x)
    hist(x,freq=F,main=main,xlab=xlab,ylab=ylab)
    curve(dnorm(x,media,dt), min, max,add = T,col="blue")
}
plotn(errores,main="Distribución normal")

# Test de normalidad darque Bera
# install.packages("tseries")
library("tseries")
jarque.bera.test(errores)
## 
##  Jarque Bera Test
## 
## data:  errores
## X-squared = 0.17484, df = 2, p-value = 0.9163
# H0 : Normalidad
# Ha : No  Normalidad 
# En términos de P-Value: si p > 0.05, 0.1, 0.01 => la variable tiene
# comportamiento normal estándar al 95%, 90%  y 99% de confianza.

Bibliografía

Cowpertwait, P. S., & Metcalfe, A. V. (2009). Introductory time series with r. Springer Science & Business Media. https://b-ok.lat/book/610800/138576
Cryer, J. D., & Chan, K.-S. (2008). Time series analysis: With applications in r. Springer Science & Business Media. https://b-ok.lat/book/487366/ebfb69
Racine, J. S. (2019). Reproducible econometrics using r. Oxford University Press, USA. https://b-ok.lat/book/3717005/405a23
Woodward, W. A., Gray, H. L., & Elliott, A. C. (2017). Applied time series analysis with r. CRC press. https://b-ok.lat/book/3598439/a7de8d

  1. puede descargar la base de datos desde.↩︎