Biais/Variance

Cette section est basée sur James et al. (2021), chapitre 2.

Quel est notre objectif ?

Nous souhaitons modéliser la relation entre une variable réponse \(Y\), pouvant être quantitative, qualitative ou de nature différente, et un ensemble de \(p\) variables explicatives \(X = (X_{1}, \dots, X_{p})\), elles aussi de (potentiellement) différents types. L’idée centrale est qu’il existe un relation entre \(Y\) et les variables explicatives \(X\). De manière générales, nous modélisons cette relation par le modèle :

\[Y = f(X) + \varepsilon. \tag{1}\]

Ici, \(f\) est une fonction déterministe (non-aléatoire) représentant l’information systématique que les variables explicatives \(X_{1}, \dots, X_{p}\) apportent sur \(Y\), et \(\varepsilon\) est un terme d’erreur aléatoire, modélisant les variations de \(Y\) non expliquées par \(X\). Dans le cadre de ce cours, nous ferons les hypothèses suivantes : la variable aléatoire \(\varepsilon\) est indépendente de des variables explicatives \(X\), \(\mathbb{E}[\varepsilon] = 0\) et \(\mathrm{Var}(\varepsilon) = \sigma^2\). Le modèle Équation 1 est général. Il sert de cadre pour l’ensemble des méthodes que nous allons étudier, même lorsque la forme explicite de \(f\) n’est pas connue.

La Figure 1 illustre les différents éléments du modèle: les données observées \((X_i, Y_i)\), la fonction \(f\) (en bleu) et les écarts aléatoires \(\varepsilon_i\) représentés par des lignes pointillées.

Code
library(tibble)
library(dplyr)

generate_noisy_data <- function(n = 100, noise_levels = c(0, 0.1, 0.3, 0.5)) {
  # x values (avoid 0 for log)
  x_vals <- seq(0.01, 0.99, length.out = n)
  
  # True function
  f <- function(x) 4 * x * (1 - x) * log(x) + 2
  
  # Generate data for each noise level
  data <- lapply(noise_levels, function(sigma) {
    y_true <- f(x_vals)
    y_noisy <- y_true + rnorm(n, mean = 0, sd = sqrt(sigma))
    
    tibble(
      x = x_vals,
      y = y_noisy,
      noise = sigma
    )
  }) %>% bind_rows()
  
  return(data)
}

# Example usage
set.seed(123)

noise_levels <- seq(0, 0.5, by=0.01)
df <- generate_noisy_data(noise_levels = noise_levels)
write.csv(df, './data.csv')
Figure 1: Les différents éléments du modèle. Les points représentent les données observées \((X_i, Y_i)\). La courbe bleue représente la fonction \(f\) et les lignes pointillées représentent l’erreur associée à chaque observation.

Dans la suite du cours, nous verrons différentes méthodes permettant d’estimer la fonction \(f\) à partir de données. Cependant avant d’étudier comment contruire un estimateur \(\widehat{f}\) de \(f\), nous allons nous interroger sur la qualité d’un tel estimateur : que signifie “bien estimer” \(f\) ? Et comment évaluer la qualité de l’estimation ?

NoteExemple : Régression linéaire simple

Dans ce cadre très simple, nous faisons l’hypothèse que la fonction \(f\) est de la forme : \(f(x) = a x + b\). Dans ce cas, l’estimation de la fonction \(f\) se résume à l’estimation des coefficients \(a\) et \(b\).

AstuceRemarque : Compromis entre exactitude et interprétabilité

Dépendant de l’objectif de l’étude, nous devons généralement faire un choix entre l’exactitude de nos prédictions et l’interprétabilité de notre modèle. Un modèle simple, comme la régression linéaire, sera facile à interpréter mais capturera mal des relations complexes. À l’inverse, un modèle plus flexible, comme une forêt aléatoire, aura de meilleur prédiction, mais sera plus difficilement interprétable. Le choix dépend donc de l’objectif de l’analyse : compréhension ou performance prédictive ?

AstuceRemarque : No free lunch in statistics

Pourquoi ne pas simplement utiliser le modèle “ultime”, celui qui serait toujours optimal quelque soit le jeu de données ? Parce qu’un tel modèle n’existe pas ! Il n’y a pas de méthode universellement meilleure pour tous les jeux de données et tous les objectifs. Une méthode performante dans un contexte donné peut échouer ailleurs. Il faut donc toujours adapter l’approche au problème (explication, prédiction, classification, …).

Comment mesurer la qualité d’un estimateur ?

Une fois que nous disposons d’un estimateur \(\widehat{f}\) de la fonction \(f\), obtenu à partir de \(n\) observations \((y_1, x_1), \dots, (y_n, x_n)\), nous cherchons à évaluer la précision des prédictions \(\widehat{Y} = \widehat{f}(X)\). L’idée est de vérifier dans quelle mesure \(\widehat{Y}\) est proche de la vraie valeur de \(Y\).

AvertissementDéfinition : Erreur quadratique moyenne

Lorsque \(Y\) est une variable quantitative, une mesure classique de la qualité de \(\widehat{f}\) est l’erreur quadratique moyenne (mean square error, MSE) : \[MSE(Y, \widehat{Y}) = \frac{1}{n} \sum_{i = 1}^{n} \left( y_i - \widehat{y}_i\right)^2 = \frac{1}{n} \sum_{i = 1}^{n} \left( y_i - \widehat{f}(x_i) \right)^2,\]\(\widehat{y}_i = \widehat{f}(x_i)\) est la prédiction que \(\widehat{f}\) donne pour l’observation \(x_i\).

Une MSE faible indique que les prédictions sont proches des observations. Nous pouvons aussi l’interpréter comme la distance moyenne entre les valeurs observées et les valeurs prédites. Nous cherchons donc à avoir une distance moyenne faible.

Dans le cas où \(Y\) est une variable qualitative, e.g. une classe ou un label, on utilise une autre mesure : le taux d’erreur.

AvertissementDéfinition: Taux d’erreur

Lorsque \(Y\) est une variable qualitative, une mesure classique de la qualité de \(\widehat{f}\) est le taux d’erreur (error rate, ER) : \[ER(Y, \widehat{Y}) = \frac{1}{n} \sum_{i = 1}^{n} \mathbb{1}(y_i \neq \widehat{y}_i) = \frac{1}{n} \sum_{i = 1}^{n} \mathbb{1}(y_i \neq \widehat{f}(x_i)).\]\(\widehat{y}_i = \widehat{f}(x_i)\) est la prédiction que \(\widehat{f}\) donne pour l’observation \(x_i\).

Le taux d’erreur mesure la proportion de mauvaises prédictions. Il s’agit, là encore, d’une mesure de la distance moyenne entre \(Y\) et \(\widehat{Y}\), adaptée aux variables qualititatives.

Le compromis biais/variance

Notre objectif est souvent de minimiser l’erreur de prédiction, non seulement sur les données observées, mais surtout sur de nouvelles données (récupérée après avoir estimer le modèle). Pour cela, nous nous intéressons à l’erreur de prédiction : \[\mathbb{E}\left[ \left( Y - \widehat{Y} \right)^2 \right] = \mathbb{E}\left[ \left( Y - \widehat{f}(X) \right)^2 \right].\]

Cette erreur peut se décomposer en trois composantes :

  • Le biais : l’erreur due à une approximation systématique, e.g. si on impose un modèle linéaire alors que la relation est non linéaire.

  • La variance : la sensibilité de l’estimateur aux fluctuations de l’échantillon d’apprentissage.

  • L’erreur irréductible : la variance intrinsèque du bruit \(\varepsilon\), notée \(\sigma^2\).

ImportantDécomposition biais/variance

On a : \[\mathbb{E}\left[ (Y - \widehat{Y})^2 \right] = \mathbb{E}\left[ (Y - \widehat{f}(X))^2 \right] = \mathrm{Biais}(\widehat{f}(X))^2 + \mathrm{Var}(\widehat{f}(X)) + \sigma^2.\]

Tout d’abord, montrons que l’espérance de l’erreur de l’estimateur se décompose en une partie réductible et en une partie irréductible.

