library(tseries)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(caschrono)
## Le chargement a nécessité le package : zoo
## 
## Attachement du package : 'zoo'
## Les objets suivants sont masqués depuis 'package:base':
## 
##     as.Date, as.Date.numeric
library(forecast)

Chargement des données :

data=read.csv2(file="4MA_ST_2024_Projet.csv", header=TRUE, sep=";", dec=",")
sum(is.na(data)) #vérification de la présence ou non de NA 
## [1] 0
head(data)
##   Year Quarter      ASK_NB
## 1 1993       1 2.99201e+11
## 2 1993       2 3.18298e+11
## 3 1993       3 3.36073e+11
## 4 1993       4 3.22796e+11
## 5 1994       1 3.19586e+11
## 6 1994       2 3.33927e+11
tail(data)
##     Year Quarter      ASK_NB
## 119 2022       3 1.30407e+12
## 120 2022       4 1.14489e+12
## 121 2023       1 1.24400e+12
## 122 2023       2 1.42893e+12
## 123 2023       3 1.59119e+12
## 124 2023       4 1.43466e+12

On passe les données en log car beaucoup trop grandes

data.log=data
data.log$ASK_NB=log(data.log$ASK_NB)
data.log.ts=ts(data=data.log$ASK_NB, start=c(1993,1), end=c(2023,4), frequency=4)

head(data.log)
##   Year Quarter   ASK_NB
## 1 1993       1 26.42438
## 2 1993       2 26.48625
## 3 1993       3 26.54059
## 4 1993       4 26.50029
## 5 1994       1 26.49029
## 6 1994       2 26.53419
tail(data.log)
##     Year Quarter   ASK_NB
## 119 2022       3 27.89651
## 120 2022       4 27.76633
## 121 2023       1 27.84935
## 122 2023       2 27.98795
## 123 2023       3 28.09550
## 124 2023       4 27.99195

On parlera désormais toujours des données en log (si non précisé) lorsque que l’on parlera des ASK.

plot(data.log.ts,ylab="ASK_NB",main="ASK en fonction du temps")

Décomposition de la série à l’aide d’un modèle de régression linéaire

trimestre1 <- rep(c(1,0,0,0),31)
trimestre2 <- rep(c(0,1,0,0),31)
trimestre3 <- rep(c(0,0,1,0),31)
#on met que 3 trimestres sur 4 pour avoir la matrice X inversible
tendance <- seq(1993, 2023 + 3/4, 1/4)

mod = lm(data.log$ASK_NB ~ tendance + trimestre1 + trimestre2 + trimestre3)
summary(mod)
## 
## Call:
## lm(formula = data.log$ASK_NB ~ tendance + trimestre1 + trimestre2 + 
##     trimestre3)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.43690 -0.03689  0.01112  0.08112  0.25896 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -63.513622   3.894717 -16.308   <2e-16 ***
## tendance      0.045176   0.001939  23.301   <2e-16 ***
## trimestre1   -0.030542   0.049070  -0.622    0.535    
## trimestre2   -0.006310   0.049058  -0.129    0.898    
## trimestre3    0.078732   0.049051   1.605    0.111    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1931 on 119 degrees of freedom
## Multiple R-squared:  0.8223, Adjusted R-squared:  0.8163 
## F-statistic: 137.7 on 4 and 119 DF,  p-value: < 2.2e-16

Tendance significative car petite p-value

On enlève le trimestre 2 car il n’est pas significatif (grande p-value)

mod <- lm(data.log$ASK_NB ~ tendance + trimestre1 + trimestre3)
summary(mod)
## 
## Call:
## lm(formula = data.log$ASK_NB ~ tendance + trimestre1 + trimestre3)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.44011 -0.03771  0.01279  0.08245  0.25576 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -63.52667    3.87741 -16.384   <2e-16 ***
## tendance      0.04518    0.00193  23.404   <2e-16 ***
## trimestre1   -0.02738    0.04231  -0.647   0.5187    
## trimestre3    0.08189    0.04230   1.936   0.0553 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1923 on 120 degrees of freedom
## Multiple R-squared:  0.8223, Adjusted R-squared:  0.8178 
## F-statistic: 185.1 on 3 and 120 DF,  p-value: < 2.2e-16

On enlève le trimestre 1 car il n’est pas significatif

