Multivariate Adaptive Regression Splines : une régression faite de morceaux de droites, raccordés à des nœuds que l'algorithme trouve seul. Là où une régression linéaire tire une seule droite, MARS repère le moment où la pente change. Le résultat reste une équation lisible, avec ses seuils.
Un géomètre qui trace une route de montagne avec une règle droite. Il pose un segment, repère l'endroit où la pente change, y plante un piquet et repart avec une nouvelle pente.
Pour chaque variable et chaque valeur candidate, on essaie une paire de « charnières » : une droite nulle avant le nœud, qui monte après, et son miroir. On garde la paire qui réduit le plus l'erreur.
L'algorithme répète la recherche, et peut croiser deux charnières pour représenter une interaction entre variables.
Le modèle obtenu est trop riche. On retire une à une les charnières les moins utiles, selon un critère qui pénalise la complexité (GCV).
2 000 heures de mesures de vibration sur un équipement. Question du responsable maintenance : à partir de quand la vibration a-t-elle commencé à dériver, et à quel rythme ?
Sur le jeu d'exemple, le nœud tombe à l'heure 1400. Avant, la vibration est stable ; après, elle augmente d'environ 0,074 unité par jour. On peut dater le début de l'usure et projeter la date d'atteinte d'un seuil d'alerte.
L'erreur quadratique moyenne passe de 0,207 avec une droite à 0,089 avec les deux charnières. En R, le R² généralisé (GRSq) pénalise les nœuds en trop : c'est lui qu'on regarde pour comparer des modèles.
Noms donnés pour le package R de référence, earth.
Degré d'interaction. 1 : effets additifs seulement, comme un GAM par morceaux. 2 : autorise le produit de deux charnières, donc des interactions entre deux variables.
Nombre maximal de termes après élagage. Le réduire donne une équation plus courte, à lire en comité.
Coût d'un nœud dans le critère GCV. Par défaut 2 (3 si degree > 1). L'augmenter donne moins de nœuds, donc un modèle plus simple.
# Dérive des vibrations d'une machine : MARS en R
library(earth)
capteurs <- read.csv("capteurs_machine.csv")
capteurs$heure <- seq_len(nrow(capteurs)) - 1 # heures depuis le début du suivi
# MARS cherche seul les nœuds, puis élague les charnières inutiles (critère GCV)
modele <- earth(vibration ~ heure, data = capteurs)
print(summary(modele)) # termes h(heure-...) : nœuds et pentes
# Nœuds retenus après élagage
noeuds <- modele$cuts[modele$selected.terms, "heure"]
cat("Nœuds retenus (heure) :", unique(noeuds[noeuds > 0]), "\n")
cat("R² :", round(modele$rsq, 3), "| R² généralisé (GCV) :", round(modele$grsq, 3), "\n")
# Comparaison avec une simple droite
droite <- lm(vibration ~ heure, data = capteurs)
cat("R² d'une droite :", round(summary(droite)$r.squared, 3), "\n")
# Avec plusieurs variables et leurs interactions : earth(y ~ ., data, degree = 2)
# Dérive des vibrations d'une machine : MARS en Python
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
capteurs = pd.read_csv("capteurs_machine.csv")
heure = np.arange(len(capteurs)).reshape(-1, 1) # heures depuis le début du suivi
y = capteurs["vibration"]
# scikit-learn n'a pas MARS (py-earth n'est plus maintenu) : on reproduit
# son étape clé, la recherche du meilleur nœud pour une paire de charnières
def charnieres(h, noeud):
return np.hstack([np.maximum(0, noeud - h), np.maximum(0, h - noeud)])
erreurs = {}
for noeud in range(100, 1950, 10):
X = charnieres(heure, noeud)
erreurs[noeud] = np.mean((y - LinearRegression().fit(X, y).predict(X)) ** 2)
meilleur = min(erreurs, key=erreurs.get)
modele = LinearRegression().fit(charnieres(heure, meilleur), y)
print("Nœud trouvé : heure", meilleur)
print("Pente avant le nœud (par jour) :", round(-modele.coef_[0] * 24, 4))
print("Pente après le nœud (par jour) :", round(modele.coef_[1] * 24, 3))
droite = LinearRegression().fit(heure, y)
print("Erreur quadratique : droite", round(np.mean((y - droite.predict(heure)) ** 2), 3), "| MARS", round(erreurs[meilleur], 3))
C'est une fonction nulle d'un côté d'un seuil et linéaire de l'autre, notée h(x - c) ou max(0, x - c). En additionnant plusieurs charnières, MARS construit une ligne brisée dont les coudes tombent aux seuils c trouvés dans les données.
Les deux cherchent des seuils. L'arbre prédit une valeur constante dans chaque zone, ce qui donne des marches d'escalier. MARS prédit des droites raccordées, donc une prévision continue qui suit mieux une tendance.
Le package py-earth n'est plus maintenu et s'installe mal sur les versions récentes de Python. En pratique, MARS se fait en R avec earth. En Python, on peut reproduire l'idée pour un seul nœud, comme dans le code, ou passer à un GAM.
Même idée d'effets non linéaires par variable, avec des courbes plutôt que des segments.
Voir la fiche → des marches d'escalierDécoupe aussi par seuils, mais donne des paliers plats au lieu de pentes continues.
Voir la fiche → pour les séries temporellesRepère les changements de régime d'une série, y compris plusieurs sauts de niveau.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus