## Le Compromis Biais-Variance

Trouver le bon modèle est une affaire de compromis : soit il est trop rigide et rate les grandes tendances (le **biais**), soit il est trop fluide et mémorise les moindres détails inutiles, y compris le bruit (la **variance**).

Un bon modèle doit trouver le juste milieu entre deux défauts opposés : **trop simpliste** (il rate les vraies tendances) ou **trop rigoureux** (il mémorise le bruit au lieu d'apprendre). C'est le compromis biais-variance [@bmc_bias_variance].

### Le Biais et le Sous-apprentissage

C'est le défaut d'un modèle trop simpliste, comme un moule en métal rigide incapable d'épouser les courbes d'une figurine (le **sous-apprentissage** ou *underfitting*).

Le **Biais** est l'erreur systématique d'un modèle trop simplet. Il "manque" les vraies tendances des données — comme un moule trop rigide qui ne parvient pas à épouser la forme de la figurine. Le modèle reste grossièrement plat, incapable de capter la structure réelle : c'est le **sous-apprentissage** (*underfitting*) [@cs229_bias_variance; @gfg_bias_variance; @ghadigaonkar_2025_bias].

::: {.callout-note collapse="true"}
## 🔢 Définition formelle (Biais)

$$\text{Biais}(\hat{Y}) = E[\hat{Y}] - Y$$ ([voir le Glossaire](../../glossaire.qmd#symboles-mathématiques-notations))

* **$\hat{Y}$ ("Y-chapeau")** : la prédiction estimée par le modèle. La notation chapeau ($\hat{}$) est la convention standard en statistiques pour désigner un estimateur.
* **$Y$** : la valeur réelle de référence (la vérité terrain).
* **$E[\cdot]$** : l'espérance mathématique (la moyenne théorique attendue des prédictions sur différents jeux d'entraînement).

L'espérance de la prédiction moins la vraie valeur — l'écart *moyen* et *systématique* entre ce que le modèle prédit et la réalité.
:::

### La Variance et le Sur-apprentissage

C'est le défaut d'un modèle trop zélé, comme un moule en silicone trop liquide qui moule aussi la poussière et les rayures de la figurine (le **sur-apprentissage** ou *overfitting*).

La **Variance** représente l'erreur liée à une sensibilité excessive aux fluctuations du jeu d'entraînement. Le modèle procède à une mémorisation du bruit [@ibm_overfitting; @utd_bias_variance] au lieu d'une généralisation.

::: {.callout-note collapse="true"}
## 🔢 Définition formelle (Variance)

$$\text{Variance}(\hat{Y}) = E\left[(\hat{Y} - E[\hat{Y}])^2\right]$$ ([voir le Glossaire](../../glossaire.qmd#symboles-mathématiques-notations))

* **$\hat{Y}$** : la prédiction du modèle.
* **$E[\hat{Y}]$** : la valeur moyenne prédite par le modèle sur tous les entraînements possibles.
* **$E[\cdot]$** (crochets extérieurs) : l'espérance calculée sur l'écart au carré, mesurant ainsi la dispersion.

La mesure de la dispersion des prédictions du modèle autour de sa moyenne pour différents jeux d'entraînement.
:::

Dans notre analogie, la matière du moule est ici beaucoup trop liquide et réactive. Non seulement elle capture parfaitement la forme générale de la figurine, mais elle va jusqu'à s'infiltrer dans la moindre micro-rayure et englober chaque grain de poussière présent sur cet exemplaire précis. Le résultat est un **sur-apprentissage** (*overfitting*). Si vous essayez d'utiliser ce moule ultra-spécifique pour valider une nouvelle figurine légèrement différente, il sera totalement inadapté et produira une erreur importante.

::: {.card .card-window}
:::: {.card-header}
⚖️ Biais et Variance
::::

:::: {.card-control-row .d-flex .flex-column .gap-2}
::::: {.d-flex .align-items-center .gap-3}
[Propriété du matériau (Complexité du modèle) :]{.text-muted .small}

:::::: {#complexity-control}
```{ojs}
//| echo: false
// Curseur allant de 0 (Très Rigide) à 100 (Très Fluide)
viewof complexity = Inputs.range([0, 100], {
  value: 50,
  step: 1
})
```
::::::
:::::
::::

:::: {.card-body}
::::: {#d3-graph-4-container .w-100 .text-center}
:::::
::::
:::

```{ojs}
//| echo: false
// ==========================================
// 🎨 MOTEUR DE RENDU D3 (Graphique 4)
// ==========================================

graph4 = {
  const width = 800;
  const height = 250;

  const svg = d3.create("svg")
    .attr("viewBox", [0, 0, width, height])
    .attr("class", "w-100 h-auto");

  const xScale = d3.scaleLinear().domain([0, 100]).range([50, width - 50]);
  const yScale = d3.scaleLinear().domain([0, 100]).range([height - 30, 30]);

  // Ligne générique D3
  const lineGenerator = d3.line()
    .curve(d3.curveMonotoneX)
    .x(d => xScale(d.x))
    .y(d => yScale(d.moldY));

  // --- 1. LOGIQUE D'INTERPOLATION (Rigide -> Optimal -> Fluide) ---

  // On calcule l'état du modèle en fonction du slider (0 à 100)
  const currentModelData = objectData.map(d => {
    // État 1 : Rigide (Sous-apprentissage / Biais fort) -> Une simple ligne droite (Moyenne Y = 60)
    const yRigid = 60;

    // État 2 : Optimal (Équilibre) -> Le vrai signal sans le bruit (Macro-forme)
    const yOptimal = 60 + 25 * Math.sin(d.x / 12);

    // État 3 : Fluide (Sur-apprentissage / Variance forte) -> Épouse parfaitement le bruit
    const yOverfit = d.y;

    let currentY;

    if (complexity <= 50) {
      // Transition Rigide (0) -> Optimal (50)
      const ratio = complexity / 50;
      currentY = yRigid + (yOptimal - yRigid) * ratio;
    } else {
      // Transition Optimal (50) -> Fluide (100)
      const ratio = (complexity - 50) / 50;
      currentY = yOptimal + (yOverfit - yOptimal) * ratio;
    }

    return { x: d.x, targetY: d.y, moldY: currentY };
  });

  // --- 2. GESTION DU BADGE UI (Diagnostic) ---
  const badge = document.getElementById("complexity-badge");
  let lineColor = "var(--sol-yellow)";

  if (badge) {
    if (complexity < 30) {
      badge.textContent = "SOUS-APPRENTISSAGE (Biais Élevé)";
      badge.dataset.state = "warning";
      lineColor = "var(--sol-orange)";
    } else if (complexity > 70) {
      badge.textContent = "SUR-APPRENTISSAGE (Variance Élevée)";
      badge.dataset.state = "danger";
      lineColor = "var(--sol-red)";
    } else {
      badge.textContent = "GÉNÉRALISATION OPTIMALE";
      badge.dataset.state = "success";
      lineColor = "var(--sol-green)";
    }
  }

  // --- 3. RENDU GRAPHIQUE ---

  // A. Les données brutes (Le Nuage de points représentant l'objet avec ses défauts)
  svg.selectAll(".data-point")
    .data(objectData)
    .enter()
    .append("circle")
    .attr("class", "data-point")
    .attr("cx", d => xScale(d.x))
    .attr("cy", d => yScale(d.y))
    .attr("r", 4)
    .attr("fill", "var(--sol-base01)")
    .attr("opacity", 0.6);

  // B. Optionnel : L'ombre du signal optimal parfait (pour référence visuelle)
  const optimalData = objectData.map(d => ({ x: d.x, moldY: 60 + 25 * Math.sin(d.x / 12) }));
  svg.append("path")
    .datum(optimalData)
    .attr("fill", "none")
    .attr("stroke", "var(--sol-base02)")
    .attr("stroke-width", 2)
    .attr("stroke-dasharray", "4 4")
    .attr("d", lineGenerator);

  // C. Le Modèle (Le Moule avec sa rigidité/fluidité actuelle)
  svg.append("path")
    .datum(currentModelData)
    .attr("fill", "none")
    .attr("stroke", lineColor)
    .attr("stroke-width", 5)
    .attr("stroke-linecap", "round")
    .attr("stroke-linejoin", "round")
    .attr("d", lineGenerator);

  // Projection DOM
  const container = document.getElementById("d3-graph-4-container");
  if (container) {
    container.replaceChildren(svg.node());
  }

  return svg.node();
}

```

### Le Phénomène de Double Descente

Parfois, un très grand modèle que l'on pense condamné au sur-apprentissage recommence mystérieusement à s'améliorer : c'est la **double descente**, une zone où le modèle découvre des règles encore plus simples et robustes.

La courbe classique en U montre que la variance augmente avec la complexité. Cependant, le Deep Learning montre parfois une **Double Descente** (la perte diminue de nouveau pour de très grands modèles).

::: {.callout-note collapse="true"}
## 🔍 Explication de la Double Descente et de l'Unfolding

Selon l'hypothèse de l'unfolding, ce phénomène est souvent un artefact visuel lié à un *scaling* composite (variation simultanée de la taille du modèle et des données) [@comesana_double_descent]. Si l'on fait varier la complexité et les données indépendamment, le modèle réadopte des motifs classiques en U ou en L [@comesana_double_descent].
:::

### L'Impact Stratégique

* **Diagnostic :** Une erreur d'entraînement très faible couplée à une erreur de test élevée indique une variance excessive [@ibm_overfitting; @wandb_learning_curves].
* **Ajustement :** Il faut adapter l'architecture ou régulariser le modèle plutôt que de sur-interpréter les performances [@yates_cross_validation].