mod <- lm(data.log$ASK_NB ~ tendance + trimestre3)
summary(mod)
## 
## Call:
## lm(formula = data.log$ASK_NB ~ tendance + trimestre3)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.43132 -0.03498  0.01411  0.08391  0.26460 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -63.593040   3.866733 -16.446   <2e-16 ***
## tendance      0.045209   0.001925  23.481   <2e-16 ***
## trimestre3    0.091010   0.039789   2.287   0.0239 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1918 on 121 degrees of freedom
## Multiple R-squared:  0.8217, Adjusted R-squared:  0.8187 
## F-statistic: 278.8 on 2 and 121 DF,  p-value: < 2.2e-16
par(mfrow = c(2,2))
plot(mod)

checkresiduals(mod)

## 
##  Breusch-Godfrey test for serial correlation of order up to 10
## 
## data:  Residuals
## LM test = 56.65, df = 10, p-value = 1.551e-08
plot(mod$fitted.values,mod$residuals,ylab="residus",xlab="valeurs ajustées")
abline(h=0)

plot(mod$fitted.values,rstudent(mod),ylab="residus",xlab="valeurs ajustées",ylim=c(-12,3))
abline(h=c(-2,2),col="chartreuse4")

plot(tendance, data.log$ASK_NB, type = "l",col="chartreuse4",ylab="time",xlab="ASK_NB",main="Values and fitted values")
lines(tendance, mod$fitted.values, col = "red")

Lissage Exponentiel

Simple

data.log.ts.decompose=decompose(data.log.ts)
plot(diff(diff(data.log.ts,lag=4),lag=1),col="chartreuse4")
lines(data.log.ts-data.log.ts.decompose$seasonal-data.log.ts.decompose$trend,col="red")
legend("topleft", legend=c("lag 1 et 12","decompose"),col=c("chartreuse4", "red"), lty=1, cex=0.8)

data.log.ts.notrend=na.omit(data.log.ts-data.log.ts.decompose$trend)
data.log.ts.notrend.noseason=data.log.ts.notrend-data.log.ts.decompose$seasonal
data.log.ts.noseason=data.log.ts-data.log.ts.decompose$seasonal
data.log.ts.notrend.noseason.ses=HoltWinters(x=data.log.ts.notrend.noseason,beta=FALSE,gamma=FALSE)
data.log.ts.notrend.noseason.ses$alpha
## [1] 0.01393039
data.log.ts.notrend.noseason.ses$SSE
## [1] 1.097775
plot(data.log.ts.notrend.noseason.ses)

data.log.ts.notrend.noseason.ses=HoltWinters(x=data.log.ts.notrend.noseason,alpha=0.7,beta=FALSE,gamma=FALSE)
data.log.ts.notrend.noseason.ses$alpha
## [1] 0.7
data.log.ts.notrend.noseason.ses$SSE
## [1] 2.073741
plot(data.log.ts.notrend.noseason.ses)

data.log.ts.notrend.noseason=diff(diff(data.log.ts,lag=4),lag=1)
data.log.ts.notrend.noseason.ses=HoltWinters(x=data.log.ts.notrend.noseason,beta=FALSE,gamma=FALSE)
data.log.ts.notrend.noseason.ses$alpha
## [1] 6.610696e-05
data.log.ts.notrend.noseason.ses$SSE
## [1] 6.140676
plot(data.log.ts.notrend.noseason.ses)

data.log.ts.notrend.noseason=diff(diff(data.log.ts,lag=4),lag=1)
data.log.ts.notrend.noseason.ses=HoltWinters(x=data.log.ts.notrend.noseason,alpha=0.7,beta=FALSE,gamma=FALSE)
data.log.ts.notrend.noseason.ses$alpha
## [1] 0.7
data.log.ts.notrend.noseason.ses$SSE
## [1] 11.18091
plot(data.log.ts.notrend.noseason.ses)

Double

