Analisis de series de tiempo

El motivo de la introducción de los modelos ARIMA nace del hecho de que no se puede trabajar con una serie temporal no estacionaria. Se dice que una serie es estacionaria cuando su media, varianza y autocovarianza son invariantes en el tiempo. La mayoría de series temporales económicas no son estacionarias pero diferenciándolas un número determinado de veces la serie original se transforma en estacionaria, con lo cual ya se podría aplicar la metodología de los modelos ARIMA. A continuación se mostrara la serie de tiempo “Inflación de argentina” en la cual se mostrara la sucesiones de datos mensuales desde el año 1970 hasta la actualidad.

A continuación se buscara el modelo que mejor se ajuste a la serie de datos.

Introducción de los datos

library(ggplot2)
library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(tseries)
library(readxl)
library(lmtest)
## Cargando paquete requerido: zoo
## 
## Adjuntando el paquete: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
datos <- read_excel("C:/Users/william/Desktop/Econometria II/datos de series de tiempo argentina.xlsx")
datos.ts= ts(datos)

Trazamos la serie de tiempo con ggplot

ggplot() +
  geom_line(data = datos, aes(x = Fecha , y = Valor)) + ylab('Inflacion de argentina')

#usamos medias moviles para suavizar el componente estacional

datos$Valor.ma = ma(datos$Valor
                    , order=7) 
datos$Valor30.ma = ma(datos$Valor, order=30)


ggplot() +
  geom_line(data = datos, aes(x = Fecha, y = Valor, colour = "serie original")) +
  geom_line(data = datos, aes(x = Fecha, y = Valor.ma,   colour = "Weekly Moving Average"))  +
  geom_line(data = datos, aes(x = Fecha, y = Valor30.ma, colour = "Monthly Moving Average"))  +
  ylab('Inflacion de argentina')
## Warning: Removed 6 rows containing missing values or values outside the scale range
## (`geom_line()`).
## Warning: Removed 30 rows containing missing values or values outside the scale range
## (`geom_line()`).

Primero, calculamos el componente estacional del uso de datos stl(). A continuación,hallamos el componente estacional de la serie mediante suavizado y ajusta la serie original restando la estacionalidad.

count_ma = ts(na.omit(datos$Valor30.ma), frequency=30)
decomp = stl(count_ma, s.window="periodic")
deseasonal_inf <- seasadj(decomp)
plot(decomp)

#  Los datos están en la segunda columna:
datos <- datos[[2]]

# Convertir los datos a un objeto de serie de tiempo
datos.ts <- ts(datos, start = c(1970, 7), frequency = 12)

# Verifica la longitud de la serie de tiempo
length(datos.ts)
## [1] 653
# Descomponer la serie de tiempo
datos_decomp <- decompose(datos.ts)

# Dividir la ventana gráfica en una matriz de 2 filas y 2 columnas
par(mfrow = c(2, 2))

# Graficar los componentes descompuestos de la serie de tiempo
plot(datos_decomp$x, main = "Serie de tiempo - Original", col = "black", ylab = "Valores")
plot(datos_decomp$trend, main = "Tendencia", col = "blue", ylab = "Valores")
plot(datos_decomp$seasonal, main = "Estacionalidad", col = "red", ylab = "Valores")
plot(datos_decomp$random, main = "Irregularidad", col = "green", ylab = "Valores")

Estacionariedad

La instalación de un modelo ARIMA requiere que la serie sea estacionaria . Se dice que una serie es estacionaria cuando su media, varianza y autocovarianza son invariantes en el tiempo.

Esta suposición tiene un sentido intuitivo:

Dado que ARIMA usa retardos previos de series para modelar su comportamiento

adf.test(count_ma, alternative = "stationary")
## 
##  Augmented Dickey-Fuller Test
## 
## data:  count_ma
## Dickey-Fuller = -3.6555, Lag order = 8, p-value = 0.02736
## alternative hypothesis: stationary

Contraste de hipótesis:

H0: No estacionaria H1: Estacionaria

Tras realizar la prueba aumentada de Dickey-Fuller (ADF), obtenemos un p-valor = 0.02 Como el p-valor < 0.05, rechazamos H0. Podemos concluir que nuestra serie temporal es estacionaria.

Autocorrelacion simple

Las ACF proporcionan información sobre cómo una observación influye en las siguientes. Las PACF proporcionan la relación directa existente entre observaciones separadas por k retardos.

Acf(count_ma, main='')

Pacf(count_ma, main='')

Serie de tiempo diferenciadas, es

#serie estacionaria
count_d1 = diff(deseasonal_inf, differences = 1)
plot(count_d1)

