Module 3 — Stationnarité, différenciation, autocorrélation
Le module 2 a séparé les composantes ; celui-ci prépare la modélisation statistique. Une famille entière de modèles — ARIMA et ses dérivés du module 5 — repose sur une hypothèse précise, la stationnarité. Comprendre ce qu'elle exige, comment la tester, comment y arriver par différenciation, puis comment lire les autocorrélogrammes ACF et PACF pour choisir des ordres : c'est le bagage technique de ce module.
Ce que veut dire « stationnaire »
Une série est strictement stationnaire si toutes ses distributions jointes sont invariantes par translation dans le temps. C'est une propriété trop forte pour être exploitable en pratique. On lui préfère la stationnarité au second ordre, qui exige seulement trois choses : une moyenne constante, une variance constante, et une autocovariance qui ne dépend que de l'écart entre deux instants, non de leur position absolue.
Concrètement, si vous découpez votre série en morceaux d'un an et qu'ils se ressemblent en niveau, en dispersion et dans leurs corrélations décalées, elle est probablement stationnaire. Sur notre fil rouge, ce n'est manifestement pas le cas : la tendance croissante fait dériver la moyenne, la saisonnalité annuelle fait varier la moyenne au sein d'une année, et la variance change entre l'hiver (fort) et l'été (faible). Il faudra donc transformer la série avant tout ajustement d'ARIMA.
Le test ADF, avec ses limites
Le test de Dickey-Fuller augmenté teste l'hypothèse nulle « la série a une racine unitaire », c'est-à-dire « la série n'est pas stationnaire ». Un -value inférieur à 0,05 permet de rejeter cette hypothèse et donc de conclure à la stationnarité.
from statsmodels.tsa.stattools import adfuller
resultat = adfuller(ventes["quantite"].dropna(), autolag="AIC")
statistique, p_value, retards, n = resultat[0], resultat[1], resultat[2], resultat[3]
print(f"statistique ADF : {statistique:.3f}")
print(f"p-value : {p_value:.4f}")
print(f"retards choisis : {retards}")
print(f"n effectif : {n}")
Deux pièges à connaître. D'abord, l'ADF a peu de puissance sur des séries courtes : il conclura souvent à la non-stationnarité par manque de preuves, ce qui n'est pas la même chose qu'une preuve de non-stationnarité. Ensuite, il ne teste que la tendance — une saisonnarité forte peut faire passer une série pour non-stationnaire alors qu'elle l'est en réalité une fois dessaisonnalisée. Un test complémentaire utile est le KPSS, dont l'hypothèse nulle est la stationnarité : quand ADF et KPSS s'accordent, la conclusion est solide ; quand ils divergent, il faut regarder plus finement.
Rendre la série stationnaire par différenciation
Deux opérations résolvent la plupart des cas. La différenciation simple :
retire la tendance : la vente d'un jour se convertit en variation par rapport à la veille. La différenciation saisonnière de période :
retire la saisonnalité en comparant chaque instant au même moment du cycle précédent. Sur notre fil rouge, compare chaque jour au même jour de la semaine précédente, éliminant la structure hebdomadaire. On peut combiner les deux : retire tendance et saisonnalité hebdomadaire.
Le nombre de différenciations à appliquer est habituellement noté pour la partie simple et pour la partie saisonnière. Le geste sain consiste à différencier le moins possible : chaque différenciation supplémentaire ampute la série d'observations et ajoute du bruit. En pratique, et suffisent presque toujours ; une deuxième différenciation () est un signal à ce qu'on ait mal spécifié la tendance.
serie = np.log(ventes["quantite"])
diff_1 = serie.diff().dropna() # d = 1
diff_1_7 = serie.diff().diff(7).dropna() # d = 1, D = 1
for nom, s in [("originale", serie), ("Δ", diff_1), ("Δ puis Δ_7", diff_1_7)]:
p = adfuller(s.dropna(), autolag="AIC")[1]
print(f"{nom:>16s} : p-value ADF = {p:.4f}")
Sur notre fil rouge, la série d'origine donne typiquement un -value au-delà de 0,3, la première différence tombe sous 0,05, et l'ajout de améliore encore la stationnarité tout en supprimant l'onde hebdomadaire.
Ne calculez jamais la moyenne ou la variance sur l'ensemble complet pour normaliser avant de découper : c'est de la fuite. De même, ne choisissez pas et en regardant la série entière : décomposez sur le train uniquement, puis appliquez les mêmes opérations au test. C'est le prolongement de la règle du module 1.
ACF et PACF : deux vues complémentaires
Une fois la série rendue stationnaire, deux graphiques renseignent sur la structure d'autocorrélation restante. La fonction d'autocorrélation (ACF) au décalage est la corrélation entre et . Elle capture la corrélation totale, y compris ce qui transite par les intermédiaires. La fonction d'autocorrélation partielle (PACF), elle, retire l'effet des retards intermédiaires : la PACF au décalage mesure la corrélation résiduelle entre et une fois neutralisées .
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
figure, (a1, a2) = plt.subplots(2, 1, figsize=(10, 6))
plot_acf(diff_1_7, lags=40, ax=a1)
plot_pacf(diff_1_7, lags=40, ax=a2, method="ywm")
Ces deux graphes forment une petite grammaire de lecture. Un AR() pur a une PACF qui coupe brusquement après le décalage et une ACF qui décroît lentement. Un MA() pur a l'inverse : ACF qui coupe après le décalage , PACF qui décroît. Un ARMA mêle les deux : les deux graphes décroissent, plus difficiles à lire, et c'est pour cela que la sélection par AIC (module 5) prend le relais dès qu'on quitte les cas simples.
Le prolongement saisonnier
Quand la série contient une saisonnalité de période , l'ACF présente des pics aux multiples de : sur nos ventes quotidiennes, on voit des pics à 7, 14, 21, 28. Ces pics guident les ordres saisonniers et du module suivant, exactement comme les pics « courts » guident et . La règle mnémotechnique : « les pics saisonniers résiduels après appellent des termes saisonniers dans SARIMA ».
Un piège fréquent de la PACF
La PACF calculée par la méthode de Yule-Walker biaisée peut osciller de façon trompeuse sur des séries courtes ; c'est pourquoi le code ci-dessus utilise method="ywm" (Yule-Walker modifié, non biaisé). Sur les séries longues, l'écart est invisible, mais la bonne habitude est de fixer la méthode explicitement.
Un autre piège concerne les bandes de confiance : par défaut, statsmodels dessine des bandes calculées sous l'hypothèse de bruit blanc. Un pic qui dépasse ces bandes n'est donc pas la preuve d'une structure, seulement une piste. C'est particulièrement vrai autour des retards saisonniers, où les corrélations induites par le calendrier peuvent tromper.
Cinq gestes, dans l'ordre : (1) log si la variance croît avec le niveau ; (2) test ADF ; (3) différencier simplement si nécessaire () ; (4) différencier saisonnièrement si l'ACF montre une saisonnalité résiduelle () ; (5) tracer ACF et PACF sur la série finalement stationnaire. Cette liste économise plusieurs heures d'ajustement à l'aveugle et donne des ordres directement plausibles au module suivant.
En résumé
- Stationnarité au second ordre : moyenne, variance et autocovariance qui ne dépendent que de l'écart.
- ADF teste la racine unitaire, KPSS la stationnarité ; leur accord donne une conclusion solide.
- Différenciation simple () contre la tendance, saisonnière () contre la saisonnalité ; différencier le moins possible.
- ACF et PACF guident , (courts) et , (saisonniers) — les motifs de coupure et de décroissance renseignent sur AR, MA ou ARMA.
Module suivant : les modèles de référence à ne jamais négliger, première ligne d'un tableau comparatif qu'on remplira jusqu'à la fin du cours.