data.log.ts.notrend=na.omit(data.log.ts-data.log.ts.decompose$trend)
data.log.ts.notrend.noseason=data.log.ts.notrend-data.log.ts.decompose$seasonal
data.log.ts.noseason=data.log.ts-data.log.ts.decompose$seasonal
data.log.ts.noseason.des=HoltWinters(x=data.log.ts.noseason,gamma=FALSE)
## Warning in HoltWinters(x = data.log.ts.noseason, gamma = FALSE): difficultés
## d'optimisation : ERROR: ABNORMAL_TERMINATION_IN_LNSRCH
data.log.ts.noseason.des$alpha
##     alpha 
## 0.6710605
data.log.ts.noseason.des$beta
##       beta 
## 0.01777311
data.log.ts.noseason.des$SSE
## [1] 2.804286
plot(data.log.ts.noseason.des)

data.log.ts.noseason.des=HoltWinters(x=data.log.ts.noseason,gamma=FALSE,alpha=0.6,beta=0.6)
data.log.ts.noseason.des$alpha
## [1] 0.6
data.log.ts.noseason.des$beta
## [1] 0.6
data.log.ts.noseason.des$SSE
## [1] 3.700657
plot(data.log.ts.noseason.des)

Holt-Winters

La saisonnalité a l’air globalement constante donc on part plus sur un modèle additif

data.log.ts.HoltWinters.additive=HoltWinters(data.log.ts,seasonal = "additive")
data.log.ts.HoltWinters.additive$alpha
##    alpha 
## 0.630329
data.log.ts.HoltWinters.additive$beta
## beta 
##    0
data.log.ts.HoltWinters.additive$gamma
## gamma 
##     0
data.log.ts.HoltWinters.additive$SSE
## [1] 2.761871
plot(data.log.ts.HoltWinters.additive)

Modèles (S)AR(I)MA

Modèle ARMA

Série résiduelle

data.log.ts.notrend=na.omit(data.log.ts-data.log.ts.decompose$trend)
data.log.ts.notrend.noseason=data.log.ts.notrend-data.log.ts.decompose$seasonal
data.log.ts.noseason=data.log.ts-data.log.ts.decompose$seasonal

Test de la stationnarité à l’aide du test de Dickey-Fuller

#on utilise la serie residuelle donc on sait deja que la tendance est nulle, on passe direct a l'etape suivante
delta_data.log.ts.notrend.noseason=diff(data.log.ts.notrend.noseason)
serie_moins_1=data.log.ts.notrend.noseason[-length(data.log.ts.notrend.noseason)]
summary(lm(formula = delta_data.log.ts.notrend.noseason ~ serie_moins_1))
## 
## Call:
## lm(formula = delta_data.log.ts.notrend.noseason ~ serie_moins_1)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.77335 -0.02263 -0.00102  0.02456  0.41846 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   -0.0002495  0.0083520   -0.03    0.976    
## serie_moins_1 -1.2976025  0.0883621  -14.69   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.09111 on 117 degrees of freedom
## Multiple R-squared:  0.6483, Adjusted R-squared:  0.6453 
## F-statistic: 215.7 on 1 and 117 DF,  p-value: < 2.2e-16
adf.test(data.log.ts.notrend.noseason)
## Warning in adf.test(data.log.ts.notrend.noseason): p-value smaller than printed
## p-value
## 
##  Augmented Dickey-Fuller Test
## 
## data:  data.log.ts.notrend.noseason
## Dickey-Fuller = -7.812, Lag order = 4, p-value = 0.01
## alternative hypothesis: stationary

Détermination des ordres p et q du modèle

On peut ainsi tracer les graphes des acf et pacf

par(mfrow=c(1,2))
acf(data.log.ts.notrend.noseason)
pacf(data.log.ts.notrend.noseason)

Grâce à l’ACF on trouve q=2 et grâce au PACF, on trouve p=6

On se retrouve donc avec un modèle ARMA(6,2)

Suppression des coefficients non significatifs

modele1=arima(data.log.ts.notrend.noseason, order=c(6,0,2))
t_stat(modele1)
##              ar1       ar2       ar3       ar4       ar5       ar6       ma1
## t.stat -0.179096 -0.571911 -0.039604 -0.343206 -0.729837 -0.780751 -0.518654
## p.val   0.857862  0.567382  0.968409  0.731443  0.465490  0.434949  0.604002
##              ma2 intercept
## t.stat -0.366685 -0.031670
## p.val   0.713854  0.974735

On supprime les coefficients non significatifs

