Accéder au contenu principal

Décomposition QR en apprentissage automatique : guide détaillé

Découvrez la décomposition QR, la factorisation matricielle qui décompose la matrice A en produit d’une matrice orthogonale Q et d’une matrice triangulaire supérieure R.
Actualisé 19 sept. 2026  · 12 min lire

Explorer avec l’IA

ChatGPTClaudePerplexity

La décomposition QR est une technique fondamentale de factorisation matricielle, largement utilisée en science des données et en apprentissage automatique. Sa capacité à décomposer des matrices complexes en éléments plus simples en fait une méthode incontournable pour résoudre des problèmes d’algèbre linéaire et améliorer la stabilité des algorithmes.

Que vous réalisiez une régression linéaire aux moindres carrés ordinaires ou que vous construisiez des moteurs de recommandation en Python ou en PySpark, comprendre la décomposition QR peut considérablement renforcer votre capacité à traiter de grands jeux de données et des modèles mathématiques complexes. 

Qu’est-ce que la décomposition QR ?

Factoriser, ou décomposer, une matrice consiste à exprimer cette matrice comme le produit de deux matrices (ou plus). Autrement dit, la factorisation matricielle permet de scinder une matrice en composants plus simples qui, multipliés entre eux, reconstituent la matrice d’origine. La factorisation matricielle nous intéresse car elle simplifie de nombreux problèmes d’algèbre linéaire et facilite leur résolution. 

La décomposition QR est un type spécifique de factorisation qui décompose une matrice en le produit d’une matrice orthogonale Q et d’une matrice triangulaire supérieure R. L’équation courante est A = QR

Visualisation de la décomposition QR

Décomposition QR visualisée. Source : ResearchGate

Pour comprendre la décomposition QR, il faut garder à l’esprit qu’en algèbre linéaire, la multiplication de matrices ne suit pas les mêmes règles intuitives que la multiplication de scalaires. En particulier, la multiplication de matrices n’est pas commutative : en général, AB ≠ BA, et la notion d’« inverse » s’en trouve plus subtile.

Que sont les matrices Q et R ?

Regardons de plus près les deux matrices clés, Q et R.

Matrice orthogonale Q

Une matrice orthogonale Q est caractérisée par le fait que sa transposée est aussi son inverse : mathématiquement, QTQ = QQT = I, où I est la matrice identité. Transposer, pour rappel, revient à « retourner » la matrice par rapport à sa diagonale.

Une matrice orthogonale se caractérise aussi par le fait que ses colonnes forment une base orthonormée. Cela signifie deux choses : d’une part, les colonnes sont orthogonales, c’est-à-dire que le produit scalaire de deux colonnes distinctes est nul ; d’autre part, chaque colonne est de norme unitaire.

Les matrices orthogonales sont agréables à manipuler car elles préservent les longueurs des vecteurs et leurs produits scalaires. Ainsi, si vous multipliez un vecteur par une matrice orthogonale, sa longueur reste inchangée. De même, si vous multipliez deux vecteurs par la même matrice orthogonale, leur produit scalaire reste inchangé. Enfin, comme elles préservent longueurs et produits scalaires, elles ne déforment pas les propriétés géométriques après transformation : deux vecteurs perpendiculaires avant la transformation le resteront après application de la matrice orthogonale. 

Matrice triangulaire supérieure R

Une matrice triangulaire supérieure R est une matrice dont tous les éléments situés sous la diagonale principale sont nuls. Cette forme simplifie les équations matricielles et s’avère particulièrement utile pour résoudre des systèmes linéaires via la substitution arrière, entre autres. On peut aussi dire que, dans la décomposition QR, R représente la composante qui capture l’« amplitude » et l’orientation de la matrice d’origine.

Méthodes pour réaliser une décomposition QR

Passons en revue quelques méthodes courantes pour effectuer une décomposition QR.

Le procédé de Gram–Schmidt 

Le procédé de Gram–Schmidt est un algorithme qui convertit systématiquement un ensemble de vecteurs linéairement indépendants en un ensemble orthonormé. Il sert spécifiquement à construire la matrice Q dans la décomposition QR et, une fois Q obtenue, on peut en déduire R

Rotations de Givens

