Quantile Regression : Guide Complet — Régression Quantile

Quantile Regression : Guide Complet — Régression Quantile

Quantile Regression : Guide complet — Régression Quantile

Résumé — La régression quantile est une technique de régression qui prédit des quantiles conditionnels (pas seulement la moyenne) de la distribution de la variable cible. Introduite par Koenker et Bassett en 1978, elle est particulièrement utile quand la distribution des erreurs n’est pas symétrique ou quand on s’intéresse aux extrêmes (risques, valeurs atypiques). Contrairement à la régression des moindres carrés qui donne une prédiction ponctuelle et symétrique, la régression quantile permet de construire des intervalles de prédiction asymétriques adaptés à la réalité des données.


Principe mathématique

1. Limitation de la régression des moindres carrés (OLS)

La régression linéaire classique minimise la somme des carrés des résidus et prédit la moyenne conditionnelle E[Y|X=x]. Problème: elle suppose que les erreurs sont symétriques et homoscédastiques. Dans la réalité, les distributions sont souvent asymétriques (salaires, temps de trajet, prix immobiliers).

2. La fonction de perte check (pinball loss)

Pour prédire le tau-ième quantile conditionnel Q_tau(Y|X=x), on minimise la perte check:

rho_tau(u) = tau · max(u, 0) + (1-tau) · max(-u, 0)
           = max(tau · u, (tau-1) · u)

