Une régression linéaire à laquelle on ajoute la variable au carré, au cube, et ainsi de suite. La droite devient une courbe, mais le calcul reste celui des moindres carrés. On l'utilise quand la relation monte puis redescend, ou plafonne, et qu'une droite passe à côté.
Une règle souple qu'on plie pour suivre la forme des points. Un degré 2 donne une seule bosse, un degré 3 permet une montée puis une descente puis une remontée.
À partir de l'heure de la journée, on crée heure², heure³… Ces nouvelles colonnes s'ajoutent au tableau comme des variables ordinaires.
Le modèle reste linéaire dans ses coefficients : a × heure + b × heure² + c × heure³. La méthode des moindres carrés s'applique telle quelle.
On compare les degrés en validation croisée. On garde le plus petit degré au-delà duquel l'erreur ne baisse plus.
La température d'une machine relevée toutes les heures pendant près de trois mois. En régime normal, elle suit un cycle de 24 heures : plus chaude vers 6 h du matin sur le jeu d'exemple, plus fraîche vers 18 h.
Le modèle donne la température attendue à chaque heure. Tout écart au profil devient un signal. Sur le jeu d'exemple, les 8 pics anormaux de la période saine ressortent seuls, et après l'heure 1400 la machine tourne en moyenne 4,4 °C au-dessus de son profil.
On compare l'erreur moyenne en validation croisée selon le degré. Ici, elle tombe de 1,4 °C (droite) à 0,7 °C au degré 3, puis ne bouge presque plus : le degré 3 suffit.
Noms donnés pour R (poly dans lm) et Python (PolynomialFeatures de scikit-learn).
Le seul vrai réglage. 2 ou 3 suffisent dans la grande majorité des cas métier. Au-delà de 4, la courbe devient instable, surtout aux extrémités.
Par défaut, R crée des puissances décorrélées entre elles, ce qui stabilise le calcul. Les coefficients ne se lisent plus un par un, mais les prévisions sont identiques.
Avec plusieurs variables, PolynomialFeatures crée aussi tous les produits croisés. Le nombre de colonnes explose vite : on limite le degré ou on passe à Ridge.
# Profil horaire de température : régression polynomiale en R
capteurs <- read.csv("capteurs_machine.csv")
capteurs$heure <- as.integer(substr(capteurs$horodatage, 12, 13))
normal <- capteurs[1:1400, ] # période de fonctionnement normal
# Choix du degré : AIC de chaque modèle (plus bas = meilleur compromis)
for (degre in 1:6) {
m <- lm(temperature ~ poly(heure, degre), data = normal)
cat("Degré", degre, ": AIC", round(AIC(m), 1), "\n")
}
# Modèle retenu : degré 3, puis écart à la normale après l'heure 1400
modele <- lm(temperature ~ poly(heure, 3), data = normal)
ecart <- capteurs$temperature - predict(modele, newdata = capteurs)
cat("Écart moyen après l'heure 1400 :", round(mean(ecart[1401:2000]), 2), "°C\n")
cat("Heures à plus de 3 °C au-dessus du profil : avant", sum(ecart[1:1400] > 3),
"/ après", sum(ecart[1401:2000] > 3), "\n")
# Profil horaire de température : régression polynomiale en Python
import pandas as pd
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score
capteurs = pd.read_csv("capteurs_machine.csv")
capteurs["heure"] = pd.to_datetime(capteurs["horodatage"]).dt.hour
normal = capteurs.iloc[:1400] # période de fonctionnement normal
# Choix du degré par validation croisée (erreur absolue en °C)
for degre in range(1, 7):
modele = make_pipeline(PolynomialFeatures(degre), LinearRegression())
erreur = -cross_val_score(modele, normal[["heure"]], normal["temperature"], cv=5, scoring="neg_mean_absolute_error").mean()
print("Degré", degre, ": erreur moyenne", round(erreur, 2), "°C")
# Modèle retenu : degré 3, puis écart à la normale après l'heure 1400
modele = make_pipeline(PolynomialFeatures(3), LinearRegression())
modele.fit(normal[["heure"]], normal["temperature"])
ecart = capteurs["temperature"] - modele.predict(capteurs[["heure"]])
print("Écart moyen après l'heure 1400 :", round(ecart[1400:].mean(), 2), "°C")
print("Heures à plus de 3 °C au-dessus du profil : avant", (ecart[:1400] > 3).sum(), "/ après", (ecart[1400:] > 3).sum())
Oui. Elle est linéaire dans ses coefficients, même si la courbe obtenue ne l'est pas en fonction de la variable. C'est ce qui permet d'utiliser les moindres carrés et les mêmes outils que la régression linéaire classique.
On compare plusieurs degrés sur des données que le modèle n'a pas vues, par validation croisée, ou avec un critère comme l'AIC. On retient le plus petit degré au-delà duquel l'erreur ne diminue plus nettement.
C'est déconseillé. Hors de la plage observée, le terme de plus haut degré domine et la courbe part très vite vers le haut ou le bas. Pour prévoir une tendance, un modèle de série temporelle est plus adapté.
Le même calcul sans puissances. À essayer d'abord : si la droite suffit, inutile de courber.
Voir la fiche → des courbes plus sagesDes splines au lieu de puissances : la courbe s'adapte localement et ne s'emballe pas aux bords.
Voir la fiche → quand les puissances s'accumulentFreine les coefficients quand les termes polynomiaux et croisés deviennent nombreux et corrélés.
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