Module 4 — Modèles de référence à ne jamais négliger
Les modules 1 à 3 ont posé le vocabulaire, la décomposition, la stationnarité et les outils de lecture. Avant d'ajuster ARIMA au module suivant, il faut fixer une référence : un modèle si simple qu'il ne peut pas être plus mauvais que rien, et que tout modèle sophistiqué devra battre nettement pour justifier sa complexité. C'est la première ligne du tableau comparatif que nous remplirons jusqu'au module 10.
Pourquoi ces modèles restent-ils incontournables
Dans un grand nombre de projets, on découvre après plusieurs semaines qu'un modèle savant fait à peine mieux qu'une constante ou qu'une moyenne. Ce résultat n'est ni rare ni gênant en soi ; il est critique quand personne ne l'a mesuré, car il aurait épargné les semaines en question. Les modèles de référence servent trois objectifs.
Ils cadrent l'espoir : quand la vente d'aujourd'hui est un mauvais prédicteur de celle de demain, la meilleure référence est déjà à un plancher que peu de modèles amélioreront. Ils détectent les fuites : un modèle qui obtient un score étrangement supérieur à toute référence naïve dissimule presque toujours une fuite du futur, à commencer par un régresseur mal daté (module 1). Enfin, ils calibrent une métrique — le MASE du module 9 est directement défini comme un rapport entre l'erreur du modèle et l'erreur d'un naïf saisonnier, ce qui exige d'avoir calculé le naïf saisonnier.
Les quatre références classiques
Notons la prévision à horizon faite à l'instant .
Naïf : . La dernière valeur observée sert de prévision pour tous les horizons. C'est le baseline universel des séries sans saisonnalité claire.
Naïf saisonnier : , où est la période saisonnière. Chaque prévision reprend la valeur de la même position du cycle précédent : le vendredi prochain égale le vendredi dernier. Sur des séries saisonnières comme la nôtre, c'est le seul baseline honnête, et c'est celui que la plupart des modèles savants peinent à battre nettement.
Moyenne : . La moyenne de toute l'histoire. Utile comme référence extrême pour vérifier qu'un modèle a bien capté quelque chose ; s'il n'est pas meilleur que la moyenne, il faut tout revoir.
Dérive (drift) : . Le naïf enrichi d'une tendance linéaire calibrée sur toute la série. Il est parfois brutalement supérieur au naïf sur des séries franchement croissantes ou décroissantes, et parfois brutalement inférieur quand la tendance récente diverge de la tendance moyenne.
Aucune de ces méthodes n'utilise de régresseur externe ni de saisonnalité annuelle sophistiquée. C'est précisément ce qui en fait une référence : elles disent « voilà ce qu'on obtient en n'apprenant presque rien ».
Les implémenter proprement
import numpy as np
import pandas as pd
def naif(train, horizon):
return pd.Series(train.iloc[-1], index=pd.date_range(
train.index[-1] + pd.Timedelta(days=1), periods=horizon, freq="D"
))
def naif_saisonnier(train, horizon, s=7):
# Reproduit les s derniers jours, en boucle jusqu'a l'horizon voulu.
dernier_cycle = train.iloc[-s:].values
valeurs = np.tile(dernier_cycle, int(np.ceil(horizon / s)))[:horizon]
index = pd.date_range(train.index[-1] + pd.Timedelta(days=1), periods=horizon, freq="D")
return pd.Series(valeurs, index=index)
def moyenne(train, horizon):
return pd.Series(train.mean(), index=pd.date_range(
train.index[-1] + pd.Timedelta(days=1), periods=horizon, freq="D"
))
def derive(train, horizon):
pente = (train.iloc[-1] - train.iloc[0]) / (len(train) - 1)
base = train.iloc[-1]
valeurs = base + pente * np.arange(1, horizon + 1)
index = pd.date_range(train.index[-1] + pd.Timedelta(days=1), periods=horizon, freq="D")
return pd.Series(valeurs, index=index)
Chaque fonction respecte deux règles : elle n'utilise que le passé (train), et elle produit un index de dates aligné sur le calendrier de test. Cette dernière précaution évite un piège fréquent — comparer les prévisions à un test avec un décalage d'un jour rend n'importe quel modèle spectaculairement mauvais, et l'erreur ne saute pas aux yeux.
Mesurer, puis remplir la première ligne du tableau
from sklearn.metrics import mean_absolute_error, mean_squared_error
def evaluer(nom, y_vrai, y_prevu):
mae = mean_absolute_error(y_vrai, y_prevu)
rmse = np.sqrt(mean_squared_error(y_vrai, y_prevu))
return {"modele": nom, "MAE": mae, "RMSE": rmse}
train = ventes.loc[:"2024-12-31", "quantite"]
test = ventes.loc["2025-01-01":"2025-01-28", "quantite"] # 28 jours d'horizon
resultats = [
evaluer("naif", test.values, naif(train, 28).values),
evaluer("naif saisonnier", test.values, naif_saisonnier(train, 28, s=7).values),
evaluer("moyenne", test.values, moyenne(train, 28).values),
evaluer("derive", test.values, derive(train, 28).values),
]
tableau = pd.DataFrame(resultats).sort_values("MAE")
print(tableau.to_string(index=False))
Sur notre fil rouge, la sortie typique met le naïf saisonnier clairement en tête, la dérive ensuite, puis le naïf simple, et la moyenne loin derrière. C'est cet ordre qu'il faut comparer aux modèles à venir. Un ARIMA ajusté sans tenir compte de la saisonnalité hebdomadaire fera plus mal que le naïf saisonnier ; c'est un signal parfaitement lisible, mais qu'on manque quand on n'a pas construit la référence.
Ce que « nettement battre » veut dire
Battre le naïf saisonnier de 2 % sur le MAE ne justifie pas un modèle de 500 lignes. La règle utile est de raisonner par ordre de grandeur : un modèle statistique bien spécifié doit apporter au moins 10 à 30 % d'amélioration relative sur la métrique retenue pour l'usage, un modèle profond au moins autant, sinon on paie une complexité qui n'apporte rien. Cette règle vaut pour la décision opérationnelle : rappeler des humains pour surveiller un modèle coûte quelque chose, et si le gain est faible, mieux vaut garder le naïf saisonnier.
Ne comparer qu'à une moyenne est trompeur sur les séries saisonnières : n'importe quel modèle bat la moyenne sur des ventes qui varient du simple au double dans la semaine. Le vrai comparatif est le naïf saisonnier, qui exploite déjà l'information la plus manifeste. Sans lui, une bonne partie des « victoires » annoncées disparaîtraient.
Le baseline par recomposition
Le module 2 fournit un cinquième baseline utile : prolonger la tendance de STL, projeter la saisonnalité et supposer un résidu de moyenne nulle. C'est un peu plus sophistiqué que les précédents mais reste explicable en une phrase et n'exige aucun ajustement. Sur notre fil rouge, il fait souvent quelques points de mieux que le naïf saisonnier, et il constitue une deuxième ligne du tableau à retenir avant d'entrer dans ARIMA.
def par_recomposition(train_log, horizon, s=7):
from statsmodels.tsa.seasonal import STL
resultat = STL(train_log, period=s, robust=True).fit()
# Prolongement lineaire de la tendance sur l'horizon voulu.
x = np.arange(len(resultat.trend))
pente, ordonnee = np.polyfit(x[-90:], resultat.trend.values[-90:], deg=1)
x_futur = np.arange(len(train_log), len(train_log) + horizon)
tend_fut = pente * x_futur + ordonnee
# La saisonnalite se replie de facon cyclique.
dernieres_saisons = resultat.seasonal.values[-s:]
sais_fut = np.tile(dernieres_saisons, int(np.ceil(horizon / s)))[:horizon]
index = pd.date_range(train_log.index[-1] + pd.Timedelta(days=1), periods=horizon, freq="D")
return pd.Series(np.exp(tend_fut + sais_fut), index=index)
L'exponentielle à la fin ramène du log à l'espace des ventes. Ce baseline reste explicable en réunion, ce qui est un critère décisif quand il faut convaincre une direction opérationnelle.
Avant tout modèle savant, calculez ces cinq lignes — naïf, naïf saisonnier, moyenne, dérive, recomposition — sur la période exacte de test que vous utiliserez plus tard. Elles constituent votre socle : chaque modèle du reste du cours viendra s'y ajouter, et le verdict du module 10 se lira dans cette même colonne « MAE ». Un projet qui n'a pas ce socle avant d'entrer dans SARIMA se retrouve incapable de justifier ses choix quatre semaines plus tard.
En résumé
- Le naïf saisonnier est la référence honnête sur les séries saisonnières ; le naïf simple, la moyenne et la dérive complètent le tableau.
- Un modèle savant doit battre le naïf saisonnier de 10 à 30 % au minimum pour justifier sa complexité opérationnelle.
- Le baseline par recomposition (tendance STL + saisonnalité projetée) est un excellent cinquième modèle explicable en une phrase.
- Ces cinq références détectent les fuites : un score étrangement bon face à un naïf robuste signale presque toujours une fuite du futur.
Module suivant : ARIMA et SARIMA, les modèles statistiques qui prolongent les intuitions de la stationnarité et de l'ACF/PACF.