Où u = y – f(x) est le résidu et tau est dans ]0, 1[. Le quantile tau représente la valeur en dessous de laquelle se trouve tau × 100% des observations.

Pour tau = 0.5 (médiane):

rho_0.5(u) = 0.5 · |u|  →  c'est équivalent à minimiser la MAE

Pour tau = 0.9 (90ème percentile):

rho_0.9(u) = 0.9 · max(u, 0) + 0.1 · max(-u, 0)

Les erreurs positives (sous-prédiction) sont pénalisées 9x plus que les erreurs négatives (sur-prédiction), ce qui pousse le modèle vers le haut de la distribution.

3. Régression quantile linéaire

Le modèle linéaire quantile estime:

Q_tau(Y|X=x) = x^T · beta_tau
beta_tau = argmin_beta somme_i rho_tau(y_i - x_i^T · beta)

Remarquez que les coefficients beta_tau dépendent de tau: la régression du 90ème percentile donne des poids différents de celle du 10ème percentile. C’est fondamental: chaque quantile capture une relation différente entre X et Y.

4. Intervalles de prédiction

Pour obtenir un intervalle de prédiction à 90%, on entraîne deux modèles:
– tau = 0.05 → borne inférieure
– tau = 0.95 → borne supérieure

L’intervalle [Q_0.05(Y|x), Q_0.95(Y|x)] contient 90% de la distribution conditionnelle de Y sachant X=x.

5. Régression quantile non-linéaire (Deep Quantile Regression)

On peut remplacer le modèle linéaire par un réseau de neurones:

Q_tau(Y|X=x) = f_theta(x)  où f est un MLP
theta_tau = argmin_theta somme_i rho_tau(y_i - f_theta(x_i))

Un avantage: on peut entraîner un seul réseau pour prédire plusieurs quantiles simultanément en ayant une dernière couche avec K sorties (une par quantile) et une loss totale:

L = somme_k somme_i rho_{tau_k}(y_i - f_theta(x_i)_k)

Intuition

La régression classique vous dit: « le trajet prendra 30 minutes en moyenne ». Mais en réalité, parfois c’est 20 minutes, parfois 50. La régression quantile vous dit: « dans 90% des cas, le trajet dure entre 22 et 42 minutes ».

C’est la différence entre une météo qui donne la température moyenne et une qui donne le min et le max — la deuxième vous aide vraiment à vous habiller.


Implémentation Python

1. Avec scikit-learn

import numpy as np
from sklearn.linear_model import QuantileRegressor
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

# Données synthétiques avec hétéroscédasticité
np.random.seed(42)
n = 200
X = np.random.uniform(0, 10, n).reshape(-1, 1)
y = 2 * X.ravel() + np.random.normal(0, X.ravel(), n)  # variance augmente avec X

# Régression sur 3 quantiles
quantiles = [0.1, 0.5, 0.9]
fits = {}

for q in quantiles:
    qr = QuantileRegressor(quantile=q, alpha=0.1, solver='highs')
    qr.fit(X, y)
    fits[q] = qr

X_plot = np.linspace(0, 10, 100).reshape(-1, 1)

fig, ax = plt.subplots(figsize=(10, 6))
ax.scatter(X, y, alpha=0.5, label='Données', c='blue')

colors = ['red', 'green', 'red']
linestyles = ['--', '-', '--']
for i, q in enumerate(quantiles):
    y_pred = fits[q].predict(X_plot)
    ax.plot(X_plot, y_pred, color=colors[i], linestyle=linestyles[i],
            label=f'Quantile {q}')

# Zone d'intervalle 80%
ax.fill_between(X_plot.ravel(),
                fits[0.1].predict(X_plot),
                fits[0.9].predict(X_plot),
                alpha=0.15, color='green', label='Intervalle 80%')

ax.set_xlabel('X'); ax.set_ylabel('y')
ax.set_title('Régression Quantile sur données hétéroscédastiques')
ax.legend()
plt.tight_layout()
plt.savefig('quantile_regression.png', dpi=150)

2. Deep Quantile Regression avec PyTorch

import torch
import torch.nn as nn
import numpy as np

def pinball_loss(pred, target, tau):
    """Fonction de perte pinball pour régression quantile."""
    residuals = target - pred
    return torch.mean(torch.max(tau * residuals, (tau - 1) * residuals))

class QuantileNet(nn.Module):
    """Réseau neuronal prédisant plusieurs quantiles simultanément."""
    def __init__(self, input_dim=1, n_quantiles=3):
        super().__init__()
        self.network = nn.Sequential(
            nn.Linear(input_dim, 64), nn.ReLU(),
            nn.Linear(64, 64), nn.ReLU(),
            nn.Linear(64, n_quantiles)  # Une sortie par quantile
        )
        self.quantiles = torch.linspace(0.1, 0.9, n_quantiles)

    def forward(self, x):
        return self.network(x)

# Données
X = torch.randn(1000, 1)
y = 3 * X + torch.randn(1000, 1) * (1 + 0.5 * torch.abs(X))

# Entraînement
model = QuantileNet(input_dim=1, n_quantiles=3)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

for epoch in range(200):
    preds = model(X)  # batch x n_quantiles
    loss = 0
    for k, tau in enumerate(model.quantiles):
        loss += pinball_loss(preds[:, k], y.squeeze(), tau)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 50 == 0:
        print(f'Epoch {epoch} | Loss: {loss.item():.4f}')

# Prédictions
X_test = torch.linspace(-3, 3, 100).reshape(-1, 1)
with torch.no_grad():
    preds = model(X_test)
    for k, tau in enumerate(model.quantiles):
        q_val = f'{tau:.1f}'
        print('Quantile ' + str(q_val) + ': ' + str(preds[50, k].item()))

Hyperparamètres

Hyperparamètre Valeur typique Description
quantile (tau) 0.1, 0.5, 0.9 Quantiles à prédire
alpha 0.01-1.0 Régularisation L1 (pour QuantileRegressor sklearn)
solver ‘highs’ / ‘interior-point’ Solveur d’optimisation linéaire
learning_rate 0.001-0.01 Pour Deep Quantile Regression

Avantages

  1. Pas d’hypothèse de normalité : Contrairement à OLS, la régression quantile ne suppose pas des erreurs gaussiennes. Elle fonctionne avec n’importe quelle distribution.
  2. Robuste aux outliers : La médiane (tau=0.5) est beaucoup plus robuste aux valeurs extrêmes que la moyenne. Un seule valeur aberrante ne change pas la médiane mais peut déplacer la moyenne de manière significative.
  3. Vue complète de la distribution : Prédire plusieurs quantiles donne une image complète de comment Y varie en fonction de X, y compris dans les queues de distribution.
  4. Interprétation directe : L’intervalle [Q_0.05, Q_0.95] a une interprétation fréquentiste naturelle: 90% des observations y tombent.

Limites

  1. Croisement des quantiles (quantile crossing): Les quantiles prédits peuvent se croiser (Q_0.9 < Q_0.1) pour certaines valeurs de X, ce qui est incohérent. Des solutions existent (contraintes d’ordre, régression quantile non-croisante).
  2. Coût computationnel : L’optimisation de la pinball loss est un programme linéaire (pas de solution fermée comme OLS). Pour de grands datasets, c’est plus lent.
  3. Moins interprétable en haute dimension : Avec beaucoup de features, comprendre les coefficients de chaque quantile devient complexe.

Comparaison avec d’autres méthodes d’incertitude

Contrairement aux méthodes bayésiennes (qui modélisent l’incertitude sur les paramètres) ou aux ensembles de modèles (qui moyennent plusieurs prédictions), la régression quantile est purement fréquentiste: elle estime directement les quantiles empiriques de la distribution. Elle est plus simple à implémenter que les GPs et plus interprétable que les ensembles de réseaux profonds.


4 cas d’usage concrets

1. Prévision de la demande énergétique

Les compagnies d’électricité prédisent la demande avec des intervalles de quantiles. Le quantile 0.95 permet de s’assurer qu’il y a assez de capacité pour couvrir 95% des scénarios — essentiel pour éviter les blackouts.

2. Évaluation des risques financiers (Value at Risk)

La VaR (Value at Risk) est essentiellement un quantile (généralement tau=0.01 ou 0.05). La régression quantile permet de prédire la VaR conditionnelle en fonction des variables de marché, adaptant le risque au contexte.

3. Médecine: courbes de croissance pédiatrique

Les courbes de croissance de l’OMS sont basées sur des centiles (quantiles). La régression quantile permet de modéliser la distribution de la taille/poids en fonction de l’âge, du sexe et d’autres covariables.

4. Météorologie: prévision probabiliste

Les services météo utilisent la régression quantile pour produire des prévisions avec intervalles de confiance, permettant aux agriculteurs et aux planificateurs d’évaluer les risques de sécheresse ou d’inondation.


Conclusion

La régression quantile est un outil fondamental pour qui veut aller au-delà de la moyenne et comprendre la distribution complète des données conditionnelles. De l’économie à la médecine en passant par la météorologie, elle fournit des intervalles de prédiction informatifs là où un simple point ne suffit pas.

Les extensions modernes (réseaux de neurones quantiles, quantile crossing avoidance) étendent son applicabilité à des problèmes de grande dimension et de non-linéarité complexe.


Voir aussi


Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.