Les rotations de Givens constituent une autre approche de la décomposition QR. Elles appliquent une série de rotations planes pour introduire des zéros sous la diagonale de la matrice A. Chaque rotation agit sur une paire de coordonnées, en préservant la norme du vecteur tout en transformant la matrice en forme triangulaire supérieure. Cette méthode est efficace pour les matrices creuses, car elle ne modifie qu’une petite portion de la matrice à chaque étape.

Réflexions de Householder

Les réflexions de Householder forment une technique plus générale qui utilise des matrices de réflexion, dites matrices de Householder, pour annuler systématiquement les éléments sous-diagonaux de la matrice A. Chaque matrice de Householder reflète un vecteur par rapport à un hyperplan orthogonal au vecteur choisi pour annuler une colonne sous la diagonale. On obtient ainsi une matrice orthogonale Q et une matrice triangulaire supérieure R. Les réflexions de Householder sont particulièrement indiquées pour les matrices denses grâce à leur stabilité numérique.

Implémenter la décomposition QR en R

Dans cette section, nous allons pratiquer la décomposition QR en R : d’abord avec la fonction intégrée qr() pour une mise en œuvre rapide, puis en reprenant le raisonnement depuis zéro via le procédé de Gram–Schmidt afin de développer l’intuition. Commençons par créer matrix_A, que nous utiliserons dans les deux parties.  

matrix_A <- matrix(c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2, 17.8, 16.4, 17.3, 15.2, 10.4, 10.4, 14.7, 32.4, 30.4, 33.9, 21.5, 15.5, 15.2, 13.3, 19.2, 27.3, 26, 30.4, 15.8, 19.7, 15, 21.4, 
              2.62, 2.875, 2.32, 3.215, 3.44, 3.46, 3.57, 3.19, 3.15, 3.44, 3.44, 4.07, 3.73, 3.78, 5.25, 5.424, 5.345, 2.2, 1.615, 1.835, 2.465, 3.52, 3.435, 3.84, 3.845, 1.935, 2.14, 1.513, 3.17, 2.77, 3.57, 2.78, 
              110, 110, 93, 110, 175, 105, 245, 62, 95, 123, 123, 180, 180, 180, 205, 215, 230, 66, 52, 65, 97, 150, 150, 245, 175, 66, 91, 113, 264, 175, 335, 109), 
            nrow = 32, ncol = 3, byrow = FALSE)

# Add column names
colnames(matrix_A) <- c("column_1", "column_2", "column_3")

Décomposition QR avec la fonction qr()

On peut effectuer cette factorisation en une seule étape avec qr(). On assigne le résultat à un objet qr_decomp, qui est une liste contenant la décomposition QR. 

# Perform and Display the QR decomposition
(qr_decomp <- qr(matrix_A))

En accédant au composant rank de l’objet, on obtient le nombre de colonnes linéairement indépendantes dans la matrice décomposée. La sortie indique un rang de trois, soit trois colonnes linéairement indépendantes, comme attendu. En consultant le composant pivot, on voit la permutation des colonnes utilisée pendant la décomposition. Ici, les indices correspondent à l’ordre d’origine : il n’y a pas eu de permutation.

qr_decomp$rank
qr_decomp$pivot
[1] 3
[1] 1 2 3

Ensuite, on peut extraire les matrices Q et R via qr.Q() et qr.R(). On constate que Q est rectangulaire et R carrée, avec des zéros sous la diagonale. 

# Extract and Display the Q and R matrices
(Q_matrix <- qr.Q(qr_decomp))
(R_matrix <- qr.R(qr_decomp))
           [,1]         [,2]         [,3]
 [1,] -0.17721481  0.023462372 -0.015872336
 [2,] -0.17721481 -0.001889138 -0.060272525
 [3,] -0.19240465  0.077625112 -0.019039920
 [4,] -0.18059033 -0.030282834 -0.118470211
 [5,] -0.15780557 -0.089157964  0.064671266
 [6,] -0.15274229 -0.099258795 -0.187022354
 [7,] -0.12067485 -0.161573766  0.277715036
 [8,] -0.20590673  0.012764996 -0.275768785
 [9,] -0.19240465 -0.004891570 -0.156509401