modele2=arima(data.log.ts.notrend.noseason, order=c(6,0,2),fixed=c(NA,NA,NA,NA,NA,NA,NA,NA,0))
t_stat(modele2)
##             ar1       ar2      ar3       ar4      ar5      ar6       ma1
## t.stat 11.88989 -3.171445 2.128154 -1.120168 0.022555 0.005831 -9.284231
## p.val   0.00000  0.001517 0.033324  0.262642 0.982005 0.995348  0.000000
##             ma2
## t.stat 4.639807
## p.val  0.000003
modele3=arima(data.log.ts.notrend.noseason, order=c(5,0,2),fixed=c(NA,NA,NA,NA,NA,NA,NA,0))
t_stat(modele3)
##              ar1       ar2       ar3      ar4       ar5       ma1       ma2
## t.stat -1.143104 -0.189301 -0.696197 0.097244 -0.868919 -0.115717 -1.514863
## p.val   0.252996  0.849857  0.486305 0.922532  0.384891  0.907876  0.129807
modele4=arima(data.log.ts.notrend.noseason, order=c(5,0,2),fixed=c(NA,NA,NA,NA,NA,0,NA,0))
t_stat(modele4)
##              ar1       ar2       ar3      ar4       ar5       ma2
## t.stat -8.369831 -0.173379 -1.172925 0.139257 -0.821698 -34.27537
## p.val   0.000000  0.862354  0.240826 0.889247  0.411249   0.00000
modele5=arima(data.log.ts.notrend.noseason, order=c(5,0,2),fixed=c(NA,NA,NA,0,NA,0,NA,0),method="CSS")
## Warning in arima(data.log.ts.notrend.noseason, order = c(5, 0, 2), fixed =
## c(NA, : certains des paramètres AR etaient fixés : transform.pars = FALSE
t_stat(modele5)
##              ar1       ar2       ar3       ar5       ma2
## t.stat -12.94807 -1.872890 -2.152993 -1.535810 -145.6863
## p.val    0.00000  0.061084  0.031319  0.124585    0.0000
modele6=arima(data.log.ts.notrend.noseason, order=c(3,0,2),fixed=c(NA,NA,NA,0,NA,0),method="CSS")
t_stat(modele6)
##              ar1       ar2       ar3       ma2
## t.stat -23.07748 -0.574012 -4.885643 -101.4561
## p.val    0.00000  0.565960  0.000001    0.0000
modele7=arima(data.log.ts.notrend.noseason, order=c(3,0,2),fixed=c(NA,0,NA,0,NA,0),method="CSS")
## Warning in arima(data.log.ts.notrend.noseason, order = c(3, 0, 2), fixed =
## c(NA, : certains des paramètres AR etaient fixés : transform.pars = FALSE
t_stat(modele7)
##              ar1       ar3       ma2
## t.stat -45.65908 -30.54278 -83.33558
## p.val    0.00000   0.00000   0.00000
summary(modele7)
## 
## Call:
## arima(x = data.log.ts.notrend.noseason, order = c(3, 0, 2), fixed = c(NA, 0, 
##     NA, 0, NA, 0), method = "CSS")
## 
## Coefficients:
##           ar1  ar2     ar3  ma1      ma2  intercept
##       -0.8013    0  -0.276    0  -1.0995          0
## s.e.   0.0175    0   0.009    0   0.0132          0
## 
## sigma^2 estimated as 0.004727:  part log likelihood = 150.99
## 
## Training set error measures:
##                        ME       RMSE       MAE      MPE     MAPE      MASE
## Training set 0.0005078177 0.06788911 0.0257532 28.15948 108.9935 0.4779648
##                     ACF1
## Training set -0.02816611
checkresiduals(modele7)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(3,0,2) with non-zero mean
## Q* = 6.1685, df = 3, p-value = 0.1037
## 
## Model df: 5.   Total lags used: 8
pacf(modele7$residuals)

C’est bien décorélé (pas de process ma ou ar dans les résidus donc ok) et ca suit une espece de loi normale

plot(data.log.ts.notrend.noseason,col="chartreuse4",ylab="Série résiduelle")
lines(fitted(modele7),col="blue")
legend("bottomleft", legend=c("Série", "Série ajustée"),
       col=c("chartreuse4", "blue"), lty=1)

plot(data.log.ts,ylab="ASK_NB",col="chartreuse4")
lines(data.log.ts.decompose$trend+data.log.ts.decompose$seasonal+fitted(modele7),col="blue")
legend("topleft", legend=c("Série", "Série ajustée"),
       col=c("chartreuse4", "blue"), lty=1)

