Module 5 — ARIMA et SARIMA
Les modules 3 et 4 ont donné toutes les briques : stationnarité, différenciation, lecture d'ACF et de PACF, référence à battre. Ce module assemble le premier modèle statistique complet, ARIMA, puis son extension saisonnière SARIMA — historiquement le standard de fait pour la prévision, et toujours un point de passage obligé aujourd'hui.
De AR et MA à ARIMA
Deux mécanismes élémentaires composent ARIMA. Un modèle AR() (autorégressif d'ordre ) explique la valeur courante par une combinaison linéaire des dernières valeurs :
Un modèle MA() (moyenne mobile d'ordre ) l'explique par une combinaison des derniers chocs :
Un ARMA() combine les deux. Enfin, ARIMA() applique ARMA sur la série différenciée fois : le « I » désigne l'intégration, opération inverse de la différenciation. Notation compacte : signifie « ma série différenciée fois suit un ARMA(, ) ».
L'intuition importante : les et ne sont pas des paramètres arbitraires, ils encodent la mémoire de la série. Une saison hebdomadaire résiduelle après différenciation appelle des composantes saisonnières, ce qui conduit au modèle suivant.
SARIMA : la version saisonnière
SARIMA()() ajoute des termes saisonniers de période aux ordres , , . Il y a donc deux jeux d'ordres : la partie courte et la partie saisonnière , les deux étant intégrées, autorégressives et moyennes mobiles à leur propre rythme.
Sur notre fil rouge, une spécification typique est SARIMA()() : différenciation simple contre la tendance, différenciation saisonnière hebdomadaire, un terme AR court, un MA court, et un MA saisonnier hebdomadaire. La saison annuelle n'est pas prise en charge ainsi (365 est trop grand pour un ordre saisonnier stable) et sera portée par des régresseurs de calendrier au module 7.
Sélection par AIC : la boucle courte
L'inspection d'ACF et de PACF (module 3) donne des ordres plausibles ; le critère AIC aide à trancher entre plusieurs candidats. L'AIC pénalise la complexité :
où est la vraisemblance et le nombre de paramètres. Un modèle qui améliore la vraisemblance sans ajouter trop de paramètres voit son AIC baisser ; un modèle qui multiplie les paramètres sans gain réel voit le sien monter. La règle est simple : choisir l'AIC le plus bas.
import itertools
from statsmodels.tsa.statespace.sarimax import SARIMAX
train = np.log(ventes.loc[:"2024-12-31", "quantite"])
# Grille modeste centree sur les ordres suggeres par l'ACF/PACF du module 3.
grille = list(itertools.product(range(0, 3), range(0, 2), range(0, 3)))
saisons = list(itertools.product(range(0, 2), range(0, 2), range(0, 2)))
meilleurs = []
for (p, d, q) in grille:
for (P, D, Q) in saisons:
try:
modele = SARIMAX(
train,
order=(p, d, q),
seasonal_order=(P, D, Q, 7),
enforce_stationarity=False,
enforce_invertibility=False,
).fit(disp=False)
meilleurs.append(((p, d, q), (P, D, Q, 7), modele.aic))
except Exception:
continue
meilleurs.sort(key=lambda x: x[2])
for ordres, saison, aic in meilleurs[:5]:
print(f"SARIMA{ordres}x{saison} -> AIC = {aic:.1f}")
Deux avertissements. D'abord, enforce_stationarity=False et enforce_invertibility=False évitent des échecs numériques sur certaines combinaisons, mais autorisent aussi des modèles douteux ; il faut donc relire les paramètres du meilleur candidat et vérifier qu'ils restent proches de l'intervalle stationnaire. Ensuite, une grille trop large est très coûteuse : préférez une grille éclairée par ACF/PACF plutôt que balayer tous les triplets.
L'algorithme auto_arima de la bibliothèque pmdarima automatise cette recherche et donne d'excellents résultats sur des séries qu'on ne connaît pas encore ; c'est un très bon point de départ, à condition de vérifier la structure retenue.
Diagnostic des résidus
Un modèle bien spécifié doit produire des résidus qui ressemblent à du bruit blanc : moyenne nulle, autocorrélations nulles, variance stable, distribution proche de la normale. Trois tests sont utiles.
L'ACF des résidus ne doit plus montrer de pic significatif : si un pic subsiste au décalage 7, la saisonnalité hebdomadaire n'est pas captée ; s'il subsiste au décalage 1, la partie courte a été sous-spécifiée. Le test de Ljung-Box globalise cette lecture : il teste l'absence d'autocorrélation sur les premiers retards. Un -value au-dessus de 0,05 est rassurant ; en dessous, il faut réviser les ordres.
L'hétéroscédasticité se lit sur un graphe des résidus au carré : une variance qui croît avec le niveau de prévision signale qu'il fallait probablement transformer la série (le log du module 3 y aide).
resultat = meilleur_modele.fit(disp=False)
resultat.plot_diagnostics(figsize=(10, 7))
Cette commande produit quatre panneaux — série des résidus, histogramme, Q-Q plot, ACF — qui suffisent à repérer 95 % des problèmes en un coup d'œil. Un modèle dont ces quatre panneaux sont propres est prêt pour la prévision.
Prévision et intervalles
Une force d'ARIMA/SARIMA, souvent sous-estimée, est de produire des intervalles de prévision cohérents avec la structure d'incertitude du modèle. On demande à statsmodels une prévision à horizon 28 :
prevision = resultat.get_forecast(steps=28)
moyenne = prevision.predicted_mean
intervalle_95 = prevision.conf_int(alpha=0.05) # 95 % de couverture theorique
# Ramener a l'echelle des ventes (le train etait en log).
moyenne_ventes = np.exp(moyenne)
borne_basse = np.exp(intervalle_95.iloc[:, 0])
borne_haute = np.exp(intervalle_95.iloc[:, 1])
Deux points à connaître. La conversion exp transforme l'intervalle log-normal en un intervalle asymétrique dans l'espace des ventes : la borne haute s'éloigne plus vite du centre que la borne basse. C'est un comportement correct, pas un bogue. Ensuite, la couverture réelle de ces intervalles est souvent inférieure à la couverture théorique — 95 % annoncés donnent en pratique 85 à 90 % — parce que l'estimation des paramètres n'est pas prise en compte. Le module 9 y reviendra pour évaluer honnêtement la couverture.
Ce que SARIMA capture mal
Trois limites structurent le passage au module 6, puis au module 7.
Les saisons longues (365 sur données quotidiennes) donnent des ordres saisonniers trop grands : SARIMA devient instable et lent. La solution est d'utiliser des régresseurs de Fourier (module 7) ou Prophet (module 6).
Les changements de régime (confinement, campagne exceptionnelle) sont mal gérés : SARIMA suppose une structure stable dans le temps. Prophet et les modèles à variables externes s'y adaptent mieux.
Enfin, la prise en compte de régresseurs externes existe (SARIMAX, le X étant pour eXogène) mais reste limitée à des relations linéaires : dès qu'on veut modéliser une interaction promotion x jour de semaine, un gradient boosting est plus commode.
Différencier trop (par exemple « pour être sûr ») rend le modèle instable et amplifie le bruit dans les intervalles. La règle du module 3 s'applique ici : le moins possible. Le test ADF sur la série une fois différenciée donne le bon nombre ; ne pas y ajouter d'ordre supplémentaire par prudence.
(1) Log si la variance croît avec le niveau ; (2) tests ADF/KPSS pour fixer et ; (3) ACF/PACF sur la série différenciée pour lister trois ou quatre candidats plausibles ; (4) AIC pour arbitrer, puis diagnostic des résidus sur le meilleur candidat ; (5) prévision à horizon avec intervalles, comparaison au tableau du module 4. Cette routine tient en une heure sur notre fil rouge et donne un modèle qui bat souvent le naïf saisonnier de 15 à 25 % en MAE.
En résumé
- ARIMA() applique un ARMA à la série différenciée ; SARIMA ajoute des ordres saisonniers de période .
- La sélection par AIC arbitre entre candidats de complexité comparable ; l'AIC le plus bas gagne, mais il faut relire les paramètres.
- Un diagnostic de résidus propre (Ljung-Box, ACF, Q-Q plot) est la condition d'un modèle exploitable ; sinon, réviser les ordres.
- Les intervalles sont un vrai atout, mais leur couverture réelle est inférieure à la couverture théorique — à valider empiriquement (module 9).
Module suivant : lissage exponentiel (Holt-Winters) et Prophet, deux familles qui complètent SARIMA sur ses points faibles.