Algèbre Linéaire pour le ML
“La géométrie derrière chaque modèle — produits scalaires, transformations matricielles et décomposition propre”
Vecteurs, produits scalaires, multiplication matricielle, décomposition propre et SVD — avec l'intuition visuelle de la transformation de l'espace.
Prérequis
Concepts Couverts
∑Formules Clés
Produit Scalaire
Mesure l'alignement de deux vecteurs — zéro signifie orthogonal, maximal quand parallèles
Multiplication de Matrices
Composition de deux transformations linéaires — appliquer B d'abord, puis A
Décomposition en Valeurs Propres
Les vecteurs propres v restent sur leur espace sous A ; λ est le facteur d'échelle
Décomposition en Valeurs Singulières (DVS)
Toute matrice se décompose en rotation × échelle × rotation — utilisé dans ACP, LSA, systèmes de recommandation
▶Simulation Interactive
Pourquoi l'Algèbre Linéaire EST le Machine Learning
Une couche de réseau de neurones, c'est y = Wx + b — une multiplication matricielle. La descente de gradient nécessite le calcul du gradient, qui est une matrice Jacobienne. L'ACP trouve les vecteurs propres principaux de la matrice de covariance. L'attention dans les Transformers est Q·Kᵀ·V — trois multiplications matricielles. Chaque passe avant, chaque rétropropagation, chaque étape d'optimisation est de l'algèbre linéaire.
Le produit scalaire a·b = ‖a‖‖b‖cos(θ) est la base de la similarité cosinus (NLP), de l'astuce du noyau (SVM) et des mécanismes d'attention (Transformers).
Les Matrices comme Transformateurs d'Espace
Chaque matrice m×n A représente une transformation linéaire de ℝⁿ vers ℝᵐ. Multiplier un vecteur v par A l'étire, le fait tourner, le réfléchit ou le projette. Le déterminant vous indique le facteur de mise à l'échelle du volume : |det(A)| = 2 signifie que chaque région double en surface. det = 0 signifie que la matrice effondre l'espace sur une dimension inférieure.
Visualisez toute matrice 2×2 en regardant où va le carré unité [0,1]×[0,1]. Les quatre coins vont en (0,0), la première colonne, la deuxième colonne, et leur somme.
Décomposition Propre Étape par Étape
Trouver les valeurs propres : résoudre det(A - λI) = 0 (polynôme caractéristique). Pour 2×2 : λ = (tr(A) ± √(tr²-4det)) / 2.
Pour chaque valeur propre λᵢ : résoudre (A - λᵢI)v = 0 pour trouver le vecteur propre vᵢ. Normaliser : ‖vᵢ‖ = 1.
Empiler les vecteurs propres comme colonnes de Q : A = QΛQ⁻¹ où Λ = diag(λ₁, λ₂, …)
Pour les matrices symétriques (matrices de covariance) : Q est orthogonale (Q⁻¹ = Qᵀ), valeurs propres réelles.
Aⁿ = QΛⁿQ⁻¹ — les grandes valeurs propres dominent l'application répétée (ex. : itération de puissance).
ACP : calculer la covariance C = XᵀX/n, décomposer en vecteurs propres, prendre les k premiers comme matrice de projection.
Algèbre Linéaire avec NumPy
import numpy as np class="tok-comment"># ── Vecteurs et produits scalaires ──────────────────────────────────────────── a = np.array([class="tok-num">3., class="tok-num">4.]) b = np.array([class="tok-num">1., class="tok-num">0.]) print(fclass="tok-str">"a·b = {np.dot(a, b):.2f}") class="tok-comment"># class="tok-num">3.0 print(fclass="tok-str">"‖a‖ = {np.linalg.norm(a):.2f}") class="tok-comment"># class="tok-num">5.0 print(fclass="tok-str">"cos(θ) = {np.dot(a,b)/(np.linalg.norm(a)*np.linalg.norm(b)):.3f}") class="tok-comment"># class="tok-num">0.6 class="tok-comment"># Similarité cosinus (NLP / recommandation) def cosine_sim(u, v): return np.dot(u, v) / (np.linalg.norm(u) * np.linalg.norm(v)) class="tok-comment"># ── Opérations matricielles ─────────────────────────────────────────────────── A = np.array([[class="tok-num">2., class="tok-num">1.], [class="tok-num">0., class="tok-num">3.]]) B = np.array([[class="tok-num">1., class="tok-num">0.], [class="tok-num">2., class="tok-num">1.]]) print(class="tok-str">"A @ B =") print(A @ B) class="tok-comment"># multiplication matricielle (composition) print(fclass="tok-str">"det(A) = {np.linalg.det(A):.2f}") class="tok-comment"># class="tok-num">6.0 — facteur d'échelle volumique print(fclass="tok-str">"rang(A) = {np.linalg.matrix_rank(A)}") class="tok-comment"># class="tok-num">2 — rang plein A_inv = np.linalg.inv(A) print(class="tok-str">"A @ A_inv ≈ I :", np.allclose(A @ A_inv, np.eye(class="tok-num">2))) class="tok-comment"># ── Décomposition propre ────────────────────────────────────────────────────── val_propres, vect_propres = np.linalg.eig(A) print(fclass="tok-str">"Valeurs propres : {val_propres}") class="tok-comment"># [class="tok-num">2. class="tok-num">3.] print(fclass="tok-str">"Vecteurs propres (colonnes) :\n{vect_propres.round(class="tok-num">3)}") class="tok-comment"># Vérification : A @ v = λ * v for i in range(len(val_propres)): v = vect_propres[:, i] lam = val_propres[i] print(fclass="tok-str">"λ{i+class="tok-num">1}={lam:.2f}, Aclass="tok-dec">@v = {Aclass="tok-dec">@v.round(class="tok-num">3)}, λ*v = {(lam*v).round(class="tok-num">3)}") class="tok-comment"># Reconstruction de A depuis la décomposition propre Q = vect_propres Lambda = np.diag(val_propres) A_reconstruit = Q @ Lambda @ np.linalg.inv(Q) print(class="tok-str">"Erreur de reconstruction :", np.linalg.norm(A - A_reconstruit)) class="tok-comment"># ── Décomposition en Valeurs Singulières (DVS) ──────────────────────────────── M = np.random.randn(class="tok-num">4, class="tok-num">3) class="tok-comment"># matrice rectangulaire class="tok-num">4×class="tok-num">3 U, S, Vt = np.linalg.svd(M, full_matrices=False) print(fclass="tok-str">"U : {U.shape}, S : {S.shape}, Vt : {Vt.shape}") class="tok-comment"># Approximation de rang faible (garder les k valeurs singulières principales) k = class="tok-num">2 M_approx = U[:, :k] @ np.diag(S[:k]) @ Vt[:k, :] print(fclass="tok-str">"Erreur approx rang-{k} : {np.linalg.norm(M - M_approx):.4f}") class="tok-comment"># ── ACP depuis zéro ─────────────────────────────────────────────────────────── X = np.random.randn(class="tok-num">200, class="tok-num">5) X -= X.mean(axis=class="tok-num">0) class="tok-comment"># centrer C = (X.T @ X) / (len(X) - class="tok-num">1) class="tok-comment"># matrice de covariance val_propres, vect_propres = np.linalg.eigh(C) class="tok-comment"># eigh pour matrices symétriques idx = np.argsort(val_propres)[::-class="tok-num">1] class="tok-comment"># trier par ordre décroissant CP = vect_propres[:, idx[:class="tok-num">2]] class="tok-comment"># class="tok-num">2 premières composantes principales X_proj = X @ CP class="tok-comment"># projection en 2D print(fclass="tok-str">"Variance expliquée : {val_propres[idx[:class="tok-num">2]] / val_propres.sum() * class="tok-num">100}")
Stabilité Numérique et Mauvais Conditionnement
Le numéro de condition κ(A) = σ_max/σ_min mesure la sensibilité aux perturbations. Numéro de condition élevé → mal conditionné → les erreurs numériques s'amplifient. La descente de gradient converge lentement sur des paysages de perte mal conditionnés — c'est pourquoi la mise à l'échelle des caractéristiques est importante. N'inversez jamais directement une matrice avec np.linalg.inv(A) si vous résolvez Ax=b — utilisez np.linalg.solve(A,b) qui est plus rapide et plus stable.
np.linalg.cond(A) vous donne le numéro de condition. κ > 10⁶ signifie des problèmes — les solutions auront ~6 chiffres significatifs de moins que prévu.
?Vérification des Connaissances
La progression est sauvegardée dans votre navigateur — aucun compte requis.
Besoin d'un ingénieur IA ou data scientist ?
Je conçois des modèles ML sur mesure, des agents IA, de la vision par ordinateur et de l'automatisation — de l'idée à la production.