Qu'est-ce qu'une spline ? Des morceaux de courbe recollés

Imagine un nuage de points bruités entre 0 et 10 : ça monte, ça se tasse, puis ça redescend. Une droite n’y arrive pas, et une seule grande formule qui s’enroulerait sur tout le nuage fait vite n’importe quoi. Il reste une idée simple : couper l’axe en tranches et laisser chaque tranche avoir sa propre courbe, à condition que les morceaux se recollent sans accroc. C’est ce qu’on appelle une spline, et tu sauras à la fin la construire, la régler et savoir ce qu’elle ne fait pas.

Sommaire

L’essentiel en 30 secondes

  • Une spline est une courbe faite de petits polynômes raccordés, un par intervalle de l’axe des X.
  • Les points de raccord s’appellent des nœuds ; les contraintes qui y sont imposées rendent la courbe continue et lisse à l’œil nu.
  • Une spline cubique à K nœuds possède 4+K degrés de liberté : c’est le prix de sa souplesse.
  • Tu règles la souplesse par le nombre de nœuds, ou avec une spline de lissage par un seul paramètre \lambda.
  • Une spline décrit une seule variable ; avec plusieurs variables, on additionne une courbe par variable.

Pourquoi une seule formule ne suit pas tout le nuage

Deux réflexes existent pour courber une droite. Le premier impose une seule forme polynomiale sur tout l’axe ; le second découpe l’axe et pose une constante par tranche. Les deux ont le même défaut : une seule forme imposée à tout le domaine, globale pour l’un, plate par morceaux pour l’autre.

Anatomie d’une spline : nœuds, morceaux, raccords

Une spline de régression se construit en trois gestes. On découpe le domaine en intervalles séparés par des nœuds (knots en anglais). On ajuste sur chaque intervalle un polynôme de bas degré, le plus souvent cubique. Et à chaque nœud, on impose des contraintes de raccordement : la courbe finale reste continue, et même dérivable deux fois de suite, c’est-à-dire sans coude ni brisure visible à l’œil nu.

💡 Intuition Chaque nœud est une couture : tu es libre de changer de forme de part et d’autre, mais pas de laisser la couture se voir.

Cette liberté se paie en paramètres. Une spline cubique à K nœuds compte 4+K degrés de liberté : quatre pour le polynôme cubique de base, plus un par nœud. Chaque nœud « consomme » donc un degré de liberté en échange de la contrainte de raccordement qu’il impose.

Il existe une variante, la spline cubique naturelle, qui reste linéaire au-delà des nœuds extrêmes.

Où poser les nœuds ?

Reste une vraie question de réglage : combien de nœuds, et où ? En pratique, on les place souvent à intervalles réguliers en quantiles des données, avec plus de nœuds là où les observations sont denses.

Pour le nombre, on essaie plusieurs valeurs du nombre de degrés de liberté par validation croisée et l’on garde celle qui minimise l’erreur de test estimée. Sur les données de salaires Wage, une spline naturelle à trois ou quatre degrés de liberté suffit déjà à capturer l’essentiel de la relation entre âge et salaire : au-delà, la courbe change très peu.

Le gain est net face à un polynôme de degré équivalent : en laissant la souplesse varier nœud par nœud, la spline évite les oscillations erratiques qu’un polynôme de haut degré développe presque inévitablement près des bords.

La spline de lissage : un seul réglage au lieu des nœuds

Choisir le nombre et l’emplacement des nœuds, c’est deux décisions. La spline de lissage les remplace par une seule : on cherche la fonction g qui minimise

    \[ \sum_{i=1}^n (y_i - g(x_i))^2 + \lambda \int g''(t)^2 \, dt,\]

Lis la formule en deux moitiés. La somme mesure l’écart entre la courbe g et les observations (x_i, y_i). L’intégrale du carré de la dérivée seconde g'' mesure la courbure totale de g : elle punit les courbes qui zigzaguent. Et \lambda \geq 0 règle l’équilibre entre les deux.

Pousse le curseur aux deux bouts. À \lambda = 0, la courbe est libre d’épouser chaque observation : parfait sur l’entraînement, mais absurdement irrégulier. À l’autre bout, avec \lambda très grand, plus aucune courbure n’est tolérée et il ne reste qu’une droite des moindres carrés.

On montre que la solution est toujours une spline cubique naturelle avec un nœud à chaque valeur observée de X ; ce n’est donc plus le nombre de nœuds mais la rugosité qui est contrôlée par \lambda. La souplesse se résume alors par des degrés de liberté effectifs, qui varient de façon continue entre n (quand \lambda = 0) et 2 (quand \lambda \to \infty, une droite).

Une spline en deux lignes de code

Voyons-la sur une vraie question : comment modéliser le salaire (wage) en fonction de l’âge (age) dans le jeu de données Wage ? Les lignes In [n]: sont les commandes saisies dans une session interactive ; ici MS construit la matrice du modèle, sm désigne statsmodels, et Wage est le jeu de données déjà chargé.

In [7]: bs_age = MS([bs('age',
                          internal_knots=[25,40,60],
                          intercept=True)])
        Xbs = bs_age.fit_transform(Wage)
        M = sm.OLS(Wage['wage'], Xbs).fit()

In [11]: ns_age = MS([ns('age', df=4)])
         Xns = ns_age.fit_transform(Wage)
         M_ns = sm.OLS(Wage['wage'], Xns).fit()

La fonction bs() construit une base de spline cubique ordinaire à partir de nœuds que tu fournis, ici 25, 40 et 60 ans. ns() construit directement une spline cubique naturelle : tu donnes seulement le nombre de degrés de liberté (df=4), et la bibliothèque place elle-même les nœuds aux quantiles appropriés des données. Dans les deux cas, le modèle est ensuite ajusté par une régression linéaire ordinaire.

Ce que la spline ne sait pas faire

Elle suit une seule variable. Une spline décrit la relation entre la réponse et un seul prédicteur. Avec plusieurs variables, on remplace chaque terme linéaire par une fonction propre à chacune, une spline par exemple : c’est le modèle additif.

Elle ne devine pas les interactions. Comme chaque courbe ne dépend que de sa variable, un tel modèle ne capture pas les interactions entre prédicteurs, sauf à les ajouter explicitement, ce qui fait perdre une partie de la simplicité d’interprétation.

Plus souple n’est pas mieux. Chaque nœud ajoute un degré de liberté, et une pénalité \lambda nulle colle à chaque point. Pour choisir le réglage, on s’appuie sur la validation croisée plutôt que sur l’ajustement des données d’entraînement.

📌 À retenir Une spline, c’est des polynômes recollés aux nœuds. Tu en règles la souplesse par le nombre de nœuds, ou par \lambda quand tu laisses la pénalité décider.