plot(forecast(modele7))
## Warning in predict.Arima(object, n.ahead = h): La partie MA du modèle est non
## inversible

Modèle ARIMA

Détermination des coefficients du modèle ARIMA

par(mfrow=c(1,2))
acf(diff(data.log.ts.noseason))
pacf(diff(data.log.ts.noseason))

Suppression des coefficients non significatifs

modarima=arima(data.log.ts.noseason, order=c(2,1,1))
t_stat(modarima)
##              ar1       ar2      ma1
## t.stat -0.663126 -1.224379 0.056284
## p.val   0.507250  0.220809 0.955115
arima2=arima(data.log.ts.noseason, order=c(2,1,0))
t_stat(arima2)
##              ar1       ar2
## t.stat -3.418936 -2.023382
## p.val   0.000629  0.043034
summary(arima2)
## 
## Call:
## arima(x = data.log.ts.noseason, order = c(2, 1, 0))
## 
## Coefficients:
##           ar1     ar2
##       -0.3024  -0.178
## s.e.   0.0884   0.088
## 
## sigma^2 estimated as 0.02218:  log likelihood = 59.63,  aic = -113.26
## 
## Training set error measures:
##                      ME      RMSE        MAE       MPE      MAPE      MASE
## Training set 0.01864005 0.1483493 0.05574108 0.0664706 0.2058271 0.9759373
##                     ACF1
## Training set -0.01710958
checkresiduals(arima2)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(2,1,0)
## Q* = 2.3897, df = 6, p-value = 0.8806
## 
## Model df: 2.   Total lags used: 8
pacf(arima2$residuals)

plot(data.log.ts.noseason,col="chartreuse4",ylab="Série sans saisonnalité")
lines(fitted(arima2),col="blue")
legend("bottomleft", legend=c("Série", "Série ajustée"),
       col=c("chartreuse4", "blue"), lty=1)

plot(data.log.ts,ylab="ASK_NB",col="chartreuse4")
lines(data.log.ts.decompose$seasonal+fitted(arima2),col="blue")
legend("topleft", legend=c("Série", "Série ajustée"),
       col=c("chartreuse4", "blue"), lty=1)

Modèle SARIMA

diff_season <- diff(data.log.ts, lag = 4)  # Différenciation saisonnière
plot(diff_season)

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

serie stationnaire donc D=1

acf(diff_season)

pacf(diff_season)

On regarde les pics aux lags multiples de la période (d’après p183 du poly)

acf –> Q=0

pacf –> P=1

sarima=arima(data.log.ts, order = c(2,1,1), seasonal = list(order = c(0,1,1), period = 4))
t_stat(sarima)
##             ar1      ar2       ma1      sma1
## t.stat 6.526795 1.405316 -17.21847 -14.15189
## p.val  0.000000 0.159927   0.00000   0.00000
sarima2=arima(data.log.ts, order = c(1,1,1), seasonal = list(order = c(0,1,1), period = 4))
t_stat(sarima2)
##             ar1       ma1      sma1
## t.stat 9.600516 -4.944707 -14.09764
## p.val  0.000000  0.000001   0.00000
checkresiduals(sarima2)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(1,1,1)(0,1,1)[4]
## Q* = 5.1633, df = 5, p-value = 0.3963
## 
## Model df: 3.   Total lags used: 8
pacf(sarima2$residuals)

pas de ma ni ar dans les residus donc ok

plot(data.log.ts,ylab="ASK_NB",col="chartreuse4")
lines(fitted(sarima2),col="blue")
legend("topleft", legend=c("Série", "Série fitted avec SARIMA"),
       col=c("chartreuse4", "blue"), lty=1)

Calcul des RMSE

