Régression non linéaire en R : polynôme, spline & GAM
Quand une droite se trompe — ajustez des courbes avec des polynômes, des splines et des modèles additifs généralisés, puis choisissez le meilleur par validation croisée
Un guide pratique de la régression non linéaire en R pour la prédiction. Quand une droite manque une relation courbe, ajustez-la avec une régression polynomiale (poly), une transformation log, une régression spline (splines::bs / splines naturelles) et un modèle additif généralisé (mgcv::gam avec termes lisses). Choisissez honnêtement le degré du polynôme et les nœuds de la spline par validation croisée, surveillez le compromis biais-variance et lisez chaque RMSE/R² en langage clair. Traité en base-R et à la manière tidymodels (step_poly / step_ns) sur le jeu de données Boston intégré.
Date de publication
25 juin 2026
Modifié
7 juillet 2026
AstucePoints clés
La régression non linéaire conserve la machinerie du modèle linéaire mais laisse l’ajustement s’incurver. Quand la relation entre une réponse et un prédicteur est courbe, une droite sous-ajuste — ces méthodes suivent la courbe.
La régression polynomiale ajoute des termes au carré/au cube (poly(lstat, 2)) : la façon la plus simple d’incurver une droite. Une transformation log (log(lstat)) gère souvent gratuitement une courbe à rendements décroissants.
La régression spline (splines::bs() / ns()) assemble des morceaux de polynômes en des nœuds — plus flexible qu’un seul polynôme global, et mieux maîtrisée aux extrémités.
Les GAM (mgcv::gam(medv ~ s(lstat))) ajustent un terme lisse et choisissent automatiquement leur ondulation — pas de degré à deviner, pas de nœuds à placer. Le choix par défaut pratique quand vous voulez simplement une bonne courbe.
Le degré et les nœuds sont des boutons de réglage. Trop bas ⇒ sous-ajustement (biais) ; trop haut ⇒ surajustement (variance, extrémités folles). Choisissez-les par validation croisée, pas à l’œil — le même compromis biais–variance que tout autre modèle.
Deux voies, une même idée : base R (lm + poly/bs/gam) et la manière tidymodels (recipes::step_poly() / step_ns() dans un workflow, ou parsnip::gen_additive_mod()) — réglées par validation croisée.
Vous ajustez une régression linéaire, le modèle tourne, et les coefficients semblent corrects — mais quand vous traçez les données, les points s’incurvent clairement. La relation se courbe, et une droite la traverse, sur-prédisant au milieu et sous-prédisant aux extrémités. Cette courbure est un signal que le modèle linéaire jette à la poubelle.
La régression non linéaire corrige cela sans abandonner la boîte à outils confortable du modèle linéaire. L’astuce : conserver les moindres carrés ordinaires, mais lui fournir des prédicteurs transformés — un terme au carré, un log, une base de morceaux de spline — pour que la droite ajustée soit libre de s’incurver. Cette leçon couvre les quatre piliers pour un prédicteur courbe :
Régression polynomiale — ajoutez lstat, lstat², lstat³, … à l’équation.
Transformation log — modélisez log(lstat) quand la courbe a une forme lisse à rendements décroissants.
Régression spline — joignez des segments polynomiaux locaux à des nœuds pour une courbe flexible et stable.
Modèles additifs généralisés (GAM) — ajustez un terme lisse et laissez l’algorithme choisir l’ondulation.
Nous procédons à la manière prédictive — partitionner, ajuster, juger sur un jeu de test mis de côté — et choisissons le degré et les nœuds par validation croisée plutôt qu’au jugé. C’est l’angle prédiction (le pilier ML) ; si votre objectif est d’interpréter les coefficients, p-values et hypothèses d’une régression, cela se trouve dans Régression linéaire du côté Biostatistique. Tout le parcours s’appuie sur le workflow tidymodels ; pour les étapes d’expansion de base plus précisément, voir l’ingénierie des variables avec les recipes.
NoteQuand y recourir
Recourez à la régression non linéaire quand un nuage de points ou un graphique des résidus montre une courbure — des points se courbant au-dessus ou en dessous d’un ajustement en droite selon un motif systématique. Essayez d’abord un polynôme ou un log (simple, interprétable) ; passez aux splines quand un seul polynôme global ne peut suivre la forme (ou oscille follement aux extrémités) ; utilisez un GAM quand vous préférez ne choisir à la main ni degré ni nœuds.
Les données
Nous utilisons le jeu de données intégré Boston du package MASS — 506 banlieues de Boston — et l’exemple classique traité : prédire medv (la valeur médiane des logements, en milliers de $) à partir de lstat (le pourcentage de population à « statut modeste »). C’est la relation courbe d’école : à mesure que lstat augmente, la valeur des logements baisse — mais pas en droite. Elle chute d’abord fortement, puis s’aplatit.
Nous partitionnons en un jeu d’entraînement (80 %, pour l’ajustement) et un jeu de test (20 %, mis de côté pour juger chaque modèle honnêtement), stratifié sur medv, avec une graine pour la reproductibilité :
Regardez avant d’ajuster. Un nuage de points avec un lissage loess rend la courbure évidente — et c’est le meilleur argument unique pour expliquer pourquoi une droite ne conviendra pas :
library(ggpubr)library(rsample)data("Boston", package ="MASS")set.seed(123)train_data <-training(initial_split(Boston, prop =0.80, strata = medv))ggscatter( train_data, x ="lstat", y ="medv",color ="#3a86d4", alpha =0.5,add ="loess", add.params =list(color ="gray25"),xlab ="Lower-status population (%)", ylab ="Median home value (k$)") +theme_minimal()
Le lissage s’incurve clairement : la valeur des logements chute vite pour les faibles lstat, puis se stabilise. Une droite sur-prédirait aux deux extrémités et sous-prédirait au milieu. Il nous faut un modèle qui peut s’incurver.
Une référence : la droite
Ajustez toujours la droite en premier — c’est la référence que tout modèle non linéaire doit battre. Nous définissons deux petites fonctions de score (RMSE et R² sur le jeu de test) et les réutilisons partout, pour que chaque modèle soit jugé de la même façon :
À lire : un RMSE ≈ 6.2 signifie qu’une prédiction typique de la valeur médiane des logements se trompe d’environ 6 200 $ (la réponse est en milliers de $), et un R² ≈ 0.53 indique que la droite n’explique qu’environ 53 % de la variance de medv. Pas terrible — mais cela laisse beaucoup sur la table, et nous avons déjà vu pourquoi sur le graphique. Chaque modèle ci-dessous cherche à battre ces deux chiffres.
Régression polynomiale
La façon la plus simple d’incurver une droite est d’ajouter des termes polynomiaux — lstat, lstat², lstat³, et ainsi de suite. La courbe ajustée peut maintenant tourner. En R, poly(lstat, 2) construit le terme au carré pour vous (utilisez raw = TRUE pour garder les coefficients sur l’échelle d’origine, interprétable) :
library(rsample)data("Boston", package ="MASS")set.seed(123)split <-initial_split(Boston, prop =0.80, strata = medv)train_data <-training(split)# A degree-2 (quadratic) polynomial: medv = b0 + b1*lstat + b2*lstat^2poly2 <-lm(medv ~poly(lstat, 2, raw =TRUE), data = train_data)round(coef(poly2), 3)
(Intercept) poly(lstat, 2, raw = TRUE)1
42.673 -2.275
poly(lstat, 2, raw = TRUE)2
0.041
Il y a maintenant deux coefficients lstat — un pour le terme linéaire, un pour le quadratique — et le coefficient quadratique positif est ce qui incurve l’ajustement vers le haut à droite, correspondant à la queue qui s’aplatit dans les données.
Jusqu’à quel degré monter ? Ajustez un polynôme d’ordre élevé et regardez quels termes sont réellement significatifs — au-delà, vous ajustez du bruit :
library(rsample)data("Boston", package ="MASS")set.seed(123)train_data <-training(initial_split(Boston, prop =0.80, strata = medv))# Fit degree 6, look at the per-term p-valuespoly6 <-lm(medv ~poly(lstat, 6, raw =TRUE), data = train_data)round(summary(poly6)$coefficients[, "Pr(>|t|)"], 4)
(Intercept) poly(lstat, 6, raw = TRUE)1
0.0000 0.0000
poly(lstat, 6, raw = TRUE)2 poly(lstat, 6, raw = TRUE)3
0.0021 0.0150
poly(lstat, 6, raw = TRUE)4 poly(lstat, 6, raw = TRUE)5
0.0418 0.0780
poly(lstat, 6, raw = TRUE)6
0.1165
Les termes sont significatifs jusqu’au quatrième ordre ; le cinquième est limite (p ≈ 0.08) et le sixième clairement pas — donc un polynôme de degré 5 est une borne supérieure défendable (le degré 4 étant le choix sûr), assez flexible pour suivre la courbe sans chasser le bruit. Ajustez-le et évaluez-le :
RMSE ≈ 4.97, R² ≈ 0.71 — un grand bond par rapport à la droite (6.2 / 0.53). Laisser l’ajustement s’incurver a expliqué près de 20 points de pourcentage de plus de variance sur des données que le modèle n’avait jamais vues. C’est le gain de la régression non linéaire en une seule comparaison.
AvertissementNe montez pas le degré à l’aveugle
Un polynôme de degré 10 ou 15 collera aux points d’entraînement encore plus étroitement — et prédira moins bien sur de nouvelles données, oscillant follement entre eux et au-delà (le phénomène de Runge). Les polynômes globaux de haut degré sont notoirement instables aux extrémités des données. C’est exactement le surajustement pour lequel le degré est un bouton de réglage : choisissez-le par validation croisée (ci-dessous), pas en maximisant l’ajustement à l’entraînement.
Transformation log
Avant de recourir aux splines, essayez la courbe la moins coûteuse de toutes : une transformation log du prédicteur. Quand la relation a une forme lisse à rendements décroissants, log(lstat) la redresse — un seul terme, aucun degré à choisir :
RMSE ≈ 5.18, R² ≈ 0.68 — un seul terme log bat le polynôme de degré 2 et atteint presque l’ajustement de degré 5, pour bien moins de complexité. Quand une transformation log fonctionne aussi bien, c’est souvent le modèle non linéaire le plus interprétable que vous puissiez livrer : un coefficient, une histoire facile (« chaque doublement de lstat fait varier medv d’une quantité fixe »).
Régression spline
Un polynôme global incurve la totalité de la courbe avec une seule équation, ce qui explique pourquoi les degrés élevés se comportent mal aux extrémités. Les splines prennent une voie plus astucieuse : découper l’étendue du prédicteur en segments en des points choisis appelés nœuds, ajuster un polynôme de bas degré à l’intérieur de chaque segment, et les joindre en douceur. Le résultat est flexible localement sans les oscillations globales folles.
La fonction splines::bs() construit une base de b-splines. Un choix courant et sensé est de placer les nœuds aux quartiles du prédicteur et d’utiliser des morceaux cubiques (de degré 3) :
library(rsample)library(splines)data("Boston", package ="MASS")set.seed(123)split <-initial_split(Boston, prop =0.80, strata = medv)train_data <-training(split)test_data <-testing(split)rmse <-function(obs, pred) sqrt(mean((obs - pred)^2))r2 <-function(obs, pred) cor(obs, pred)^2# Knots at the lower-quartile, median and upper-quartile of lstatknots <-quantile(train_data$lstat, p =c(0.25, 0.50, 0.75))spline_model <-lm(medv ~bs(lstat, knots = knots), data = train_data)pred <-predict(spline_model, test_data)data.frame(RMSE =rmse(test_data$medv, pred), R2 =r2(test_data$medv, pred))
RMSE R2
1 4.97265 0.7074703
RMSE ≈ 4.97, R² ≈ 0.71 — essentiellement à égalité avec le polynôme de degré 5, mais la spline y parvient avec une courbe plus douce et plus stable. (Remarque : les coefficients individuels d’une spline ne sont pas interprétables — lisez la courbe ajustée, pas les poids de la base.)
Noteb-splines vs splines naturelles
bs() construit des b-splines ; ns() construit des splines naturelles, qui ajoutent une contrainte forçant la courbe à être linéaire au-delà des nœuds les plus externes. Cela rend les splines naturelles bien plus stables dans les queues — l’endroit exact où les b-splines et les polynômes de haut degré ont tendance à s’envoler. Si votre courbe ajustée semble instable aux extrêmes des données, remplacez bs() par ns(). Plus de nœuds = plus de flexibilité ; placez-les là où la courbe change de forme (les quartiles sont un choix par défaut sûr).
Modèles additifs généralisés (GAM)
Choisir un degré de polynôme ou un ensemble de nœuds reste un choix — et un choix légèrement arbitraire. Les modèles additifs généralisés le suppriment : vous demandez un terme lisses(lstat) et l’algorithme trouve la bonne ondulation pour vous, en pénalisant la rugosité de sorte qu’il ne sous-ajuste ni ne surajuste. Le package mgcv est la référence :
RMSE ≈ 4.99, R² ≈ 0.70 — juste à côté du polynôme et de la spline, mais avec rien à régler à la main. C’est l’attrait d’un GAM comme choix par défaut : vous le pointez vers le prédicteur, il renvoie une courbe lisse sensée, et summary(gam_model) rapporte même les degrés de liberté effectifs (à quel point l’ajustement s’est révélé ondulé). Pour un ajustement non linéaire rapide et robuste, recourez d’abord à un GAM.
La figure emblématique : toutes les courbes sur les données
Toute l’histoire tient en un graphique — les données avec chaque courbe ajustée posée par-dessus. Là où elles s’incurvent ensemble se trouve l’endroit où les modèles non linéaires s’accordent ; là où la droite traverse est exactement ce qu’ils corrigent :
library(rsample)library(splines)library(mgcv)library(ggplot2)data("Boston", package ="MASS")set.seed(123)train_data <-training(initial_split(Boston, prop =0.80, strata = medv))ggplot(train_data, aes(lstat, medv)) +geom_point(color ="#3a86d4", alpha =0.4) +geom_smooth(aes(color ="Linear"), method ="lm",formula = y ~ x, se =FALSE) +geom_smooth(aes(color ="Log"), method ="lm",formula = y ~log(x), se =FALSE) +geom_smooth(aes(color ="Polynomial (5)"), method ="lm",formula = y ~poly(x, 5, raw =TRUE), se =FALSE) +geom_smooth(aes(color ="Spline (cubic)"), method ="lm",formula = y ~ splines::bs(x, df =3), se =FALSE) +geom_smooth(aes(color ="GAM smooth"), method ="gam",formula = y ~s(x), se =FALSE) +scale_color_manual(name ="Fit",values =c("Linear"="gray50", "Log"="#e07b39","Polynomial (5)"="#0073C2", "Spline (cubic)"="#EFC000","GAM smooth"="#CD534C") ) +labs(x ="Lower-status population (%)", y ="Median home value (k$)",title ="A line misses the curve — polynomials, splines and GAMs follow it",subtitle ="Boston data: medv vs lstat, five fits over the same scatter" ) +theme_minimal()
L’ajustement linéaire gris est l’intrus — une entaille plate à travers un nuage courbe. Chaque courbe non linéaire (polynôme, log, spline, GAM) suit de près la forme abrupte-puis-plate, et elles s’accordent presque partout, ce qui est rassurant : la courbure est réelle, pas un artefact d’une seule méthode. Elles ne diffèrent que dans les queues clairsemées (lstat élevé), où il y a peu de données pour les fixer — la région où une spline naturelle ou la pénalité d’un GAM garde la courbe sensée et où un polynôme de haut degré ne le ferait pas.
Comparer les modèles
Mettez les cinq scores de jeu de test côte à côte — la comparaison honnête, hors échantillon, qui désigne le gagnant :
library(rsample)library(splines)library(mgcv)data("Boston", package ="MASS")set.seed(123)split <-initial_split(Boston, prop =0.80, strata = medv)train_data <-training(split)test_data <-testing(split)rmse <-function(obs, pred) sqrt(mean((obs - pred)^2))r2 <-function(obs, pred) cor(obs, pred)^2knots <-quantile(train_data$lstat, p =c(0.25, 0.50, 0.75))models <-list(Linear =lm(medv ~ lstat, data = train_data),`Log transform`=lm(medv ~log(lstat), data = train_data),`Polynomial (5)`=lm(medv ~poly(lstat, 5, raw =TRUE), data = train_data),`Spline (cubic)`=lm(medv ~bs(lstat, knots = knots), data = train_data),GAM =gam(medv ~s(lstat), data = train_data))scores <-lapply(models, function(m) { pred <-predict(m, test_data)data.frame(RMSE =rmse(test_data$medv, pred), R2 =r2(test_data$medv, pred))})round(do.call(rbind, scores), 3)
Lisez le tableau. Le meilleur modèle est celui avec le RMSE le plus bas et le R² le plus haut :
Le modèle linéaire est nettement le pire (RMSE ≈ 6.2, R² ≈ 0.53) — le prix de forcer une droite sur une courbe.
La transformation log récupère l’essentiel de l’écart (R² ≈ 0.68) avec un seul terme — un excellent rapport valeur/simplicité.
Le polynôme (5), la spline et le GAM forment le haut du panier et sont quasi identiques (RMSE ≈ 4.97, R² ≈ 0.70–0.71). Quand la précision prédictive est à égalité ainsi, préférez le modèle le plus simple et le plus stable — ici le GAM (rien à régler) ou la spline (stable aux extrémités) plutôt qu’un fragile polynôme global de degré 5.
Ce schéma « elles sont à égalité, donc choisissez la robuste » est exactement ce qui se produit avec la régression pénalisée aussi — quand la précision est égale, la simplicité et la stabilité départagent.
La manière tidymodels
Tout ce qui précède utilisait lm/gam de base, ce qui est l’enseignement le plus clair. Dans un véritable pipeline prédictif vous voudrez les mêmes expansions de base à l’intérieur d’un workflow tidymodels, pour que la courbe soit réglée et validée avec la même machinerie que tout autre modèle (voir construire des modèles avec tidymodels). L’expansion de base devient une étape de recipe — step_poly() pour les polynômes, step_ns() pour les splines naturelles — et le degré / nombre de nœuds devient un paramètre réglable :
library(rsample)library(recipes)library(parsnip)library(workflows)library(yardstick)data("Boston", package ="MASS")set.seed(123)split <-initial_split(Boston, prop =0.80, strata = medv)train_data <-training(split)test_data <-testing(split)# A natural-spline basis on lstat (4 df), then an ordinary linear modelspline_rec <-recipe(medv ~ lstat, data = train_data) |>step_ns(lstat, deg_free =4)lm_spec <-linear_reg() |>set_engine("lm")spline_wf <-workflow() |>add_recipe(spline_rec) |>add_model(lm_spec)spline_fit <-fit(spline_wf, data = train_data)# Predict on the held-out test set and scoreresults <-predict(spline_fit, new_data = test_data)results <-cbind(results, medv = test_data$medv)reg_metrics <-metric_set(yardstick::rmse, yardstick::rsq)reg_metrics(results, truth = medv, estimate = .pred)
# A tibble: 2 × 3
.metric .estimator .estimate
<chr> <chr> <dbl>
1 rmse standard 4.97
2 rsq standard 0.705
Le même ajustement spline (RMSE ≈ 5.0, R² ≈ 0.70), désormais exprimé comme un workflow que vous pouvez glisser dans la validation croisée. Pour choisir la flexibilité honnêtement, marquez le deg_free de la recipe comme tune() et lancez tune_grid() sur quelques valeurs, exactement comme dans la leçon des fondations de tidymodels :
library(tune)library(dials)# Tune the spline's degrees of freedom by 10-fold cross-validationspline_rec <-recipe(medv ~ lstat, data = train_data) |>step_ns(lstat, deg_free =tune())spline_wf <-workflow() |>add_recipe(spline_rec) |>add_model(lm_spec)set.seed(123)folds <-vfold_cv(train_data, v =10)grid <- tibble::tibble(deg_free =2:8)tuned <-tune_grid(spline_wf, resamples = folds, grid = grid,metrics =metric_set(rmse))select_best(tuned, metric ="rmse") # the flexibility with the lowest CV error
Ce select_best() est tout l’enjeu : la validation croisée, pas votre œil, décide à quel point la courbe doit onduler. Pour un GAM, la voie tidymodels est parsnip::gen_additive_mod() avec le moteur "mgcv" — gen_additive_mod() |> set_engine("mgcv") |> set_mode("regression"), ajusté avec un terme lisse dans la formule (medv ~ s(lstat)) — ce qui vous donne le GAM à lissage automatique dans la même grammaire de workflow.
NotePolynômes, splines & lissages (optionnel)
Une régression polynomiale reste un modèle linéaire — linéaire dans les coefficients — ajusté sur des colonnes transformées. Pour un polynôme de degré \(d\) :
Un seul polynôme global doit utiliser les mêmes coefficients partout, donc les degrés élevés achètent de la flexibilité aux extrémités au prix d’une oscillation folle (le phénomène de Runge).
Une spline de régression remplace le polynôme unique par une base de polynômes par morceaux joints en \(K\) nœuds \(\xi_1, \dots, \xi_K\). L’ajustement est toujours \(medv = \sum_j \beta_j B_j(lstat) + \varepsilon\), où les \(B_j\) sont les fonctions de base de la spline (issues de bs() ou ns()) ; chaque morceau est de bas degré, donc la courbe reste locale et stable. Une spline naturelle ajoute la contrainte que l’ajustement est linéaire au-delà des nœuds externes — domptant les queues.
Un GAM écrit la réponse comme une somme de fonctions lisses, \(medv = \beta_0 + f(lstat) + \varepsilon\), où \(f\) est elle-même une spline pénalisée. mgcv estime \(f\) en maximisant l’ajustement moins une pénalité de rugosité \(\lambda \int f''(x)^2\,dx\), et choisit la pénalité \(\lambda\) automatiquement (par validation croisée généralisée / REML). Cette pénalité est la raison pour laquelle un GAM n’a pas besoin que vous choisissiez un degré ou des nœuds — il règle sa propre ondulation. Dans tous les cas, le solveur sous-jacent est celui des moindres carrés ordinaires (pénalisés) ; seules les colonnes que vous lui fournissez changent.
Quelle méthode quand
Un repère de décision rapide pour un seul prédicteur courbe :
Situation
Recourir à
Courbe lisse à rendements décroissants, interprétabilité souhaitée
Courbure plus forte / locale, les extrémités comptent
Spline — ns() pour des queues stables
Ne pas vouloir choisir de degré ni de nœuds ; juste une bonne courbe
GAM (s(), lissage automatique)
Quand plusieurs sont à égalité sur la précision en jeu de test (comme ici), livrez le plus simple et le plus stable — généralement le GAM ou une spline naturelle.
🟢 Avec un agent IA
Vous avez un prédicteur qui s’incurve ? Demandez à Prova« ajuste des modèles polynomiaux, splines et GAM à cette relation, valide le degré par validation croisée, et dis-moi lequel prédit le mieux » — elle répond avec du code tidymodels + mgcv que vous pouvez exécuter sur vos propres données, puis vous aide à lire le RMSE/R² et à choisir la courbe qui généralise. The runtime is the judge.Demandez à Prova →
Problèmes courants
Vous avez monté le degré du polynôme pour « mieux ajuster ». Le RMSE d’entraînement continue de baisser, mais le RMSE de test se retourne et grimpe — c’est du surajustement, et les polynômes globaux de haut degré oscillent follement aux extrémités des données (le phénomène de Runge). Choisissez le degré par validation croisée sur des données mises de côté, ou passez à une spline/un GAM, qui restent flexibles localement sans l’explosion globale.
bs() ou ns() avertit de valeurs hors de l’étendue des nœuds. Les splines sont définies sur l’étendue des données sur lesquelles elles ont été construites ; prédire à de nouvelles valeurs x au-delà des nœuds externes extrapole. Construisez la base sur le prédicteur d’entraînement (le step_ns() d’une recipe le fait automatiquement), et préférez ns(), dont les queues linéaires extrapolent plus raisonnablement que bs().
Vous avez essayé de lire les coefficients d’une spline. Ne le faites pas — un terme de spline (ou GAM) n’a aucun coefficient individuel interprétable. Lisez la courbe ajustée (tracez-la) et le RMSE/R² du jeu de test ; pour l’interprétation des coefficients, vous voulez un polynôme avec raw = TRUE ou, mieux, le traitement par inférence.
Votre modèle log() a échoué ou renvoyé NaN.log(0) vaut -Inf et log d’un nombre négatif vaut NaN. Une transformation log ne fonctionne que pour des prédicteurs strictement positifs ; si le vôtre a des zéros, utilisez log1p(x) (= log(1 + x)) ou une spline/un GAM à la place.
Questions fréquentes
NoteComment faire une régression polynomiale en R ?
Ajoutez des termes polynomiaux avec poly() à l’intérieur de lm() : lm(medv ~ poly(lstat, 2), data = train) ajuste une quadratique, poly(lstat, 3) une cubique, et ainsi de suite. Utilisez raw = TRUE si vous voulez des coefficients sur l’échelle d’origine. Choisissez le degré par validation croisée (ou en vérifiant quels termes restent significatifs) — un degré trop élevé surajuste et oscille follement aux extrémités des données.
NoteComment faire une régression spline en R ?
Utilisez le package splines : splines::bs(x, knots = ...) construit une base de b-splines et splines::ns(x, df = ...) une spline naturelle, glissées dans un lm() — par ex. lm(medv ~ bs(lstat, knots = quantile(lstat, c(.25,.5,.75))), data = train). Les nœuds sont les points où les morceaux polynomiaux locaux se joignent ; plus de nœuds signifie plus de flexibilité. Les splines naturelles (ns()) sont plus stables dans les queues que les b-splines.
NoteQu’est-ce que la régression non linéaire et quand l’utiliser ?
La régression non linéaire modélise une relation courbe entre une réponse et un prédicteur tout en conservant la machinerie du modèle linéaire — vous ajustez les moindres carrés ordinaires sur des prédicteurs transformés (un terme au carré, un log, une base de spline). Utilisez-la quand un nuage de points ou un graphique des résidus montre une courbure systématique qu’une droite manque. Les polynômes, transformations log, splines et GAM sont les outils standard.
NoteQu’est-ce qu’un GAM (modèle additif généralisé) en R ?
Un GAM modélise la réponse comme une somme de fonctions lisses des prédicteurs — par ex. mgcv::gam(medv ~ s(lstat)), où s() est une spline pénalisée dont l’ondulation est choisie automatiquement par mgcv. C’est la façon la plus simple d’ajuster une courbe flexible : aucun degré de polynôme à deviner et aucun nœud à placer. summary() rapporte les degrés de liberté effectifs, vous indiquant à quel point le lissage ajusté s’est révélé courbe.
NotePolynôme vs spline vs GAM — lequel est le meilleur ?
Ils prédisent souvent de façon quasi identique (comme sur les données Boston ici). Un polynôme est le plus simple et ses coefficients sont interprétables, mais les degrés élevés sont instables aux extrémités. Une spline est plus flexible localement et plus stable (surtout ns()), mais vous choisissez les nœuds. Un GAM ne nécessite ni degré ni nœuds manuels — il règle son propre lissage — donc c’est le meilleur choix par défaut quand vous voulez simplement une courbe robuste. Quand la précision en jeu de test est à égalité, livrez le modèle le plus simple et le plus stable.
Testez vos connaissances
ImportantExercice : ajuster et comparer un polynôme cubique et une spline naturelle
En utilisant les données Boston (MASS), prédisez medv à partir de lstat. Partitionnez 80/20 stratifié sur medv, puis ajustez (a) un polynôme de degré 3 avec lm(medv ~ poly(lstat, 3, raw = TRUE)) et (b) une spline naturelle avec lm(medv ~ ns(lstat, df = 4)). Rapportez le RMSE et le R² du jeu de test pour chacun. Lequel ajuste mieux, et l’écart est-il grand ?
AstuceIndice
Réutilisez les fonctions rmse() / r2() de la leçon et la même partition. Pour la spline naturelle, vous avez besoin de library(splines) et ns(). Prédisez sur le jeu de test, pas le jeu d’entraînement.
Tous deux atterrissent autour de RMSE ≈ 5.0 et R² ≈ 0.70 — proches du polynôme de degré 5 et du GAM de la leçon, et bien meilleurs que la droite. La spline naturelle est typiquement un brin plus stable ; l’écart entre les deux ici est petit, ce qui est le constat habituel une fois que le modèle peut s’incurver tout court.
Vérification rapide. Vous ajustez un polynôme de degré 5 et un GAM au même prédicteur courbe et ils prédisent aussi bien sur le jeu de test, mais le polynôme oscille fortement vers le haut aux valeurs lstat les plus élevées où les données sont clairsemées. Lequel livreriez-vous, et pourquoi ?
NoteAfficher la réponse
Livrez le GAM (ou une spline naturelle). Quand deux modèles prédisent aussi bien, préférez celui qui se comporte raisonnablement là où les données sont rares. La forte remontée du polynôme de degré 5 dans la queue clairsemée est un artefact du forçage d’une seule équation globale à travers toute l’étendue — il extrapolera mal. La pénalité du GAM (et les queues linéaires d’une spline naturelle) gardent la courbe stable aux extrémités, c’est donc le modèle plus sûr à mettre en production. Quand la précision est à égalité, choisissez l’ajustement le plus robuste.
Conclusion
Vous avez ajusté une régression non linéaire de bout en bout sur les données Boston : une droite a sous-ajusté la relation medv–lstat courbe (R² ≈ 0.53), et quatre méthodes l’ont corrigée — des termes polynomiaux (R² ≈ 0.71), une transformation log à un terme (≈ 0.68), une spline cubique (≈ 0.71), et un lissage GAM qui a réglé sa propre ondulation (≈ 0.70). Vous avez vu toutes les courbes sur le nuage, les avez comparées honnêtement sur un jeu de test mis de côté, et avez exprimé la spline comme une recipe tidymodels (step_ns()) prête pour la validation croisée. Les règles pratiques : cherchez la courbure avant de modéliser, laissez la validation croisée choisir le degré/les nœuds, et quand les meilleurs modèles sont à égalité, livrez le plus simple et le plus stable — généralement le GAM ou une spline naturelle.
Prouvez que vous savez le faire. Maîtrisez toute la série Sélection de modèles en R — suivez votre parcours, construisez des projets et obtenez un certificat.
Cette leçon est reproductible : chaque métrique, courbe et figure a été produite par le code montré — copiez n’importe quel bloc et exécutez-le pour les reproduire. The runtime is the judge.
Références
James, G., Witten, D., Hastie, T., & Tibshirani, R. (2014). An Introduction to Statistical Learning, with Applications in R. Springer. (Chapitre 7 — Moving Beyond Linearity.)
Wood, S. N. (2017). Generalized Additive Models: An Introduction with R (2e éd.). Chapman & Hall/CRC. (Le package mgcv.)
Kuhn, M., & Silge, J. Tidy Modeling with R. Gratuit en ligne (CC BY-NC-SA).