Valider une prévision temporelle sans utiliser le futur
Découper chronologiquement et apprendre les transformations sur le passé.
Dans ce guide
La réponse courte
En prévision, entraînez sur les premières observations et évaluez sur les suivantes. Un découpage aléatoire peut fournir une information indisponible au moment d’une véritable prévision.
Définir le moment réel de la prévision
Un magasin prévoit chaque dimanche soir la demande des sept jours suivants. L’évaluation doit reproduire ce moment : les ventes de la semaine à venir et les informations publiées après dimanche ne sont pas disponibles. Une séparation aléatoire mélange passé et futur et peut surestimer l’intérêt opérationnel du modèle.
Définissez l’origine, l’horizon et la disponibilité de chaque variable. Le calendrier est connu à l’avance ; une température observée ou un total de ventes révisé ne l’est pas toujours. Pour la météo, utilisez la prévision disponible à cette date plutôt que l’observation ultérieure si cela correspond à l’usage prévu.
Définir l’horizon
Adaptez la fenêtre de test à l’horizon prévu. Apprenez la normalisation et les autres transformations uniquement sur les données d’entraînement. Les variables glissantes doivent utiliser l’information disponible au moment du calcul.
from sklearn.model_selection import TimeSeriesSplit
observations = list(range(12))
splitter = TimeSeriesSplit(n_splits=3, test_size=2, gap=1)
for train, test in splitter.split(observations):
print(train.tolist(), test.tolist())Lire un découpage chronologique concret
Le petit exemple ci-dessus contient 12 observations ordonnées, trois fenêtres de deux observations et un intervalle d’exclusion d’une ligne. Le premier entraînement utilise 0–4 et l’évaluation 6–7 ; ensuite 0–6 et 8–9 ; enfin 0–8 et 10–11.
Cet intervalle représente une exclusion choisie, pas une solution universelle aux fuites. Adaptez-le aux délais de publication ou aux cibles qui se chevauchent. TimeSeriesSplit compte des lignes : deux lignes ne signifient pas forcément deux jours. Vérifiez tri, doublons, périodes absentes et régularité avant d’interpréter les fenêtres.
Vérifier les hypothèses temporelles
Contrôlez l’ordre, les dates manquantes et les intervalles. Ajoutez un écart si les délais ou les étiquettes qui se chevauchent l’exigent. Réservez une dernière période indépendante.
Chercher les fuites en dehors du découpage
Ajustez normalisation, imputation et sélection de variables sur chaque partie d’entraînement uniquement. Appliquez ensuite ces transformations à la partie future. Un Pipeline regroupe les traitements appris, mais ne répare pas une variable contenant déjà des informations futures.
Pour des ventes quotidiennes, une moyenne mobile au jour t doit utiliser les observations antérieures, par exemple shift(1).rolling(7).mean(). Une fenêtre centrée peut inclure le futur. Pour prévoir toute une semaine d’un coup, les ventes réelles de ses premiers jours sont également inconnues : ne les utilisez pas pour prévoir les suivants.
Comparer à une prévision simple avant d’optimiser
Choisissez une référence adaptée : dernière valeur connue ou période correspondante du cycle saisonnier précédent. Comparez sur les mêmes origines et horizons. Dans le calcul illustratif ci-dessous, les valeurs réelles 100, 110 et 90 avec trois prévisions à 100 donnent une MAE d’environ 6,67 dans l’unité de la cible.
Examinez les erreurs par horizon et période ; une moyenne peut masquer les mauvaises journées de forte demande. Les métriques en pourcentage deviennent délicates près de zéro. Gardez une période finale qui ne sert pas au choix du modèle et réévaluez lorsque les conditions changent.
actual = [100, 110, 90]
predicted = [100, 100, 100]
mae = sum(abs(a - p) for a, p in zip(actual, predicted)) / len(actual)
print(round(mae, 2))Points à vérifier
- Découpez chronologiquement.
- Apprenez les transformations dans chaque pli.
- Vérifiez la disponibilité des variables.
Champ d’application
TimeSeriesSplit utilise les positions des lignes. Vérifiez l’espacement régulier pour comparer des fenêtres temporelles.