Prévision de séries temporelles et apprentissage supervisé

Version portfolio : formulation, stratégies multi-pas, prétraitements, baselines, équations, figures et code.

Pour recruteurs (lecture rapide)

J’aborde la prévision comme un problème supervisé en respectant strictement l’ordre temporel. Ma méthode met l’accent sur :

  • Formulation claire : entrées/sorties uni- ou multivariées, horizon mono-pas vs multi-pas.
  • Baselines solides : modèles classiques (ARIMA/ETS) et naïfs avant le deep learning.
  • Validation adaptée : walk-forward / rolling (pas de CV aléatoire).
  • Préparation des données : gestion NA, normalisation, suppression de tendance, différenciation.
  • Choix déployables : si une méthode classique est aussi performante, je la privilégie.
Walk-forward Prévision récursive Feature engineering Baselines-first

La prévision comme problème supervisé

La prévision peut être formulée en régression (cible continue : température, prix, demande) ou en classification (cible discrète : “ensoleillé” vs “non ensoleillé”). Le paradigme reste supervisé : entrées historiques → sorties futures, avec une contrainte forte : l’ordre du temps.

Structures entrée–sortie

Définitions

  • Entrée univariée : une seule série en entrée.
  • Entrée multivariée : plusieurs séries en entrée.
  • Sortie univariée : une seule série à prédire.
  • Sortie multivariée : plusieurs séries à prédire.

Exemple concret

Prédire le nombre de jours ensoleillés dans un mois futur à partir de : jours ensoleillés, température, pression atmosphérique → entrée multivariée – sortie univariée.

Dans les cas entrée multivariée–sortie univariée, on considère souvent une série comme principale et les autres comme variables explicatives.

Pour les cas entrée multivariée–sortie multivariée, on distingue souvent : many-to-one vs many-to-many (selon qu’on prédit un point ou une séquence).

Mono-pas vs multi-pas

Mono-pas : prédire la valeur suivante. Multi-pas : prédire plusieurs valeurs futures (plus difficile, car les erreurs s’accumulent).

Trois stratégies de prévision multi-pas

  1. Modèle multi-pas unique : un seul modèle sort tout l’horizon.
  2. Plusieurs modèles mono-pas (stratégie directe) : un modèle par horizon.
  3. Stratégie récursive : on réutilise un modèle mono-pas en réinjectant ses prédictions.
Cas pratique : si tu as un modèle mono-pas et que tu dois faire 2 pas sans entraîner un nouveau modèle, tu peux utiliser la stratégie récursive : prédire \( \hat{y}_{t+1} \), l’ajouter à la fenêtre, puis prédire \( \hat{y}_{t+2} \).

Méthodes pour remplir les valeurs manquantes (N/A)

  • Interpolation linéaire
  • Remplacement par la moyenne de la série
  • Remplissage par zéro (si 0 a un sens réel)
  • Remplissage par la valeur suivante connue (back-fill)
  • Remplissage par la dernière valeur connue (forward-fill)

Prétraitements principaux

  • Normalisation / scaling
  • Suppression de tendance (detrending)
  • Différenciation