[10,] -0.16202497 -0.082397566 -0.117343880
[11,] -0.15021065 -0.101326680 -0.120852866
[12,] -0.13839633 -0.182888939 -0.033166125
[13,] -0.14599125 -0.136918208  0.028289904
[14,] -0.12826977 -0.170282764  0.014320506
[15,] -0.08776353 -0.381326588 -0.165554550
[16,] -0.08776353 -0.398625266 -0.160607236
[17,] -0.12405037 -0.332631845 -0.083208412
[18,] -0.27341714  0.219354877 -0.069242665
[19,] -0.25653954  0.250472633 -0.021737724
[20,] -0.28607534  0.275923528 -0.005454217
[21,] -0.18143421  0.045632512 -0.033447865
[22,] -0.13080141 -0.140377926 -0.045388530
[23,] -0.12826977 -0.135983661 -0.031340393
[24,] -0.11223605 -0.201937338  0.228196652
[25,] -0.16202497 -0.122661730 -0.004593473
[26,] -0.23037925  0.176744505 -0.035884026
[27,] -0.21940881  0.138786843  0.013273146
[28,] -0.25653954  0.260613237  0.211010230
[29,] -0.13333305 -0.101525496  0.418085457
[30,] -0.16624437 -0.009027316  0.183837006
[31,] -0.12658201 -0.152109209  0.596664759
[32,] -0.18059033  0.012963861 -0.046253102
      column_1  column_2  column_3
[1,] -118.5003 -16.11602 -711.9200
[2,]    0.0000 -10.05857 -496.9319
[3,]    0.0000   0.00000  283.7369

Par curiosité, vérifions quelle méthode la fonction qr() utilise pour la décomposition. 

?qr

On peut lire notamment ceci dans la documentation :  

The function computes the QR decomposition of a matrix using the LINPACK or LAPACK routine dgeqrf.

En consultant la documentation FORTRAN, on voit que dgeqrf est une routine LAPACK qui s’appuie sur des transformations de Householder. 

Décomposition QR via le procédé de Gram–Schmidt

Essayons de comprendre ce qui se passe avec qr() en recréant non pas la même implémentation, mais une idée similaire en suivant le procédé de Gram–Schmidt. L’objectif n’est pas de reproduire exactement la méthode, mais d’enrichir notre compréhension.

Construction de la matrice Q

Pour commencer la construction de Q avec Gram–Schmidt, nous normalisons la première colonne des données pour obtenir la première colonne de Q. Le but est de transformer l’ensemble de vecteurs de la matrice A en un nouvel ensemble de vecteurs de norme unitaire, mutuellement orthogonaux.

Pour trouver la première colonne de Q, on extrait la première colonne de A, on calcule la norme euclidienne, puis on normalise.

Rappel : la norme euclidienne mesure la longueur (ou amplitude) d’un vecteur dans l’espace euclidien. Elle correspond à la distance entre l’origine et l’extrémité du vecteur, en considérant chaque élément comme une coordonnée en espace multidimensionnel. Pour un vecteur v = [v1, v2, …, vn], sa norme euclidienne se calcule ainsi :

Équation de la norme euclidienne

En R, on élève chaque colonne au carré, on somme, on prend la racine carrée, puis on normalise.

# Extract the first column of the subset data
col_1 <- matrix_A[, 1]

# Calculate the Euclidean norm of the first column
norm_col_1 <- sqrt(sum(col_1^2))

# Normalize and display the first column to get the first column of Q
(q1 <- col_1 / norm_col_1)

Deuxième rappel d’algèbre linéaire : la projection. Une projection est l’opération qui projette un vecteur sur un sous-espace (un espace de dimension inférieure inclus dans l’espace vectoriel). Le résultat est un vecteur du sous-espace, le plus proche possible du vecteur initial projeté, et orthogonal au complémentaire.

Visualisons cela avec le graphique suivant, où la projection p est le point de a le plus proche de b, et elle doit être perpendiculaire à b.

Illustration d’une projection en algèbre linéaire

Illustration d’une projection. Image par l’auteur.

À l’étape suivante de la factorisation QR, nous calculons le deuxième vecteur orthogonal en projetant d’abord la deuxième colonne de A sur la première colonne de Q, puis en soustrayant ce résultat de la deuxième colonne de A. Le vecteur obtenu est orthogonal au premier. Enfin, nous le normalisons pour obtenir la deuxième colonne de Q.

Revenons à l’équation d’une projection. La matrice de projection s’écrit comme a fois a-transposé, divisé par le scalaire a-transposé fois a, puis multiplié par b.

équation de la matrice de projection

Ou, de manière équivalente :