\[\begin{align*} \mathbb{E}\left[ \left( Y - \widehat{Y} \right)^2 \right] &= \mathbb{E}\left[ \left( Y - \widehat{f}(X) \right)^2 \right] \\ &= \mathbb{E}\left[ \left( f(X) + \varepsilon - \widehat{f}(X) \right)^2 \right] \\ &= \mathbb{E}\left[ \left( f(X) - \widehat{f}(X) \right)^2 \right] + 2\mathbb{E}\left[ \left( f(X) - \widehat{f}(X) \right)\varepsilon \right] + \mathbb{E}[\varepsilon^2] \\ &= \mathbb{E}\left[ \left( f(X) - \widehat{f}(X) \right)^2 \right] + 2\mathbb{E}\left[ \left( f(X) - \widehat{f}(X) \right) \right] \underbrace{\mathbb{E}\left[ \varepsilon \right]}_{= 0} + \sigma^2 \\ &= \underbrace{\mathbb{E}\left[ \left( f(X) - \widehat{f}(X) \right)^2 \right]}_{\text{réductible}} + \underbrace{\sigma^2}_{\text{irréductible}}. \end{align*}\]

On utilise la linéarité de l’espérance et le fait que \(X\) et \(\varepsilon\) soient indépendants. On s’intéresse maintenant à la partie “réductible”. L’astuce est de faire apparaître \(\mathbb{E}\left[ \widehat{f}(X) \right]\).

\[\begin{align*} \mathbb{E}\left[ \left( f(X) - \widehat{f}(X) \right)^2 \right] &= \mathbb{E}\left[ \left( f(X) - \mathbb{E}\left[ \widehat{f}(X) \right] + \mathbb{E}\left[ \widehat{f}(X) \right] - \widehat{f}(X) \right)^2 \right] \\ &= \underbrace{\mathbb{E}\left[ \left( f(X) - \mathbb{E}\left[ \widehat{f}(X) \right] \right)^2 \right]}_{\text{A}} \\ &\quad - 2 \underbrace{\mathbb{E}\left[ \left( f(X) - \mathbb{E}\left[ \widehat{f}(X) \right] \right) \left( \widehat{f}(X) - \mathbb{E}\left[ \widehat{f}(X) \right] \right) \right]}_{\text{B}} \\ &\quad + \underbrace{\mathbb{E}\left[ \left( \widehat{f}(X) - \mathbb{E}\left[ \widehat{f}(X) \right] \right)^2 \right]}_{\text{C}}. \end{align*}\]

A. La fonction \(f(X)\) n’étant pas aléatoire, on a \(\mathbb{E}\left[ f(X) \right] = f(X)\) et donc

\[\begin{align*} \mathbb{E}\left[ \left( f(X) - \mathbb{E}\left[ \widehat{f}(X) \right] \right)^2 \right] &= \mathbb{E}\left[ \left( \mathbb{E}\left[ f(X) - \widehat{f}(X) \right] \right)^2 \right] \\ &= \mathbb{E}\left[ f(X) - \widehat{f}(X) \right]^2 \\ &= \text{Biais}(\widehat{f}(X))^2. \end{align*}\]

B. En développant l’expression et en utilisant l’indépendance des variables, on trouve que \(B = 0\).

C. En utilisant la définition de la variance,

\[\mathbb{E}\left[ \left( \widehat{f}(X) - \mathbb{E}\left[ \widehat{f}(X) \right] \right)^2 \right] = \mathrm{Var}(\widehat{f}).\]

Finalement, on a

\[\mathbb{E}\left[ \left( f(X) - \widehat{f}(X) \right)^2 \right] = \text{Biais}(\widehat{f}(X))^2 + \mathrm{Var}(\widehat{f}(X)).\]

D’où le résultat.

Cette décomposition met en avant un compromis fondamental en analyse de données :

  • Si on choisit un modèle peu flexible, le biais sera élevé, mais la variance sera faible.

  • Si on choisit un modèle flexible, le biais sera faible, mais la variance peut être très élevée.

Notre objectif est donc de trouver un juste équilibre entre biais et variance, i.e. un modèle qui prédit correctement, tout en étant généralisable à de nouvelles données. La Figure 2 (a) présente un jeu de données et différents estimateurs \(\widehat{f}\). En faisant varier le paramètre \(\lambda\), on obtient des modèles plus ou moins flexible (lorsque \(\lambda = 0.15\), le modèle est flexible et lorsque \(\lambda = 1\), le modèle est rigide). La Figure 2 (b) montre la valeur du biais, de la variance et de la MSE pour les modèles estimés pour la Figure 2 (a). On remarque que plus \(\lambda\) est petit, plus la variance est grande, mais le biais est petit (le modèle est flexible). Inversement, plus \(\lambda\) est grand, plus le biais est grand et la variance petite (le modèle est rigide). La courbe de MSE en fonction du paramètre est une courbe en U. Comme on cherche à minimiser la MSE, i.e. à faire un compromis entre le biais et la variance, on peut prendre \(\lambda = 0.5\).