summary(sarima2) #SARIMA
## 
## Call:
## arima(x = data.log.ts, order = c(1, 1, 1), seasonal = list(order = c(0, 1, 1), 
##     period = 4))
## 
## Coefficients:
##          ar1      ma1     sma1
##       0.6791  -1.0000  -0.9101
## s.e.  0.0707   0.2022   0.0646
## 
## sigma^2 estimated as 0.02214:  log likelihood = 51,  aic = -94.01
## 
## Training set error measures:
##                        ME      RMSE        MAE         MPE      MAPE     MASE
## Training set -0.008523232 0.1458693 0.04008316 -0.03350983 0.1482445 0.506924
##                    ACF1
## Training set -0.0923017
summary(arima2) #ARIMA
## 
## Call:
## arima(x = data.log.ts.noseason, order = c(2, 1, 0))
## 
## Coefficients:
##           ar1     ar2
##       -0.3024  -0.178
## s.e.   0.0884   0.088
## 
## sigma^2 estimated as 0.02218:  log likelihood = 59.63,  aic = -113.26
## 
## Training set error measures:
##                      ME      RMSE        MAE       MPE      MAPE      MASE
## Training set 0.01864005 0.1483493 0.05574108 0.0664706 0.2058271 0.9759373
##                     ACF1
## Training set -0.01710958
summary(modele7) #ARMA
## 
## Call:
## arima(x = data.log.ts.notrend.noseason, order = c(3, 0, 2), fixed = c(NA, 0, 
##     NA, 0, NA, 0), method = "CSS")
## 
## Coefficients:
##           ar1  ar2     ar3  ma1      ma2  intercept
##       -0.8013    0  -0.276    0  -1.0995          0
## s.e.   0.0175    0   0.009    0   0.0132          0
## 
## sigma^2 estimated as 0.004727:  part log likelihood = 150.99
## 
## Training set error measures:
##                        ME       RMSE       MAE      MPE     MAPE      MASE
## Training set 0.0005078177 0.06788911 0.0257532 28.15948 108.9935 0.4779648
##                     ACF1
## Training set -0.02816611
n=length(data.log.ts)
sqrt(data.log.ts.notrend.noseason.ses$SSE / n) #SES
## [1] 0.3002809
sqrt(data.log.ts.noseason.des$SSE / n) #DES
## [1] 0.1727542
sqrt(data.log.ts.HoltWinters.additive$SSE /n) #HW
## [1] 0.1492419

Modèles sans covid + Prévisions

data.log.ts.nocovid=ts(data=data.log$ASK_NB, start=c(1993,1), end=c(2019,4), frequency=4)

Séparation en set d’entrainement et validation pour vérifier nos résultats

data.log.ts.nocovid.training=window(x=data.log.ts.nocovid, start=c(1993,1), end=c(2014,4), frequency=4)
data.log.ts.nocovid.validation=window(x=data.log.ts.nocovid, start=c(2015,1), end=c(2019,4), frequency=4)

HW

data.log.ts.nocovid.HoltWinters.additive.training=HoltWinters(data.log.ts.nocovid.training,seasonal = "additive")
plot(forecast(data.log.ts.nocovid.HoltWinters.additive.training,h=5*4))
lines(data.log.ts.nocovid.validation,col="green",lwd=2)

SARIMA

data.log.ts.nocovid.sarima.training=auto.arima(data.log.ts.nocovid.training,d=1,D=1,seasonal=TRUE)
checkresiduals(data.log.ts.nocovid.sarima.training)

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(0,1,1)(0,1,1)[4]
## Q* = 2.9615, df = 6, p-value = 0.8137
## 
## Model df: 2.   Total lags used: 8
pacf(data.log.ts.nocovid.sarima.training$residuals)

plot(forecast(data.log.ts.nocovid.sarima.training,h=5*4))
lines(data.log.ts.nocovid.validation,col="green",lwd=2)

plot(forecast(data.log.ts.nocovid.sarima.training,h=10*4))
lines(data.log.ts,col="green",lwd=2)

Prévisions

data.log.ts.nocovid.HoltWinters.additive=HoltWinters(data.log.ts.nocovid,seasonal = "additive")
checkresiduals(data.log.ts.nocovid.HoltWinters.additive)

## 
##  Ljung-Box test
## 
## data:  Residuals from HoltWinters
## Q* = 24.953, df = 8, p-value = 0.001583
## 
## Model df: 0.   Total lags used: 8
plot(forecast(data.log.ts.nocovid.HoltWinters.additive,h=23*4+1))

f=forecast(data.log.ts.nocovid.HoltWinters.additive,h=23*4+1)
tail(f$lower,1)
##              80%      95%
## 2043 Q1 28.85268 28.74097
tail(f$upper,1)
##              80%      95%
## 2043 Q1 29.27474 29.38645