Skip to content

Anatomie d'une série temporelle et piège du split aléatoire

Une entreprise SaaS veut prévoir son volume quotidien de tickets support, pour dimensionner son astreinte du lendemain.

import numpy as np
import pandas as pd
n_days = 500
dates = pd.date_range("2024-01-01", periods=n_days, freq="D")
# ... simulation d'un processus ARMA(1,1) autour d'une moyenne de 150 tickets/jour
serie = pd.Series(tickets, index=dates)
print("moyenne:", serie.mean(), "ecart-type:", serie.std())
moyenne: 151.4 ecart-type: 12.8

Pourquoi un split aléatoire est une triche

Section titled “Pourquoi un split aléatoire est une triche”

Le module 4 a introduit GroupShuffleSplit pour éviter qu’une même entité apparaisse des deux côtés du split. Sur une série temporelle, le problème est encore plus radical : mélanger les jours avant de découper reviendrait à entraîner un modèle avec des jours futurs, puis à l’évaluer sur des jours passés — une fuite d’information totale, puisque le modèle « connaîtrait » déjà la suite.

n_test = 30
train, test = serie[:-n_test], serie[-n_test:]

Le split doit être strictement chronologique : les derniers jours, et uniquement eux, forment le test.

baseline_moyenne = np.full(n_test, train.mean())
baseline_persistance = np.concatenate([[train.iloc[-1]], test.values[:-1]])
mae_moyenne = np.mean(np.abs(test.values - baseline_moyenne))
mae_persistance = np.mean(np.abs(test.values - baseline_persistance))
MAE baseline (moyenne): 13.12
MAE baseline (persistance, 'comme hier'): 7.33

Deux réflexes simples, avant tout modèle complexe : prédire la moyenne globale, ou prédire la valeur de la veille (persistance). Ici, la persistance bat largement la moyenne — signe qu’il existe une vraie mémoire d’un jour sur l’autre dans cette série, que la suite du module va chercher à modéliser explicitement plutôt que de l’ignorer.

👉 L’autocorrélation, boussole du choix de modèle


Junior TSAFACK – 12/09/2026