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.
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
- Modèle multi-pas unique : un seul modèle sort tout l’horizon.
- Plusieurs modèles mono-pas (stratégie directe) : un modèle par horizon.
- Stratégie récursive : on réutilise un modèle mono-pas en réinjectant ses prédictions.
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
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).
- 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
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)))