W3docs

Régression linéaire

Apprenez le fonctionnement de la régression linéaire, la mathématique sous-jacente et son implémentation simple ou multiple en Python avec scikit-learn.

La régression linéaire est l'un des algorithmes les plus fondamentaux du machine learning. Elle modélise la relation entre une variable dépendante (ce que vous souhaitez prédire) et une ou plusieurs variables indépendantes (les entrées) en ajustant une droite — ou un hyperplan — aux données.

Cette page couvre :

  • Le fonctionnement mathématique de la régression linéaire simple et multiple
  • La méthode des moindres carrés ordinaires (MCO) pour ajuster une droite
  • Les hypothèses clés à vérifier avant de faire confiance à votre modèle
  • Un tutoriel complet avec scikit-learn : chargement des données, entraînement, évaluation et interprétation des résultats
  • Comment lire les coefficients du modèle et identifier les pièges courants

Fonctionnement de la régression linéaire

L'équation

La régression linéaire simple (une seule variable d'entrée) ajuste cette droite :

y = β₀ + β₁x + ε
  • y — la variable dépendante (cible)
  • x — la variable indépendante (caractéristique)
  • β₀ — l'ordonnée à l'origine (valeur de y quand x = 0)
  • β₁ — la pente (variation de y pour une augmentation d'une unité de x)
  • ε — le terme d'erreur (bruit que le modèle ne peut pas expliquer)

La régression linéaire multiple étend cela à n caractéristiques :

y = β₀ + β₁x₁ + β₂x₂ + ... + βₙxₙ + ε

Chaque coefficient βᵢ indique de combien y varie lorsque xᵢ augmente d'une unité, toutes les autres caractéristiques restant constantes.

Moindres carrés ordinaires (MCO)

Le modèle apprend les coefficients en minimisant la somme des carrés des résidus — la différence entre chaque valeur réelle yᵢ et la prédiction du modèle ŷᵢ :

SSR = Σ(yᵢ - ŷᵢ)²

La mise au carré des résidus pénalise davantage les grandes erreurs que les petites, et garantit que les erreurs positives et négatives ne s'annulent pas. Ce critère possède une solution analytique exacte en forme fermée, ce qui explique pourquoi la régression linéaire s'entraîne quasi instantanément, même sur de grands jeux de données.

Hypothèses clés

La régression linéaire produit des prédictions fiables uniquement lorsque ces conditions sont satisfaites :

HypothèseCe qu'il faut vérifier
LinéaritéLa relation entre les caractéristiques et la cible est approximativement linéaire
IndépendanceLes observations sont indépendantes les unes des autres
HomoscédasticitéLa variance des résidus est à peu près constante pour toutes les prédictions
Normalité des résidusLes résidus sont approximativement distribués normalement
Absence de multicolinéaritéLes variables indépendantes ne sont pas fortement corrélées entre elles

Lorsque ces hypothèses sont violées, les estimations des coefficients peuvent être biaisées ou le modèle peut mal performer sur des données inédites.

Exemple de régression linéaire simple

Avant de passer à plusieurs caractéristiques, voyons comment l'algorithme ajuste une droite à une seule variable. Cela rend la géométrie facile à visualiser.

import numpy as np
import matplotlib
matplotlib.use('Agg')  # non-interactive backend for scripts
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# Simulate: house size (sq ft) vs price ($1000s)
rng = np.random.default_rng(42)
X_simple = rng.uniform(500, 3000, 50).reshape(-1, 1)
y_simple = 50 + 0.1 * X_simple.ravel() + rng.normal(0, 15, 50)

model = LinearRegression()
model.fit(X_simple, y_simple)

print(f"Intercept (β₀): {model.intercept_:.2f}")
print(f"Slope    (β₁): {model.coef_[0]:.4f}")
print(f"Interpretation: each extra sq ft adds ${model.coef_[0]*1000:.0f} to the predicted price")

Résultat attendu :

Intercept (β₀): 46.17
Slope    (β₁): 0.1007
Interpretation: each extra sq ft adds $101 to the predicted price

L'ordonnée à l'origine et la pente sont calculées automatiquement par MCO — vous n'avez pas à faire l'algèbre vous-même.

Régression linéaire multiple avec scikit-learn

Les jeux de données réels comportent de nombreuses caractéristiques. Cette section présente un pipeline complet sur le jeu de données California Housing, qui recense des statistiques immobilières au niveau des îlots de recensement en Californie en 1990.

Étape 1 : Importer les bibliothèques

import pandas as pd
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score

Étape 2 : Charger et explorer le jeu de données

california = fetch_california_housing()
df = pd.DataFrame(california.data, columns=california.feature_names)
df['MedHouseVal'] = california.target  # median house value in $100,000s

print(df.shape)          # (20640, 9)
print(df.head())
print(df.describe())

Le jeu de données contient 20 640 lignes et 8 caractéristiques d'entrée :

CaractéristiqueDescription
MedIncRevenu médian de l'îlot (en dizaines de milliers de dollars)
HouseAgeÂge médian des logements dans l'îlot
AveRoomsNombre moyen de pièces par ménage
AveBedrmsNombre moyen de chambres par ménage
PopulationPopulation de l'îlot
AveOccupOccupation moyenne des ménages
LatitudeLatitude de l'îlot
LongitudeLongitude de l'îlot

La cible MedHouseVal est la valeur médiane des logements en unités de 100 000 $.

Étape 3 : Choisir les caractéristiques et diviser les données

Pour une démonstration simple, nous utilisons les 8 caractéristiques. Consultez Train/Test Split pour une explication détaillée de pourquoi nous divisons les données.

X = df[california.feature_names]   # all 8 features
y = df['MedHouseVal']

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

print(f"Training samples: {len(X_train)}")   # 16512
print(f"Test samples:     {len(X_test)}")    # 4128

Le paramètre random_state=42 garantit des divisions reproductibles à chaque exécution du script.

Étape 4 : Entraîner le modèle

model = LinearRegression()
model.fit(X_train, y_train)

C'est tout ce qu'il faut. La méthode fit() résout le problème MCO de manière analytique via l'algèbre matricielle — aucune descente de gradient itérative n'est impliquée par défaut.

Étape 5 : Inspecter les coefficients appris

Comprendre ce que le modèle a appris est aussi important que sa précision :

coef_df = pd.DataFrame({
    'Feature': california.feature_names,
    'Coefficient': model.coef_
}).sort_values('Coefficient', key=abs, ascending=False)

print(coef_df.to_string(index=False))
print(f"\nIntercept: {model.intercept_:.4f}")

Résultat typique :

   Feature  Coefficient
 AveBedrms     0.7831
    MedInc     0.4487
 Longitude    -0.4337
  Latitude    -0.4198
  AveRooms    -0.1233
  HouseAge     0.0097
  AveOccup    -0.0035
Population    -0.0000

Intercept: -37.0233

Lecture des coefficients :

  • AveBedrms = 0.783 : une augmentation d'une unité du nombre moyen de chambres prédit une hausse de 78 300 $ de la valeur du logement — mais cela est entremêlé avec AveRooms (ils sont corrélés). Lorsque des caractéristiques corrélées sont toutes deux présentes, les coefficients individuels peuvent devenir grands, instables, voire contre-intuitifs. C'est la multicolinéarité.
  • MedInc = 0.449 : une augmentation d'une unité du revenu médian (environ 10 000 $) prédit une hausse de 44 900 $ de la valeur du logement, toutes choses égales par ailleurs.
  • Longitude = -0.434 et Latitude = -0.420 : des contrôles purement géographiques ; le modèle les utilise pour capturer les effets de localisation, même s'il ne peut pas modéliser la géographie non linéaire efficacement.

Étape 6 : Évaluer le modèle

y_pred = model.predict(X_test)

mse  = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2   = r2_score(y_test, y_pred)

print(f"RMSE: {rmse:.4f}  (in $100,000s, so ±${rmse*100_000:,.0f})")
print(f"R²:   {r2:.4f}")

Résultat attendu :

RMSE: 0.7456  (in $100,000s, so ±$74,560)
R²:   0.5758

Interprétation des métriques :

  • RMSE (Root Mean Squared Error) — l'erreur de prédiction moyenne dans les mêmes unités que la cible. Plus la valeur est basse, mieux c'est.
  • R² (coefficient de détermination) — la proportion de variance de y expliquée par le modèle. Un R² de 0,58 signifie que le modèle explique environ 58 % de la variance des prix immobiliers. Les valeurs proches de 1,0 sont meilleures ; les valeurs proches de 0 indiquent que le modèle fait à peine mieux que prédire la moyenne.

Un R² d'environ 0,58 est typique pour ce jeu de données avec la régression linéaire. La relation entre les prix immobiliers et ces caractéristiques est partiellement non linéaire, ce qui explique pourquoi des méthodes telles que la régression polynomiale ou le gradient boosting obtiennent souvent de meilleurs scores.

Étape 7 : Visualiser les valeurs prédites vs réelles

Le graphique diagnostique le plus clair pour un modèle de régression est prédit vs réel — il fonctionne quel que soit le nombre de caractéristiques :

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

plt.figure(figsize=(7, 5))
plt.scatter(y_test, y_pred, alpha=0.3, s=10, color='steelblue')
plt.plot([y_test.min(), y_test.max()],
         [y_test.min(), y_test.max()],
         'r--', linewidth=1.5, label='Perfect prediction')
plt.xlabel('Actual Median House Value ($100,000s)')
plt.ylabel('Predicted Median House Value ($100,000s)')
plt.title('Linear Regression: Predicted vs Actual')
plt.legend()
plt.tight_layout()
plt.savefig('lr_predicted_vs_actual.png', dpi=120)
print("Plot saved.")

Les points qui tombent sur la ligne rouge en pointillés correspondent à des prédictions parfaites. La dispersion autour de la ligne représente l'erreur. Une forme en éventail (dispersion plus large aux valeurs élevées) signale une hétéroscédasticité — l'une des hypothèses clés est violée.

Pipeline complet (toutes les étapes réunies)

import pandas as pd
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score

# Load data
california = fetch_california_housing()
df = pd.DataFrame(california.data, columns=california.feature_names)
df['MedHouseVal'] = california.target

# Split
X = df[california.feature_names]
y = df['MedHouseVal']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Train
model = LinearRegression()
model.fit(X_train, y_train)

# Evaluate
y_pred = model.predict(X_test)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
r2   = r2_score(y_test, y_pred)

print(f"RMSE: {rmse:.4f}")
print(f"R²:   {r2:.4f}")

Quand utiliser la régression linéaire

La régression linéaire est un bon premier choix lorsque :

  • La relation entre les entrées et la sortie est approximativement linéaire
  • L'interprétabilité est importante — vous devez expliquer les prédictions aux parties prenantes
  • Le jeu de données est de taille petite ou moyenne et la vitesse d'entraînement est importante
  • Vous souhaitez obtenir rapidement une référence avant d'essayer des modèles plus complexes

Envisagez des alternatives lorsque :

  • Les caractéristiques et la cible ont des relations non linéaires fortes → essayez la régression polynomiale ou les arbres de décision
  • Vous avez de nombreuses caractéristiques potentiellement non pertinentes → les variantes régularisées (Ridge, Lasso) préviennent le surapprentissage en réduisant les coefficients
  • La cible est une catégorie et non un nombre → utilisez plutôt la régression logistique

Pièges courants

Oublier de mettre les caractéristiques à l'échelle. Les coefficients de régression linéaire reflètent les unités de chaque caractéristique. Si une caractéristique est en milliers et une autre en fractions, les tailles brutes des coefficients ne sont pas comparables. Utilisez StandardScaler avant de comparer les importances des caractéristiques. Voir Feature Scaling pour plus de détails.

Multicolinéarité. Des caractéristiques fortement corrélées rendent les coefficients individuels peu fiables — ils peuvent même changer de signe. Vérifiez la matrice de corrélation avec df.corr() et supprimez ou combinez les caractéristiques corrélées.

Extrapolation. Un modèle linéaire entraîné sur des données dans une certaine plage peut donner des prédictions totalement erronées en dehors de cette plage. Vérifiez toujours que les nouvelles entrées se situent dans la distribution d'entraînement.

Ignorer les graphiques de résidus. Tracez toujours les résidus après l'ajustement. Des motifs dans les résidus (courbes, éventails, groupes d'outliers) indiquent que les hypothèses du modèle sont violées et que les prédictions ne doivent pas être utilisées sans investigation complémentaire.

Prochaines étapes

Une fois que vous disposez d'une référence de régression linéaire fonctionnelle, explorez ces sujets connexes :

  • Multiple Regression — approfondissement de l'utilisation de plusieurs caractéristiques et de l'interprétation de chaque coefficient
  • Polynomial Regression — ajuster des courbes plutôt que des droites en ajoutant des termes polynomiaux
  • Train/Test Split — comprendre pourquoi et comment évaluer correctement les performances du modèle
  • Feature Scaling — standardiser les entrées pour que les coefficients et les solveurs à gradient se comportent correctement
  • Logistic Regression — prédire des catégories (oui/non, spam/non-spam) plutôt que des valeurs continues
Was this page helpful?