équation de la matrice de projection

Vous vous demandez peut‑être : en quoi ces deux formulations sont‑elles équivalentes ? Dans la première, la partie à gauche de b calcule une matrice qui capture la direction définie par a et son facteur d’échelle. C’est analogue au calcul du vecteur unitaire de a dans la méthode par produit scalaire. 

Le code R suivant calcule la projection du vecteur col_2 sur le vecteur q1 via le produit scalaire.

# Extract the second column of the subset data
col_2 <- matrix_A[, 2]

# Calculate the projection of col_2 onto q1
projection_col_2_q1 <- sum(col_2 * q1) * q1

# Calculate the second orthogonal vector
v2 <- col_2 - projection_col_2_q1

# Calculate the Euclidean norm of the second orthogonal vector
norm_v2 <- sqrt(sum(v2^2))

# Normalize the second orthogonal vector to get the second column of Q
q2 <- v2 / norm_v2

Comme on le voit ci‑dessus, construire le deuxième vecteur orthogonal (et donc la deuxième colonne de Q) implique projection, soustraction, puis normalisation. Les étapes sont proches de celles de la première colonne, mais un peu plus impliquées : extraire la deuxième colonne de A ; projeter sur le premier vecteur de Q ; soustraire la projection à la deuxième colonne de A ; normaliser ; former la deuxième colonne de Q.

On peut répéter cette étape pour q3 jusqu’à la dernière colonne. Dans notre cas, les vecteurs orthogonaux q1, q2 et q3 forment la base de la matrice orthogonale Q. Ces vecteurs sont essentiels car ils fournissent le nouveau système de coordonnées pour exprimer les données d’origine.

On voit que Gram–Schmidt est un processus itératif qui garantit que chaque nouveau vecteur est orthogonal aux précédents. Rappelons que l’orthogonalité signifie que le produit scalaire de deux vecteurs est nul, ce qui indique leur perpendicularité dans l’espace vectoriel. Vérifions l’orthogonalité de q1 et q2 avec leur produit scalaire :

# Calculate the dot product of q1 and q2
dot_product_q1_q2 <- sum(q1 * q2)

# Print the dot product to confirm orthogonality
print(dot_product_q1_q2)
[1] 2.43295e-16

Construction de la matrice R

Maintenant que nous avons la matrice Q, construisons la matrice R. Dans la décomposition QR, R encode les relations entre les colonnes de la matrice orthogonale Q et les données d’origine. C’est une matrice triangulaire supérieure ; chaque élément de sa partie supérieure s’obtient par le produit scalaire entre la colonne correspondante de Q et la colonne d’origine.

Pour construire R, on calcule donc les produits scalaires de chaque colonne de Q avec chaque colonne du jeu de données initial. On obtient une matrice dont le nombre de lignes correspond au nombre de colonnes de Q, et qui est triangulaire supérieure du fait du processus précédent.

matrix_A <- matrix_A %>% as.matrix()

# Calculate and display the R matrix by multiplying Q^T and the subset data
R_matrix <- t(Q_matrix) %*% matrix_A

La sortie de R diffère ici un peu de la précédente. C’est parce que qr() utilise les réflexions de Householder, plus stables numériquement, contrairement à notre version inspirée de Gram–Schmidt.

         column_1      column_2  column_3
[1,] -1.185003e+02 -1.611602e+01 -711.9200
[2,]  5.814446e-16 -1.005857e+01 -496.9319
[3,]  7.633287e-15  1.338669e-15  283.7369

Nous pouvons vérifier la reconstruction en multipliant Q et R pour retrouver matrix_A. Ici, %*% correspond à la multiplication matricielle en R.  

Q_matrix %*% R_matrix
   column_1 column_2 column_3
 [1,]     21.0    2.620      110
 [2,]     21.0    2.875      110
 [3,]     22.8    2.320       93
 [4,]     21.4    3.215      110
 [5,]     18.7    3.440      175
 [6,]     18.1    3.460      105
 [7,]     14.3    3.570      245
 [8,]     24.4    3.190       62
 [9,]     22.8    3.150       95