#decomposicion
decomp2 = stl(count_d1, s.window="periodic")
deseasonal_inf2 <- seasadj(decomp2)
plot(decomp2)

estacionariedad

adf.test(count_d1, alternative = "stationary")
## Warning in adf.test(count_d1, alternative = "stationary"): p-value smaller than
## printed p-value
## 
##  Augmented Dickey-Fuller Test
## 
## data:  count_d1
## Dickey-Fuller = -4.4557, Lag order = 8, p-value = 0.01
## alternative hypothesis: stationary

AUTOCORRELACION DE LA SERIE DIFERENCIADA

Acf(count_d1, main='')

Pacf(count_d1, main='')

Modelo arima

#serie sin diferenciar
auto.arima(deseasonal_inf, seasonal=FALSE)
## Series: deseasonal_inf 
## ARIMA(5,1,4) 
## 
## Coefficients:
##          ar1      ar2     ar3      ar4     ar5     ma1     ma2      ma3
##       0.5751  -0.0991  0.7494  -0.6233  0.2746  1.1146  0.3845  -0.5818
## s.e.  0.0589   0.0455  0.0325   0.0496  0.0451  0.0512  0.0866   0.0843
##           ma4
##       -0.6538
## s.e.   0.0500
## 
## sigma^2 = 0.03799:  log likelihood = 136.29
## AIC=-252.57   AICc=-252.21   BIC=-208.24
#serie diferenciar
auto.arima(deseasonal_inf2, seasonal=FALSE)
## Series: deseasonal_inf2 
## ARIMA(2,0,1) with zero mean 
## 
## Coefficients:
##          ar1      ar2     ma1
##       0.7528  -0.0679  0.9284
## s.e.  0.0460   0.0459  0.0248
## 
## sigma^2 = 0.04205:  log likelihood = 102.54
## AIC=-197.08   AICc=-197.01   BIC=-179.35

Por lo tanto, basados en los criterios de informacion, correlogramas y ademas por parsimonia, elegimos la serie diferenciada.

library(TSA)
## Registered S3 methods overwritten by 'TSA':
##   method       from    
##   fitted.Arima forecast
##   plot.Arima   forecast
## 
## Adjuntando el paquete: 'TSA'
## The following objects are masked from 'package:stats':
## 
##     acf, arima
## The following object is masked from 'package:utils':
## 
##     tar
modeloarima<-auto.arima(deseasonal_inf, seasonal=FALSE)


##Podemos especificar el horizonte de pronóstico h periodos por delante para que se realicen las predicciones, y usar el modelo ajustado para generar dichas predicciones:

#prediccion para los proximos treinta meses con una confianza del 95%
prediccion <- forecast(modeloarima, h=100, level= c(95))
plot(prediccion)

# Calcular las medidas de precisión del modelo
accuracy_measures <- accuracy(modeloarima)

# Imprimir las medidas de precisión
print(accuracy_measures)
##                       ME      RMSE        MAE        MPE     MAPE       MASE
## Training set 0.001043776 0.1933381 0.08785958 0.01062971 14.62566 0.02023222
##                     ACF1
## Training set -0.02574648

#vALIDACIÓN#

# Prueba de Ljung-Box
Box.test(datos.ts, lag = 20, type = "Ljung-Box")
## 
##  Box-Ljung test
## 
## data:  datos.ts
## X-squared = 1509.4, df = 20, p-value < 2.2e-16
# Prueba de Shapiro-Wilk
shapiro.test(datos_decomp$random)
## 
##  Shapiro-Wilk normality test
## 
## data:  datos_decomp$random
## W = 0.3872, p-value < 2.2e-16
# Prueba de Shapiro-Wilk
shapiro.test(datos_decomp$random)
## 
##  Shapiro-Wilk normality test
## 
## data:  datos_decomp$random
## W = 0.3872, p-value < 2.2e-16

Resumen de la Interpretación

  • Error Medio (ME): Muy cercano a 0, lo cual es positivo y sugiere que el modelo no está sesgado.

  • RMSE y MAE: Relativamente bajos, lo cual indica que el modelo se ajusta bien a los datos.

  • MPE: Bajo, indicando un buen rendimiento en términos de error porcentual medio.

  • MAPE: Alto, sugiriendo posibles problemas con valores atípicos o un ajuste deficiente en ciertas partes de los datos.

  • MASE: Menor que 1, indicando que el modelo es mejor que un modelo naive.

  • ACF1: Muy cercano a 0, indicando que no hay autocorrelación significativa en los errores residuales.