Cours
Une grande partie de ce qu’il faut savoir pour plonger sérieusement dans le machine learning, c’est l’algèbre linéaire — et c’est précisément l’objet de ce tutoriel. Ce billet passe en revue les notions d’algèbre linéaire à connaître pour affiner votre intuition sur le fonctionnement et les cas d’usage des méthodes de machine learning, en travaillant au niveau des vecteurs et des matrices.
À la fin du tutoriel, vous devriez vous sentir plus à l’aise pour examiner de près un algorithme !
Sommaire
Introduction
Le machine learning est l’un des trois piliers à maîtriser pour apprendre la data science. Et lorsque vous allez au fond des choses, il est essentiel d’approfondir pour développer une intuition sur le fonctionnement des algorithmes.
Et vous, data scientist (en devenir), serez sans doute d’accord : atteindre ce niveau n’est pas toujours simple.
Mais ce n’est pas une fatalité.
SciPy versus NumPy
D’après le tutoriel NumPy de DataCamp, vous avez compris que cette bibliothèque est l’une des bases du calcul scientifique en Python. Elle offre un ensemble d’outils et de techniques pour résoudre sur ordinateur des modèles mathématiques issus des sciences et de l’ingénierie. L’outil le plus utilisé est l’objet tableau multidimensionnel haute performance : une structure de données puissante pour calculer efficacement sur des tableaux et des matrices.
Or, SciPy, c’est essentiellement NumPy.
C’est aussi un package clé du calcul scientifique, qui fournit des algorithmes mathématiques et des fonctions pratiques, mais il est construit sur l’extension NumPy de Python. Concrètement, SciPy et NumPy sont souvent utilisés ensemble !
La suite du tutoriel montrera à quel point la complémentarité des deux bibliothèques va de soi.
Interagir avec NumPy et SciPy
Pour travailler efficacement avec ces deux packages, il faut d’abord connaître les bases de la bibliothèque et de sa structure de données puissante. Pour manipuler ces tableaux, un grand nombre de fonctions mathématiques de haut niveau opèrent sur matrices et tableaux.
Dans ce qui suit, vous trouverez un aperçu rapide des notions à maîtriser pour travailler efficacement avec SciPy : comprendre la structure des tableaux, gérer les types de données et modifier la forme des tableaux. Si tout cela vous semble obscur, suivez le Python NumPy Tutorial de DataCamp et, pendant que vous apprenez, gardez à portée de main la feuille de triche NumPy.
Si vous savez déjà tout cela, passez la section suivante et rendez‑vous à « Algèbre linéaire avec SciPy », mais conservez votre feuille de triche SciPy pour l’algèbre linéaire !
L’essentiel sur les objets NumPy ndarray
Structurellement, un tableau n’est rien d’autre qu’un ensemble de pointeurs : une adresse mémoire, un type de données, une forme (shape) et des « strides ». Il contient des informations sur les données brutes, comment localiser un élément et comment l’interpréter.
L’adresse mémoire et les strides sont utiles quand on s’aventure dans les détails bas niveau, tandis que le type de données et la forme sont des notions que les débutants doivent absolument comprendre. Deux autres attributs utiles sont data et size, pour en savoir plus sur votre tableau.
Rafraîchissez l’usage des attributs d’ndarray dans l’extrait DataCamp Light ci‑dessous. Le tableau myArray est déjà chargé. Vous pouvez l’inspecter en le tapant dans le shell IPython puis en appuyant sur ENTRÉE.
Vous verrez dans les résultats que le type de données de myArray est int64. Quand on travaille intensivement avec des tableaux, on retient vite qu’il existe des moyens de convertir les types via la méthode astype().
Cela dit, lorsque vous utilisez SciPy et NumPy ensemble, les fonctions NumPy suivantes de gestion des types s’avèrent très utiles, notamment avec les nombres complexes :
Ajoutez des appels à print() pour visualiser les résultats. Vous verrez que les nombres complexes comportent une partie réelle et une partie imaginaire. Les fonctions np.real() et np.imag() renvoient respectivement ces composantes.
Vous pouvez également utiliser np.cast pour convertir un tableau vers un autre type, par exemple en float dans l’exemple ci‑dessus.
Le seul point un peu subtil ci‑dessus est np.real_if_close(). Si vous lui fournissez un tableau complexe comme myArray, il renverra un tableau réel si les parties imaginaires sont proches de zéro. Ce seuil « proche de 0 » peut être ajusté via l’argument tol. Amusez‑vous à le modifier pour voir l’effet !
Création de tableaux
Vous savez maintenant inspecter vos tableaux et ajuster leur type, mais nous n’avons pas encore vu explicitement comment les créer. Vous savez déjà que np.array() permet de le faire, mais d’autres routines valent la peine d’être connues : np.eye() et np.identity().
La fonction np.eye() crée une matrice carrée dont la dimension correspond à l’entier positif passé en argument. Les éléments sont des zéros, sauf la diagonale principale remplie de uns. np.identity() fonctionne de même et renvoie également une matrice identité.
Notez cependant que np.eye() accepte un argument supplémentaire k pour choisir l’indice de la diagonale à remplir de uns.
Autres fonctions de création utiles en algèbre linéaire :
np.arange()crée un tableau de valeurs régulièrement espacées entre deux bornes. Vous spécifiez l’incrément,np.linspace()fait de même, mais vous spécifiez le nombre de valeurs souhaitées,np.logspace()crée des valeurs régulièrement espacées sur une échelle logarithmique (base 10).
Ces fonctions permettent de générer des maillages (meshes), utiles pour créer des grilles (meshgrids), évoquées plus haut.
Note : numpy est déjà importé sous l’alias np ci‑dessous !
Maintenant que la mémoire est rafraîchie et que vous savez gérer les types, passons à l’indexation et au slicing.
Indexation et slicing
L’indexation utilise les crochets [] pour accéder aux valeurs du tableau. Autrement dit, elle permet d’extraire un sous‑ensemble d’éléments. Le slicing est proche du sous‑échantillonnage, mais un peu plus avancé : au lieu de viser des emplacements précis, on travaille sur des « régions » de données.
Rafraîchissez ces deux notions avec les exemples suivants :
Maintenant que l’indexation et le slicing sont frais, voici quelques astuces d’indexation pour gagner en efficacité avec SciPy. Quatre fonctions reviennent souvent : np.mgrid(), np.ogrid(), np.r et np.c.
Vous connaissez peut‑être déjà les deux dernières si vous avez pratiqué NumPy : np.r et np.c servent à empiler des tableaux par lignes ou par colonnes. Elles permettent de construire rapidement des tableaux sans recourir à np.concatenate().
Pourquoi un meshgrid ? Pour générer deux tableaux contenant les coordonnées x et y à chaque position d’une grille rectangulaire. np.meshgrid() prend deux tableaux 1D et produit deux matrices 2D correspondant à toutes les paires (x, y).
np.mgrid()implémente le meshgrid de MATLAB et renvoie des tableaux de même forme : les dimensions et le nombre de tableaux de sortie correspondent au nombre de dimensions d’indexation.np.ogrid()génère un meshgrid « ouvert », moins dense quenp.mgrid(). La différence visuelle apparaît dans l’extrait ci‑dessus.
Vous pouvez lire davantage sur leurs différences ici.
Autre fonction utile pour indexer/slicer : np.select(). Elle renvoie des valeurs issues d’une liste de tableaux en fonction de conditions passées en premier argument. En second argument, vous passez le tableau à considérer.
Exemple :
Parfait ! Maintenant que vous avez sélectionné les bonnes valeurs, vous pouvez encore choisir la forme et manipuler votre nouveau tableau.
Sélection et manipulation de la forme
NumPy propose de nombreuses façons de sélectionner et de manipuler la forme des tableaux. Voici un bref aperçu des fonctions les plus utiles dans ce contexte.
Les plus pratiques avec SciPy ? Celles qui aident à aplatir, empiler et scinder des tableaux. Vous avez vu np.c et np.r, souvent préférés à np.concatenate(), mais il y en a d’autres !
Par exemple np.hstack() pour empiler horizontalement, np.vstack() pour empiler verticalement. Et pour scinder : np.hsplit() horizontalement et np.vsplit() verticalement. Prouvez‑le dans l’extrait suivant :
Rappel : np.eye() crée une matrice identité 2×2, parfaite à empiler avec le tableau 2D chargé ci‑dessus.
Pour en savoir plus sur les conditions d’empilement, rendez‑vous ici. Vous pouvez aussi examiner les formes et le comportement des fonctions pour en déduire les « règles » d’assemblage par lignes ou colonnes.
Lors du découpage (split), la forme du tableau est déterminante pour choisir l’indice de séparation.
En plus des routines d’empilement et de découpage, gardez à l’esprit les fonctions qui garantissent une certaine dimensionnalité — indispensables en calcul scientifique.
Considérez les fonctions suivantes :
Notez la différence entre reshape et resize. Le premier modifie la forme sans changer les données. Le second peut modifier le contenu selon la nouvelle forme.
Au‑delà de ces manipulations, pensez à la « vectorisation ». Lorsqu’une fonction s’applique élément par élément à un tableau (np.cos(), np.sin(), np.tan()…), elle est dite vectorisée.
Pour vos propres fonctions, vous pouvez les vectoriser avec np.vectorize() :
Parmi les autres fonctions vectorisées utiles : np.angle() (angle des éléments complexes), ainsi que les fonctions trigonométriques, exponentielles et logarithmiques de base.
Algèbre linéaire avec SciPy
Maintenant que vous savez tirer parti des deux packages, passons au cœur du sujet : l’algèbre linéaire.
Mais avant de plonger dans Python, vérifiez que votre environnement est fin prêt !
Installer SciPy
Assurez‑vous d’abord que Python est installé. Rendez‑vous sur cette page si nécessaire :) Sous Windows, ajoutez Python à la variable d’environnement PATH. N’oubliez pas d’installer un gestionnaire de packages comme pip pour accéder aux bibliothèques open source de Python.
Notez que les versions récentes de Python 3 incluent pip ; vérifiez sa présence et mettez‑le à jour avant d’installer d’autres packages :
pip install pip --upgrade pip --version
Mais un gestionnaire de packages ne suffit pas toujours ; vous devez aussi télécharger la « wheel » de la bibliothèque : rendez‑vous ici pour récupérer la wheel SciPy. Après téléchargement, ouvrez un terminal dans le dossier et installez‑la. Vous pouvez ensuite vérifier l’installation et la version du package utilisé :
# Install the wheel install "scipy‑0.18.1‑cp36‑cp36m‑win_amd64.whl"# Confirm successful installimport scipy# Check package versionscipy.__version__
Après ces étapes, vous êtes prêt à démarrer !
Astuce : installez le package via la distribution Anaconda. C’est un moyen simple de débuter rapidement, car Anaconda inclut non seulement 100 des packages Python, R et Scala les plus populaires pour la data science, mais aussi plusieurs environnements de développement comme Jupyter et Spyder. Pour démarrer avec Jupyter Notebook, consultez ce tutoriel Jupyter.
Si vous ne l’avez pas encore téléchargée, allez ici.
Vecteurs et matrices : les bases
Une fois l’environnement prêt, vous pouvez attaquer l’algèbre linéaire en Python. En substance, cette discipline étudie les espaces vectoriels et les applications linéaires entre ces espaces. Ces applications se décrivent par des matrices, ce qui facilite les calculs.
Rappel : un espace vectoriel est un concept fondamental. C’est un espace dans lequel on peut additionner et mettre à l’échelle des vecteurs sans sortir de l’espace. Les vecteurs correspondent aux lignes (ou colonnes) d’une matrice.
Et en Python ?
Créez facilement un vecteur avec np.array(). De même, vous pouvez donner une structure matricielle à tout ndarray 1D ou 2D via np.matrix() ou np.mat().
Essayez dans l’extrait suivant :
Tableaux et matrices sont‑ils équivalents, à la mise en forme près ?
Pas exactement. Il y a des différences :
- Une matrice est 2D, tandis que les tableaux sont généralement
nD, - Comme le suggèrent les fonctions ci‑dessus,
matrixest une sous‑classe d’ndarray, - Tableaux et matrices ont
.T(), mais seules les matrices ont.H()et.I(), - La multiplication matricielle diffère de la multiplication élément par élément des tableaux,
- Et l’opérateur
**n’a pas le même comportement.
Vous manipulerez parfois des matrices dont la plupart des éléments sont nuls : ce sont des « matrices creuses » (sparse), par opposition aux « denses ».
Avec SciPy, ce choix influe sur les modules à utiliser. Pour les matrices denses : scipy.linalg. Pour les creuses : scipy.sparse et son sous‑module scipy.sparse.linalg.
Pour les matrices creuses, plusieurs options de création existent. En voici quelques‑unes :
Autres fonctions utiles : matrices « Block Sparse Row » avec bsr_matrix(), format de coordonnées coo_matrix(), stockage diagonal dia_matrix(), ou listes chaînées par lignes lil_matrix().
Face au choix, comment décider ?
Commencez par la méthode d’initialisation. Ensuite, réfléchissez aux opérations ciblées.
Check‑list rapide :
- Remplissage élément par élément :
coo_matrix()oudok_matrix(). - Initialisation avec une diagonale :
dia_matrix(). - Découpage par tranches :
lil_matrix(). - Construction par blocs :
bsr_matrix(). - Accès rapide aux lignes/colonnes : convertissez en
csr_matrix()/csc_matrix(). Moins indiquées pour l’initialisation, mais très performantes en multiplication.
Simple et efficace !
Opérations sur les vecteurs
Après la différence vecteurs / matrices denses / matrices creuses, voyons de plus près les vecteurs et les opérations mathématiques associées. L’objectif : faire apparaître similitudes et différences avec les matrices, puisque l’algèbre linéaire repose largement sur ces dernières.
Vous savez créer un vecteur avec np.array(). Voici quelques opérations de base. vector1 et vector2 sont déjà chargés :
Maintenant que vous avez vu quelques opérations vectorielles, place aux matrices !
Matrices : opérations et routines
Vous savez créer des matrices ; voyons comment les exploiter. Cette section dresse un panorama de fonctions et routines de base pour travailler efficacement.
Commençons par des fonctions simples, familières si vous avez déjà utilisé NumPy : np.add() et np.subtract() pour additionner/soustraire, np.divide() et np.multiply pour diviser/multiplier. Rien de mystérieux. np.dot(), déjà vue pour le produit scalaire, s’applique aussi aux matrices — en passant deux matrices.
Bases acquises ?
Allons un cran plus loin. Pour les multiplications : np.vdot() (produit scalaire de vecteurs), np.inner() et np.outer() (produits intérieur/extérieur), np.tensordot() et np.kron() (produit de Kronecker) :
Astuce : ajoutez des print pour observer chaque résultat.
À cela s’ajoutent des fonctions du module linalg : exponentielle matricielle linalg.expm(), linalg.expm2(), linalg.expm3() (diffèrent par la méthode de calcul — commencez par expm()),
ainsi que linalg.cosm(), linalg.sinm(), linalg.tanm() (trigonométrie), linalg.coshm(), linalg.sinhm(), linalg.tanhm() (trigonométrie hyperbolique), linalg.signm() (signe), linalg.logm() (logarithme), linalg.sqrtm() (racine carrée).
Vous pouvez aussi évaluer une fonction de matrice avec linalg.funm(). Exemple :
Vous passez d’abord la matrice ciblée, puis la fonction (ici une lambda). La fonction fournie à linalg.funm() doit être vectorisée.
Regardons maintenant quelques routines de base. Les attributs : T (transposition), H (transconjuguée), I (inverse), A (conversion en tableau).
Essayez :
La transposition échange lignes et colonnes. La transposition conjuguée fait de même avec conjugaison complexe. L’inverse d’une matrice est telle que son produit avec la matrice d’origine donne l’identité.
Outre ces attributs, vous pouvez utiliser np.transpose() et linalg.inv() pour la transposition et l’inverse, respectivement.
Vous pouvez aussi obtenir la trace (somme de la diagonale principale) avec np.trace(). De même, le rang d’une matrice (nombre de valeurs singulières SVD supérieures à un seuil) via linalg.matrix_rank de NumPy.
Pas clair pour le rang ? Pas d’inquiétude, on y revient plus loin.
Deux autres routines utiles :
- La norme matricielle via
linalg.norm— un indicateur de « taille » des éléments. - Le déterminant d’une matrice carrée via
linalg.det(), qui conditionne notamment l’inversibilité.
Enfin, la résolution de grands systèmes linéaires est un cas d’usage fondamental. Pour un système \(Ax = b\) (avec \(A\) carrée et \(b\) général), deux méthodes selon le type de matrice :
Pour les matrices creuses : linalg.spsolve(). Si la résolution exacte échoue, linalg.lstsq() peut fournir une solution approchée de \(x\).
Astuce : ne manquez pas la feuille de triche SciPy de DataCamp.
Maintenant que vous savez créer et manipuler des matrices, passons à des notions plus avancées, indispensables pour le machine learning.
Valeurs propres et vecteurs propres
Premier sujet : valeurs propres et vecteurs propres.
Les valeurs propres offrent une nouvelle façon de « lire » une matrice. Avant cela, définissons les vecteurs propres. La plupart des vecteurs changent de direction lorsqu’on les multiplie par une matrice. Certains vecteurs exceptionnels restent pourtant alignés : ce sont les vecteurs propres.
Autrement dit, multiplier un vecteur propre par une matrice revient à multiplier ce vecteur par \(\lambda\), la valeur propre : \[Ax = \lambda x. \]
La valeur propre indique donc si l’un des vecteurs propres est étiré, contracté, inversé ou inchangé par la matrice.
Utilisez la fonction eig() du module SciPy linalg pour résoudre les problèmes de valeurs/vecteurs propres (ordinaires ou généralisés) de matrices carrées.
Notez que eigvals() permet d’extraire uniquement les valeurs propres.
Pour les matrices creuses, utilisez le module scipy.sparse :
la, v = sparse.linalg.eigs(myMatrix,1)
Note : le code ci‑dessus précise le nombre de valeurs/vecteurs propres à récupérer : ici 1.
Ces notions sont clés en vision par ordinateur et en machine learning, par exemple en ACP (réduction de dimension) ou avec EigenFaces pour la reconnaissance de visages.
Décomposition en valeurs singulières (SVD)
Ensuite, la SVD est incontournable en data science. La décomposition en valeurs singulières d’une matrice \(A\) consiste à factoriser \(A\) en produit de trois matrices : \(A = U * \Sigma * V^t\).
Si \(A\) est de taille \(M\) × \(N\) :
- \(U\) est de taille \(M\) × \(M\)
- \(V\) est de taille \(N\) × \(N\)
- \(\Sigma\) est de taille \(M\) × \(N\)
Le symbole \(*\) indique une multiplication, et \(^t\) dans \(V^t\) signifie « transposée ».
En bref, la SVD permet de décomposer une matrice en éléments plus simples et porteurs d’information.
Note : pour les matrices creuses, utilisez sparse.linalg.svds().
Si vous débutez, la factorisation matricielle peut sembler abstraite. Pourtant, la SVD sert à la compression, la réduction de bruit, l’analyse de données… Voici un exemple de compression d’image via SVD :
# Import the necessary packagesimport numpy as npfrom scipy import linalgfrom skimage import dataimport matplotlib.pyplot as plt# Get an image from `skimage`img= data.camera()# Check number of singular valueslinalg.svdvals(img)# Singular Value DecompositionU, s, Vh = linalg.svd(img)# Use only 32 singular valuesA = np.dot(U[:,0:32], np.dot(np.diag(s[0:32]), Vh[0:32,:]))fig = plt.figure(figsize=(8, 3))# Add a subplot to the figureax = fig.add_subplot(121)# Plot `img` on grayscaleax.imshow(img, cmap='gray')# Add a second subplot to the figureax2 = fig.add_subplot(122)# Plot `A` in the second subplotax2.imshow(A)# Add a titlefig.suptitle('Image Compression with SVD', fontsize=14, fontweight='bold')# Show the plotplt.show()
Ce qui donne le résultat suivant :