[10,]     19.2    3.440      123
[11,]     17.8    3.440      123
[12,]     16.4    4.070      180
[13,]     17.3    3.730      180
[14,]     15.2    3.780      180
[15,]     10.4    5.250      205
[16,]     10.4    5.424      215
[17,]     14.7    5.345      230
[18,]     32.4    2.200       66
[19,]     30.4    1.615       52
[20,]     33.9    1.835       65
[21,]     21.5    2.465       97
[22,]     15.5    3.520      150
[23,]     15.2    3.435      150
[24,]     13.3    3.840      245
[25,]     19.2    3.845      175
[26,]     27.3    1.935       66
[27,]     26.0    2.140       91
[28,]     30.4    1.513      113
[29,]     15.8    3.170      264
[30,]     19.7    2.770      175
[31,]     15.0    3.570      335
[32,]     21.4    2.780      109

Apprendre R pour l'apprentissage automatique

Maîtriser les compétences de base en R pour devenir un scientifique de l'apprentissage automatique
Commencez À Apprendre Gratuitement

Décomposition QR en régression linéaire

La décomposition QR est utilisée par la fonction lm() à chaque exécution dans R. La raison : c’est une méthode numériquement stable et efficace pour résoudre des systèmes linéaires, en particulier avec de grands jeux de données ou lorsque les variables prédictives — c’est‑à‑dire les colonnes de la matrice de conception — sont presque colinéaires. 

On peut voir comment lm() exploite la décomposition QR en tapant simplement lm dans la console et en observant la signature où figurent method = "qr" et qr = TRUE.

lm
lm <- function (formula, data, subset, weights, na.action,
		method = "qr", model = TRUE, x = FALSE, y = FALSE,
		qr = TRUE, singular.ok = TRUE, contrasts = NULL,
		offset, ...)

Il existe d’autres méthodes pour estimer les coefficients d’une régression linéaire. On peut, par exemple, résoudre ce que l’on appelle l’équation normale. On peut aussi recourir au calcul différentiel en annulant les dérivées partielles de la somme des carrés des erreurs par rapport aux coefficients. Ou, dans le cas d’une régression linéaire simple (une variable indépendante et une dépendante), on peut obtenir la pente en multipliant la corrélation r par le quotient de l’écart‑type de y sur celui de x

Parmi toutes ces approches, la décomposition QR est souvent préférable car elle allie stabilité et efficacité. L’équation normale, en particulier ATA x = ATB, est coûteuse en calcul. Pour résoudre x, on écrit x = ((ATA)-1) ATB. La partie qui exige l’inversion de ATA a une complexité temporelle en O(n3) : si la taille de la matrice double, le temps d’inversion est multiplié par huit. C’est un mauvais choix pour les problèmes de grande dimension.

Pour conclure

La décomposition QR ne se limite pas à l’algèbre linéaire : c’est une méthode aux usages étendus en science des données et en apprentissage automatique. En la comprenant et en la mettant en pratique, vous renforcez votre capacité à traiter des problèmes complexes, comme la gestion de grands jeux de données et l’estimation en régression linéaire. 

Si la décomposition vous intéresse, sachez qu’il s’agit d’une idée plus générale en data science. Par exemple, la décomposition de séries temporelles scinde une série en tendance‑cycle, saisonnalité et résidu. Additionnés ou multipliés, ces composants reconstituent la série d’origine. Autre exemple : la transformée de Fourier, qui décompose une image en composantes fréquentielles, utile en traitement du signal

En explorant des sujets avancés en science des données, vous verrez que des concepts comme la décomposition QR sont étroitement liés à d’autres fondamentaux. Suivez nos cours : Linear Algebra for Data Science in R et Introduction to Statistics. Maîtriser ces disciplines interconnectées vous aidera à aborder des problèmes de data science encore plus variés et exigeants.

Obtenez une certification en science des données

Validez vos compétences professionnelles de data scientist.

Faire Progresser Ma Carrière Dans Les Données
Timeline mobile.png

Josef Waples's photo
Author
Josef Waples

Je suis rédacteur et éditeur dans le domaine de la science des données. Je suis particulièrement intéressé par l'algèbre linéaire, les statistiques, R, etc. Je joue également beaucoup aux échecs ! 

Sujets
Science des données
R

Learn with DataCamp

Cours

Algèbre linéaire pour la data science en R

4 h
21.6K
Ce cours constitue une introduction à l'algèbre linéaire, l'un des domaines mathématiques les plus importants qui sous-tendent la science des données.
Afficher les détailsRight Arrow
Commencer Le Cours
Voir plusRight Arrow