Code
# Load packages
library(ggplot2)
library(dplyr)
library(tidyr)

set.seed(42)

# 1. Simulate a single dataset
n <- 100
sigma2 <- 0.1
x <- sort(runif(n, 0.05, 1))
y <- 4 * x * (1 - x) * log(x) + 2 + rnorm(n, 0, sqrt(sigma2))
df <- data.frame(x = x, y = y, span = 0)

# 2. Define grid and spans to compare
x_grid <- seq(0.05, 1, length.out = 300)
spans_to_plot <- seq(0.1, 1, by = 0.1)

# 3. Compute loess fits for each span
fits <- lapply(spans_to_plot, function(s) {
  loess_model <- loess(y ~ x, data = df, span = s)
  y_hat <- predict(loess_model, newdata = data.frame(x = x_grid))
  data.frame(x = x_grid, y = y_hat, span = s)
})

fit_df <- bind_rows(fits)
fit_df <- fit_df |> add_row(df)  # Add data points
 
write.csv(fit_df, './data_fit.csv')


# Parameters
n_sim <- 100          # number of simulated datasets
spans <- seq(0.1, 1, by = 0.05)  # LOESS smoothing parameters
x_grid <- seq(0.1, 1, length.out = 200)
f_true <- 4 * x_grid * (1 - x_grid) * log(x_grid) + 2

# Storage for predictions
results <- list()

for (s in spans) {
  pred_matrix <- matrix(NA, nrow = length(x_grid), ncol = n_sim)
  
  for (sim in 1:n_sim) {
    x <- sort(runif(n, 0.01, 1.1))
    y <- 4 * x * (1 - x) * log(x) + 2 + rnorm(n, 0, sqrt(sigma2))
    df <- data.frame(x = x, y = y)
    
    # Fit loess model with span = s
    model <- loess(y ~ x, data = df, span = s, degree = 2)
    pred <- predict(model, newdata = data.frame(x = x_grid), )
    
    pred_matrix[, sim] <- pred
  }
  
  # For each point in x_grid, compute bias², variance, MSE
  mean_pred <- rowMeans(pred_matrix, na.rm = TRUE)
  bias2 <- (mean_pred - f_true)^2
  var_pred <- apply(pred_matrix, 1, var, na.rm = TRUE)
  mse <- bias2 + var_pred
  
  results[[as.character(s)]] <- data.frame(
    span = s,
    Biais2 = mean(bias2),
    Variance = mean(var_pred),
    MSE = mean(mse)
  )
}

# Combine and reshape results
results_df <- bind_rows(results)
results_long <- pivot_longer(
  results_df,
  cols = c("Biais2", "Variance", "MSE"),
  names_to = "component", values_to = "value"
)

write.csv(results_long, './data_mse.csv')
(a) Différents estimateurs \(\widehat{f}\).
(b) Différentes parties de l’erreur.
Figure 2: Illustration du compromis biais/variance. Le paramètre \(\lambda\) contrôle la flexibilité du modèle, plus \(\lambda\) est petit, plus le modèle est flexible.

De manière générale, lorsque la flexibilité augmente, la diminution du biais est plus importante que l’augmentation de la variance, ce qui fait décroître l’erreur de prédiction. Cependant, à partir d’un certain niveau de flexibilité, le biais devient négligeable, et toute baisse supplémentaire est compensée par l’augmentation rapide de la variance. L’erreur de prédiction commence donc à croître. Il en résulte une courbe en U de l’erreur de prédiction en fonction de la flexibilité du modèle : un modèle trop rigide engendre un fort biais, tandis qu’un modèle trop flexible conduit à une trop grande variance.

AstuceRemarque : Pourquoi un compromis ?

Il est toujours possible de construire un modèle très flexible avec un biais nul, e.g. un modèle qui passe par tous les points d’observations, mais qui aura une variance énorme. À l’opposé, un modèle trop rigide, e.g. une constante, aura un biais très important mais une variance presque nulle. Le compromis biais/variance consiste à choisir un modèle qui contrôle ces deux quantités.

Les références

James, Gareth, Daniela Witten, Trevor Hastie, et Robert Tibshirani. 2021. An Introduction to Statistical Learning: With Applications in R. Springer Texts in Statistics. New York, NY: Springer US. https://doi.org/10.1007/978-1-0716-1418-1.