Écrire une régression linéaire multiple à partir de zéro

Appliquer de manière complète les opérations matricielles + la descente de gradient + MSE, et parcourir entièrement le processus complet de « données → modèle → entraînement → prédiction ».

Après avoir étudié ce cas, vous comprendrez :Un modèle d'apprentissage automatique qui peut fonctionner est essentiellement une combinaison d'algèbre linéaire + de calcul différentiel + d'optimisation.


Introduction à la vie

Estimer les prix immobiliers — Pas seulement la superficie

Le prix des maisons dépend non seulement de la superficie, mais aussi du nombre de chambres, de l'étage, de la proximité du métro, de l'âge du bâtiment... Chaque facteur a son propre poids.

La régression linéaire multiple consiste à :Donner à chaque facteur un poids w, multiplier tous les facteurs par leurs poids et les additionner, puis ajouter un prix de base b.Ensuite, utiliser des données historiques de transactions pour inférer ces poids — c'est l'entraînement.


Compréhension intuitive

La boucle d'apprentissage automatique complète en cinq étapes :

Préparer les données
X, y
Prédiction avant
X*W+b
Calculer la perte
MSE
Calculer le gradient
X.T*error
Mettre à jour les paramètres
W-=lr*dW

Ces cinq étapes sont exécutées en boucle à chaque itération jusqu'à ce que la perte converge. La méthode fit() dans PyTorch/TensorFlow est exactement cette boucle en interne.


Définition mathématique

\[ \hat{y} = XW + b, \quad L = \frac{1}{n}\sum(\hat{y}_i - y_i)^2 \] \[ \frac{\partial L}{\partial W} = \frac{2}{n} X^T (XW + b - y), \quad \frac{\partial L}{\partial b} = \frac{2}{n} \sum (XW + b - y) \]

Exercice pratique Python

Exemple

import numpy as np
np.random.seed(0)


class LinearRegressionFromScratch:
    """Entièrement implémenté avec des opérations matricielles NumPy + descente de gradient"""

    def __init__(self, lr=0.01, epochs=500):
        self.lr = lr
        self.epochs = epochs
        self.W = None
        self.b = None
        self.loss_history = []

    def fit(self, X, y):
        n_samples, n_features = X.shape
        self.W = np.zeros(n_features)
        self.b = 0.0

        for epoch in range(self.epochs):
            y_pred = X @ self.W + self.b
            error = y_pred - y
            loss = np.mean(error ** 2)
            self.loss_history.append(loss)

            dW = (2 / n_samples) * (X.T @ error)
            db = (2 / n_samples) * np.sum(error)

            self.W -= self.lr * dW
            self.b -= self.lr * db

            if epoch % 100 == 0:
                print(f"EXEMPLE époque {epoch:4d} perte={loss:.4f}")

    def predict(self, X):
        return X @ self.W + self.b


# Construire les données : y = 3*x1 - 2*x2 + 5 + bruit
X = np.random.uniform(-5, 5, size=(200, 2))
true_W = np.array([3.0, -2.0])
true_b = 5.0
y = X @ true_W + true_b + np.random.randn(200) * 1.5

model = LinearRegressionFromScratch(lr=0.01, epochs=500)
model.fit(X, y)

print(f"\nEXEMPLE appris : W={np.round(model.W, 3)}, b={round(model.b, 3)}")
print(f"Vrai : W={true_W}, b={true_b}")
print(f"Perte : {model.loss_history[0]:.1f} -> {model.loss_history[-1]:.2f}")

# Prédire de nouveaux échantillons
X_new = np.array([[1.0, 1.0], [-2.0, 3.0]])
print(f"Prédiction : {np.round(model.predict(X_new), 2)}")
EXAMPLE epoch    0  loss=157.0828
EXAMPLE epoch  100  loss=2.6062
EXAMPLE epoch  200  loss=2.3077
EXAMPLE epoch  300  loss=2.2581
EXAMPLE epoch  400  loss=2.2475

EXAMPLE 学到的: W=[ 3.014 -2.017], b=4.737
真实的:       W=[ 3. -2.], b=5.0
损失: 157.1 -> 2.25
预测: [5.73 -4.18]

Scénarios d'application en IA

ScénarioLien avec ce cas
Modèle de référenceLe premier modèle pour toute tâche de régression devrait être la régression linéaire — simple et interprétable
La dernière couche d'un réseau de neuronesLa couche de sortie de nombreux réseaux est une couche linéaire — essentiellement une régression linéaire
Analyse de l'importance des caractéristiquesAprès l'entraînement, examinez la taille de W — les caractéristiques avec des valeurs absolues plus grandes ont un impact plus important sur le résultat
Autres extensions