Autres exemples d’usage :
- La SVD est étroitement liée à l’ACP (réduction de dimension) : les deux produisent de « nouveaux axes » construits par combinaisons linéaires des axes du jeu de caractéristiques. Ces axes décomposent la variance selon la contribution de chaque direction. Pour un exemple concret, consultez notre tutoriel Scikit-Learn.
- Autre lien : le text mining et le NLP avec le Latent Semantic Indexing (LSI). Cette technique pour la recherche documentaire et la similarité de mots s’appuie sur la SVD pour regrouper les documents par concepts. Elle réduit le bruit dans les corrélations mots‑documents et diminue la dimensionnalité initiale.
Vous le voyez, la SVD est une brique essentielle de votre parcours data. Pour aller plus loin, lisez par exemple cet article.
Et maintenant ?
Vous êtes arrivé au bout du tutoriel ! La suite dépend de vos objectifs.
Mais attendez !
Ne passez pas à côté de cours qui vont plus loin en algèbre linéaire : ce tutoriel n’est qu’une introduction et ne couvre pas tout.
Pensez aussi à suivre le tutoriel Machine Learning de DataCamp, qui complétera parfaitement votre programme de formation après ce tutoriel SciPy sur l’algèbre linéaire. Et si vous souhaitez revenir aux bases, parcourez notre tutoriel NumPy ou le cours Intermediate Python for Data Science.
