1) Concernant votre première question, des statistiques de tests ont été développées et discutées dans la littérature pour tester le nul de stationnarité et le nul d'une racine unitaire. Certains des nombreux articles qui ont été écrits sur cette question sont les suivants:
Liés à la tendance:
- Dickey, D. y Fuller, W. (1979a), Distribution of the estimators for autoregressive time series with a unit root, Journal of the American Statistical Association 74, 427-31.
- Dickey, D. et Fuller, W. (1981), Statistiques du rapport de vraisemblance pour les séries chronologiques autorégressives avec une racine unitaire, Econometrica 49, 1057-1071.
- Kwiatkowski, D., Phillips, P., Schmidt, P. y Shin, Y. (1992), Test de l'hypothèse nulle de stationnarité par rapport à l'alternative d'une racine unitaire: dans quelle mesure sommes-nous sûrs que les séries chronologiques économiques ont une racine unitaire? , Journal of Econometrics 54, 159-178.
- Phillips, P. y Perron, P. (1988), Testing for a unit root in time series regression, Biometrika 75, 335-46.
- Durlauf, S.y Phillips, P. (1988), Tendances versus marches aléatoires dans l'analyse des séries chronologiques, Econometrica 56, 1333-54.
Relatif à la composante saisonnière:
- Hylleberg, S., Engle, R., Granger, C. y Yoo, B. (1990), Seasonal integration and cointegration, Journal of Econometrics 44, 215-38.
- Canova, F. y Hansen, BE (1995), Les tendances saisonnières sont-elles constantes dans le temps? un test de stabilité saisonnière, Journal of Business and Economic Statistics 13, 237-252.
- Franses, P. (1990), Test des racines unitaires saisonnières dans les données mensuelles, rapport technique 9032, Econometric Institute.
- Ghysels, E., Lee, H. y Noh, J. (1994), Test des racines unitaires dans les séries chronologiques saisonnières. quelques extensions théoriques et une enquête de monte carlo, Journal of Econometrics 62, 415-442.
Le manuel Banerjee, A., Dolado, J., Galbraith, J.y Hendry, D. (1993), Co-Integration, Error Correction, and the econometric analysis of non-stationary data, Advanced Texts in Econometrics. Oxford University Press est également une bonne référence.
2) Votre deuxième préoccupation est justifiée par la littérature. S'il existe un test de racine unitaire, la statistique t traditionnelle que vous appliqueriez sur une tendance linéaire ne suit pas la distribution standard. Voir par exemple, Phillips, P. (1987), Régression de séries chronologiques avec racine unitaire, Econometrica 55 (2), 277-301.
Si une racine unitaire existe et est ignorée, alors la probabilité de rejeter le zéro que le coefficient d'une tendance linéaire est zéro est réduite. Autrement dit, nous finirions par modéliser une tendance linéaire déterministe trop souvent pour un niveau de signification donné. En présence d'une racine unitaire, nous devrions plutôt transformer les données en prenant des différences régulières avec les données.
3) À titre d'illustration, si vous utilisez R, vous pouvez effectuer l'analyse suivante avec vos données.
x <- structure(c(7657, 5451, 10883, 9554, 9519, 10047, 10663, 10864,
11447, 12710, 15169, 16205, 14507, 15400, 16800, 19000, 20198,
18573, 19375, 21032, 23250, 25219, 28549, 29759, 28262, 28506,
33885, 34776, 35347, 34628, 33043, 30214, 31013, 31496, 34115,
33433, 34198, 35863, 37789, 34561, 36434, 34371, 33307, 33295,
36514, 36593, 38311, 42773, 45000, 46000, 42000, 47000, 47500,
48000, 48500, 47000, 48900), .Tsp = c(1, 57, 1), class = "ts")
Tout d'abord, vous pouvez appliquer le test Dickey-Fuller pour le zéro d'une racine unitaire:
require(tseries)
adf.test(x, alternative = "explosive")
# Augmented Dickey-Fuller Test
# Dickey-Fuller = -2.0685, Lag order = 3, p-value = 0.453
# alternative hypothesis: explosive
et le test KPSS pour l'hypothèse nulle inverse, stationnarité contre l'alternative de stationnarité autour d'une tendance linéaire:
kpss.test(x, null = "Trend", lshort = TRUE)
# KPSS Test for Trend Stationarity
# KPSS Trend = 0.2691, Truncation lag parameter = 1, p-value = 0.01
Résultats: test ADF, au niveau de signification de 5%, une racine unitaire n'est pas rejetée; Test KPSS, le nul de stationnarité est rejeté au profit d'un modèle à tendance linéaire.
Remarque: l'utilisation de lshort=FALSE
la valeur nulle du test KPSS n'est pas rejetée au niveau de 5%, mais elle sélectionne 5 retards; une inspection supplémentaire non présentée ici a suggéré que le choix de 1 à 3 décalages est approprié pour les données et conduit à rejeter l'hypothèse nulle.
En principe, nous devons nous guider par le test pour lequel nous avons pu rejeter l'hypothèse nulle (plutôt que par le test pour lequel nous n'avons pas rejeté (nous avons accepté) le nul). Cependant, une régression de la série originale sur une tendance linéaire se révèle non fiable. D'une part, le carré R est élevé (plus de 90%), ce qui est indiqué dans la littérature comme un indicateur de régression parasite.
fit <- lm(x ~ 1 + poly(c(time(x))))
summary(fit)
#Coefficients:
# Estimate Std. Error t value Pr(>|t|)
#(Intercept) 28499.3 381.6 74.69 <2e-16 ***
#poly(c(time(x))) 91387.5 2880.9 31.72 <2e-16 ***
#---
#Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#
#Residual standard error: 2881 on 55 degrees of freedom
#Multiple R-squared: 0.9482, Adjusted R-squared: 0.9472
#F-statistic: 1006 on 1 and 55 DF, p-value: < 2.2e-16
En revanche, les résidus sont autocorrélés:
acf(residuals(fit)) # not displayed to save space
De plus, la valeur nulle d'une racine unitaire dans les résidus ne peut être rejetée.
adf.test(residuals(fit))
# Augmented Dickey-Fuller Test
#Dickey-Fuller = -2.0685, Lag order = 3, p-value = 0.547
#alternative hypothesis: stationary
À ce stade, vous pouvez choisir un modèle à utiliser pour obtenir des prévisions. Par exemple, les prévisions basées sur un modèle structurel de séries chronologiques et sur un modèle ARIMA peuvent être obtenues comme suit.
# StructTS
fit1 <- StructTS(x, type = "trend")
fit1
#Variances:
# level slope epsilon
#2982955 0 487180
#
# forecasts
p1 <- predict(fit1, 10, main = "Local trend model")
p1$pred
# [1] 49466.53 50150.56 50834.59 51518.62 52202.65 52886.68 53570.70 54254.73
# [9] 54938.76 55622.79
# ARIMA
require(forecast)
fit2 <- auto.arima(x, ic="bic", allowdrift = TRUE)
fit2
#ARIMA(0,1,0) with drift
#Coefficients:
# drift
# 736.4821
#s.e. 267.0055
#sigma^2 estimated as 3992341: log likelihood=-495.54
#AIC=995.09 AICc=995.31 BIC=999.14
#
# forecasts
p2 <- forecast(fit2, 10, main = "ARIMA model")
p2$mean
# [1] 49636.48 50372.96 51109.45 51845.93 52582.41 53318.89 54055.37 54791.86
# [9] 55528.34 56264.82
Un tracé des prévisions:
par(mfrow = c(2, 1), mar = c(2.5,2.2,2,2))
plot((cbind(x, p1$pred)), plot.type = "single", type = "n",
ylim = range(c(x, p1$pred + 1.96 * p1$se)), main = "Local trend model")
grid()
lines(x)
lines(p1$pred, col = "blue")
lines(p1$pred + 1.96 * p1$se, col = "red", lty = 2)
lines(p1$pred - 1.96 * p1$se, col = "red", lty = 2)
legend("topleft", legend = c("forecasts", "95% confidence interval"),
lty = c(1,2), col = c("blue", "red"), bty = "n")
plot((cbind(x, p2$mean)), plot.type = "single", type = "n",
ylim = range(c(x, p2$upper)), main = "ARIMA (0,1,0) with drift")
grid()
lines(x)
lines(p2$mean, col = "blue")
lines(ts(p2$lower[,2], start = end(x)[1] + 1), col = "red", lty = 2)
lines(ts(p2$upper[,2], start = end(x)[1] + 1), col = "red", lty = 2)
Les prévisions sont similaires dans les deux cas et semblent raisonnables. Notez que les prévisions suivent un modèle relativement déterministe similaire à une tendance linéaire, mais nous n'avons pas modélisé explicitement une tendance linéaire. La raison en est la suivante: i) dans le modèle de tendance locale, la variance de la composante de pente est estimée à zéro. Cela transforme la composante de tendance en une dérive qui a l'effet d'une tendance linéaire. ii) ARIMA (0,1,1), un modèle avec dérive est sélectionné dans un modèle pour la série différenciée. L'effet du terme constant sur une série différenciée est une tendance linéaire. Ceci est discuté dans ce post .
Vous pouvez vérifier que si un modèle local ou un ARIMA (0,1,0) sans dérive est choisi, alors les prévisions sont une ligne horizontale droite et, par conséquent, n'auraient aucune ressemblance avec la dynamique observée des données. Eh bien, cela fait partie du puzzle des tests de racine unitaire et des composants déterministes.
Edit 1 (inspection des résidus):
L'autocorrélation et l'ACF partielle ne suggèrent pas de structure dans les résidus.
resid1 <- residuals(fit1)
resid2 <- residuals(fit2)
par(mfrow = c(2, 2))
acf(resid1, lag.max = 20, main = "ACF residuals. Local trend model")
pacf(resid1, lag.max = 20, main = "PACF residuals. Local trend model")
acf(resid2, lag.max = 20, main = "ACF residuals. ARIMA(0,1,0) with drift")
pacf(resid2, lag.max = 20, main = "PACF residuals. ARIMA(0,1,0) with drift")
Comme l'a suggéré IrishStat, il est également recommandé de vérifier la présence de valeurs aberrantes. Deux valeurs aberrantes additives sont détectées à l'aide du package tsoutliers
.
require(tsoutliers)
resol <- tsoutliers(x, types = c("AO", "LS", "TC"),
remove.method = "bottom-up",
args.tsmethod = list(ic="bic", allowdrift=TRUE))
resol
#ARIMA(0,1,0) with drift
#Coefficients:
# drift AO2 AO51
# 736.4821 -3819.000 -4500.000
#s.e. 220.6171 1167.396 1167.397
#sigma^2 estimated as 2725622: log likelihood=-485.05
#AIC=978.09 AICc=978.88 BIC=986.2
#Outliers:
# type ind time coefhat tstat
#1 AO 2 2 -3819 -3.271
#2 AO 51 51 -4500 -3.855
En regardant l'ACF, nous pouvons dire qu'au niveau de signification de 5%, les résidus sont également aléatoires dans ce modèle.
par(mfrow = c(2, 1))
acf(residuals(resol$fit), lag.max = 20, main = "ACF residuals. ARIMA with additive outliers")
pacf(residuals(resol$fit), lag.max = 20, main = "PACF residuals. ARIMA with additive outliers")
Dans ce cas, la présence de valeurs aberrantes potentielles ne semble pas fausser les performances des modèles. Ceci est soutenu par le test de Jarque-Bera pour la normalité; le zéro de normalité dans les résidus des modèles initiaux ( fit1
, fit2
) n'est pas rejeté au niveau de signification de 5%.
jarque.bera.test(resid1)[[1]]
# X-squared = 0.3221, df = 2, p-value = 0.8513
jarque.bera.test(resid2)[[1]]
#X-squared = 0.426, df = 2, p-value = 0.8082
Edit 2 (tracé des résidus et leurs valeurs)
Voici à quoi ressemblent les résidus:
Et ce sont leurs valeurs au format csv:
0;6.9205
-0.9571;-2942.4821
2.6108;4695.5179
-0.5453;-2065.4821
-0.2026;-771.4821
0.1242;-208.4821
0.1909;-120.4821
-0.0179;-535.4821
0.1449;-153.4821
0.484;526.5179
1.0748;1722.5179
0.3818;299.5179
-1.061;-2434.4821
0.0996;156.5179
0.4805;663.5179
0.8969;1463.5179
0.4111;461.5179
-1.0595;-2361.4821
0.0098;65.5179
0.5605;920.5179
0.8835;1481.5179
0.7669;1232.5179
1.4024;2593.5179
0.3785;473.5179
-1.1032;-2233.4821
-0.3813;-492.4821
2.2745;4642.5179
0.2935;154.5179
-0.1138;-165.4821
-0.8035;-1455.4821
-1.2982;-2321.4821
-1.9463;-3565.4821
-0.1648;62.5179
-0.1022;-253.4821
0.9755;1882.5179
-0.5662;-1418.4821
-0.0176;28.5179
0.5;928.5179
0.6831;1189.5179
-1.8889;-3964.4821
0.3896;1136.5179
-1.3113;-2799.4821
-0.9934;-1800.4821
-0.4085;-748.4821
1.2902;2482.5179
-0.0996;-657.4821
0.5539;981.5179
2.0007;3725.5179
1.0227;1490.5179
0.27;263.5179
-2.336;-4736.4821
1.8994;4263.5179
0.1301;-236.4821
-0.0892;-236.4821
-0.1148;-236.4821
-1.1207;-2236.4821
0.4801;1163.5179