É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 :
X, y
X*W+b
MSE
X.T*error
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
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énario | Lien avec ce cas |
|---|---|
| Modèle de référence | Le 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 neurones | La couche de sortie de nombreux réseaux est une couche linéaire — essentiellement une régression linéaire |
| Analyse de l'importance des caractéristiques | Aprè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 |