Une différenciation simple : \( x'_t = x_t - x_{t-1} \). Elle aide souvent à réduire la non-stationnarité.

Fonctions de perte en régression (équations)

MAE (erreur absolue moyenne) : \[ \mathrm{MAE} = \frac{1}{n}\sum_{i=1}^n \left|y_i - \hat{y}_i\right| \]

MSE (erreur quadratique moyenne) : \[ \mathrm{MSE} = \frac{1}{n}\sum_{i=1}^n \left(y_i - \hat{y}_i\right)^2 \]

MAE est plus robuste aux outliers ; MSE pénalise davantage les grosses erreurs.

Évaluation : ce qui marche (et ce qui ne marche pas)

La validation croisée aléatoire est souvent mauvaise pour les séries temporelles car elle casse la dépendance temporelle. On utilise plutôt une évaluation walk-forward (rolling).

Règle d’or : comparer systématiquement à des alternatives. Si une méthode classique est très précise, la choisir est souvent le meilleur compromis (simplicité + interprétabilité).
  • Baseline naïf (persistence) : \( \hat{y}_{t+1} = y_t \)
  • Baselines classiques : ARIMA / ETS / seasonal naïf
  • Baselines ML : régression linéaire sur lags, arbres, petits réseaux

Feature engineering & fenêtres glissantes

Feature engineering : enrichir les entrées (lags, moyennes mobiles, volatilité, variables calendrier, etc.).

Fenêtre glissante : transformer les séries en échantillons supervisés (passé → futur).

Figures

Exemple de série (tendance + bruit) temps → valeur
Illustration simple : en pratique, on respecte l’ordre temporel et on valide sur des segments futurs.
Fenêtre glissante → données supervisées fenêtre d’entrée cible On décale la fenêtre pour créer de nombreux couples (X, y).
La fenêtre glissante transforme la séquence en échantillons supervisés : passé/features → futur (mono-pas ou multi-pas).

Extraits Python

1) Fenêtre glissante (univariée)

# Transformer une série 1D en (X, y) supervisés
import numpy as np

def make_sliding_window(series, window=24, horizon=1):
    series = np.asarray(series, dtype=float)
    X, y = [], []
    for t in range(window, len(series) - horizon + 1):
        X.append(series[t-window:t])
        y.append(series[t:t+horizon])  # horizon=1 → cible mono-pas
    return np.array(X), np.array(y)

ts = np.sin(np.linspace(0, 10, 200)) + 0.1*np.random.randn(200)
X, y = make_sliding_window(ts, window=20, horizon=1)
print(X.shape, y.shape)

2) Prévision multi-pas récursive avec un modèle mono-pas

# Stratégie récursive : prédire → réinjecter → prédire…
def recursive_forecast(model_predict_one, last_window, steps=5):
    window = np.array(last_window, dtype=float).copy()
    preds = []
    for _ in range(steps):
        yhat = float(model_predict_one(window))
        preds.append(yhat)
        window = np.roll(window, -1)
        window[-1] = yhat
    return np.array(preds)

# Exemple de "modèle" : baseline persistance
def persistence_model(window):
    return window[-1]

last = ts[-20:]
print(recursive_forecast(persistence_model, last, steps=3))

3) Walk-forward (validation adaptée séries temporelles)

# Évaluation rolling : entraînement sur le passé, test sur le futur
from sklearn.linear_model import LinearRegression

def walk_forward_mae(series, window=24, start=100, step=1):
    series = np.asarray(series, dtype=float)
    errs = []
    for split in range(start, len(series)-1, step):
        train = series[:split]
        test_next = series[split]

        Xtr, ytr = make_sliding_window(train, window=window, horizon=1)
        model = LinearRegression().fit(Xtr, ytr.ravel())

        last_window = train[-window:]
        pred = model.predict(last_window.reshape(1, -1))[0]
        errs.append(abs(test_next - pred))
    return float(np.mean(errs))

print("MAE walk-forward:", walk_forward_mae(ts, window=20, start=120))

4) Différenciation et reconstruction

# Différenciation simple + inversion
def difference(series):
    series = np.asarray(series, dtype=float)
    return series[1:] - series[:-1], series[0]

def invert_difference(diff_series, first_value):
    out = [first_value]
    for d in diff_series:
        out.append(out[-1] + d)
    return np.array(out)

diff_ts, first = difference(ts)
recovered = invert_difference(diff_ts, first)
print(np.max(np.abs(recovered - ts)))
Note : en entrée multivariée (ex : jours ensoleillés + température + pression), la fenêtre X devient un tenseur (fenêtre × features), et la sortie est univariée ou multivariée selon le besoin.