Décrypter le transcriptome : L’art de la réduction de dimension

Analyse en composantes principales des profils d’expression génique

Auteur·rice
Affiliation

Antoine Géré

Date de publication

28 février 2026


Exercice 1 - Décrypter le transcriptome

Les packages qui seront utiles pour cet exercice.

library(dplyr)
library(car)
library(readxl)
library(factoextra)
library(FactoMineR)
library(remotes)
library(factoextra)
library(corrplot)

Le jeu de données utilisé dans cet examen est inspiré d’une étude publiée dans la revue Cell, Petropoulos et al. (2016), où des chercheurs ont mesuré l’activité de nombreux gènes dans des cellules provenant d’embryons humains très précoces. Leur objectif était d’observer comment les cellules évoluent au cours du développement et comment elles se différencient en plusieurs types cellulaires.

Pour notre exercice, nous utilisons une version simplifiée de ce type de données. Le fichier contient :

  • 300 gènes (chaque ligne correspond à un gène différent)

  • 12 échantillons (chaque colonne correspond à une condition biologique), représentant différents jours de développement et différents types de cellules :

    • Exemples : Day_5_EPI, Day_5_TE, Day_6_PE, etc.
  • Les variables du fichier sont donc :

    • Gene : nom du gène

    • 12 variables quantitatives (une par condition), correspondant à l’expression du gène dans chaque échantillon (mesure numérique)

L’objectif de l’Analyse en composantes principales est d’identifier les grands axes qui résument les principales différences d’expression entre ces 12 conditions, et de visualiser si certaines conditions se regroupent selon des profils similaires.

Le fichier de données est mmc3.xlsx.

data  = read_excel("data_raw/mmc3.xlsx")
head(data)
# A tibble: 6 × 13
  Gene    Day_3 Day_4 Pre_Day_5 Day_5_EPI Day_5_PE Day_5_TE Day_6_EPI Day_6__PE
  <chr>   <dbl> <dbl>     <dbl>     <dbl>    <dbl>    <dbl>     <dbl>     <dbl>
1 SEPT6     1.5   0         0.2       2.2      0.6      0.3       9.8       0.7
2 AARS2     2.3  13.8      17.3      44.1     19.5      8.5      21.8       7.5
3 ABCG2     0.2   0.3       7.6       3.3     10.4     35.1      23        54  
4 ABHD12B   5.8  11        16.7      33.3     17       12.3      57.4      18.3
5 ABHD6     0.8   4.2       9.7       7.5     29.2      8.1      11.8      14.8
6 ACE       0.3  17.5      10.3      15.4      6.7      3.9      11.1       1.3
# ℹ 4 more variables: Day_6_TE <dbl>, Day_7_EPI <dbl>, Day_7_PE <dbl>,
#   Day_7_TE <dbl>
var.quanti = sapply(data, is.numeric)
data.quanti = data[, var.quanti]
head(data.quanti)
# A tibble: 6 × 12
  Day_3 Day_4 Pre_Day_5 Day_5_EPI Day_5_PE Day_5_TE Day_6_EPI Day_6__PE Day_6_TE
  <dbl> <dbl>     <dbl>     <dbl>    <dbl>    <dbl>     <dbl>     <dbl>    <dbl>
1   1.5   0         0.2       2.2      0.6      0.3       9.8       0.7      0.4
2   2.3  13.8      17.3      44.1     19.5      8.5      21.8       7.5      4.8
3   0.2   0.3       7.6       3.3     10.4     35.1      23        54       71.3
4   5.8  11        16.7      33.3     17       12.3      57.4      18.3      9.8
5   0.8   4.2       9.7       7.5     29.2      8.1      11.8      14.8      8.8
6   0.3  17.5      10.3      15.4      6.7      3.9      11.1       1.3      0.8
# ℹ 3 more variables: Day_7_EPI <dbl>, Day_7_PE <dbl>, Day_7_TE <dbl>
1. Question théorique
  1. Combien de gènes et de conditions contient le jeu de données ?
  2. Quelles sont les variables quantitatives ?
  3. Pourquoi est-il important de distinguer les variables quantitatives et qualitatives avant l’analyse ?
  4. Expliquez en quelques phrases l’objectif de l’ACP. Pourquoi cette méthode est-elle utilisée ?

Le jeu de données est structuré sous forme de tableau où :

  • Chaque ligne correspond à un gène

  • Chaque colonne correspond à une variable

À partir de la description et de l’aperçu avec head(data), on observe :

  • 300 lignes, ce qui signifie que 300 gènes distincts sont analysés

  • 13 colonnes au total, parmi lesquelles :

    • 1 colonne qualitative : Gene (nom du gène)

    • 12 colonnes quantitatives correspondant aux conditions biologiques. Ces 12 conditions représentent :

      • Différents jours de développement embryonnaire (Day 3 à Day 7)
      • Différents types cellulaires :
        • EPI (Epiblaste)
        • PE (Primitive Endoderm)
        • TE (Trophectoderme)

Le jeu de données contient donc 300 gènes (individus statistiques) décrits par 12 conditions biologiques (variables quantitatives).


Les variables quantitatives sont celles qui sont de type numérique, qui représentent des mesures continues, et peuvent être comparées par des opérations mathématiques (moyenne, variance, corrélation). Dans ce jeu de données, il s’agit des 12 colonnes évoquées plus haut :

Day_3, Day_4, Pre_Day_5, Day_5_EPI, Day_5_PE, Day_5_TE, Day_6_EPI, Day_6_PE, Day_6_TE, Day_7_EPI, Day_7_PE et Day_7_TE.

Chaque valeur numérique correspond à un niveau d’expression génique mesuré pour un gène donné dans une condition biologique précise.


L’Analyse en Composantes Principales est une méthode algébrique. Elle repose sur :

  • Le calcul de variances

  • Le calcul de covariances ou de corrélations

  • La diagonalisation d’une matrice numérique

Ces concepts mathématiques n’ont de sens que pour des variables quantitatives. Conséquences si cette distinction n’est pas faite, inclure une variable qualitative dans une ACP entraînerait une impossibilité mathématique ! Cette sélection garantit la validité statistique de l’analyse.


L’Analyse en Composantes Principales vise à résumer l’information contenue dans un grand nombre de variables corrélées par un petit nombre de variables non corrélées, appelées composantes principales. Plus précisément, cette analyse permet de :

  • Réduire la dimension des données

  • Conserver un maximum de variance

  • Identifier les structures dominantes

  • Faciliter la visualisation et l’interprétation de corrlations entre variables

Cette analyse est particulièrement adaptée ici car il y a un grand nombre de variables, les 12 conditions biologiques fortement dépendantes biologiquement (mêmes processus de développement). On s’attend donc à de fortes corrélations, ce qui est une situation idéale pour l’ACP. L’étude ne cherche pas à tester une hypothèse précise, mais à :

  • Explorer les données

  • Détecter des tendances

  • Mettre en évidence des regroupements

L’ACP est une méthode exploratoire non supervisée, parfaitement adaptée à cet objectif. Dans ce contexte, l’ACP doit permettre de :

  • Identifier si les conditions se regroupent :
    • Par jour de développement
    • Par type cellulaire
  • Comprendre quels ensembles de conditions :
    • Partagent des profils d’expression similaires
    • S’opposent sur certains axes
Matrice.Correlation <- cor(data.quanti, use = "complete.obs")

corrplot(Matrice.Correlation, 
         method = "color", 
         type = "upper", 
         order = "hclust",
         tl.col = "black", 
         tl.srt = 45, 
         addCoef.col = "black",
         cl.pos = "n",
         cl.cex = 1.2,
         addCoefasPercent = TRUE,
         number.cex = 0.8)

data.quanti = data[, var.quanti]
2. Matrice de corrélation
  1. Quelles conditions semblent fortement corrélées ? Quelles conditions semblent peu corrélées ?
  2. Que peut-on déduire de ces corrélations pour l’analyse en composantes principales ?

Les conditions qui montrent des valeurs proches de 100 dans la matrice sont fortement corrélées.

Conditions fortement corrélées Interprétation
Day_6_EPI et Day_7_EPI Même type cellulaire (EPI) à des jours consécutifs
Day_5_TE et Day_6_TE Même type cellulaire (EPI) à des jours consécutifs
Day_5_PE et Day_6_PE Même type cellulaire (EPI) à des jours consécutifs
  • Ces cellules continuent leur programme de développement spécifique.

  • Les gènes exprimés dans un type cellulaire donné restent actifs à des niveaux comparables au cours des jours successifs.


Les conditions qui montrent des valeurs proches de 0 dans la matrice sont faiblement corrélées.

Conditions faiblement corrélées Interprétation
Day_3 et Day_7_TE Gènes exprimés très différemment ; changement de programme de développement
Day_3 et Day_5_PE Profils biologiques distincts.
EPI vs TE ou PE Très différents

Les variables fortement corrélées apportent la même information (exemple : Day_6_EPI et Day_7_EPI). Pour une ACP, cette redondance est utile. L’ACP combine les variables corrélées pour créer un axe principal. Cela permet de résumer l’information avec moins de composantes.

  • L’axe 1 de l’ACP capturera probablement la variation commune à ces jours consécutifs pour un type cellulaire.

  • Les variables faiblement corrélées ou négativement corrélées introduisent des axes supplémentaires.

Observation Implication pour l’ACP
Corrélation forte entre conditions similaires Ces variables seront résumées par le même axe principal
Corrélation faible entre types cellulaires ou jours éloignés Ces différences seront capturées par des axes secondaires
Bloc de corrélations Permet d’identifier des groupes biologiques cohérents avant l’ACP
data.CR <- scale(data.quanti,center = TRUE,scale=TRUE)
pca.data <- PCA(data.CR, graph = FALSE)
vp = pca.data$eig
vp
         eigenvalue percentage of variance cumulative percentage of variance
comp 1  7.585892122            63.21576768                          63.21577
comp 2  2.217238058            18.47698382                          81.69275
comp 3  0.873147907             7.27623255                          88.96898
comp 4  0.776224795             6.46853996                          95.43752
comp 5  0.293172253             2.44310211                          97.88063
comp 6  0.097438066             0.81198388                          98.69261
comp 7  0.072100242             0.60083535                          99.29345
comp 8  0.046325556             0.38604630                          99.67949
comp 9  0.016444017             0.13703347                          99.81653
comp 10 0.013633402             0.11361169                          99.93014
comp 11 0.005016309             0.04180257                          99.97194
comp 12 0.003367273             0.02806061                         100.00000
barplot(vp[, 2], 
        names.arg=1:nrow(vp), 
        main = "",
        xlab = "Composantes principales",
        ylab = "Pourcentage de variance expliquée",
        col ="steelblue")

lines(x = 1:nrow(vp), 
      vp[, 2], 
      type="b", 
      pch=19, 
      col = "black")

3. Variance expliquée
  1. Que représente la variance expliquée par chaque composante principale ?
  2. Combien de composantes principales retiendriez-vous pour représenter l’essentiel de l’information ? Justifiez votre réponse.
  3. Quelle proportion de variance est expliquée par les deux premières composantes ?

Dans une ACP, chaque composante principale est une combinaison linéaire des variables originales.

  • La première composante principale (Dim 1) est construite pour maximiser la variance totale des données projetées sur cette dimension.

  • La deuxième composante principale (Dim 2) maximise la variance restante sous contrainte d’orthogonalité à la première composante principale.

  • Et ainsi de suite pour les axes suivants.

La variance expliquée par une composante principale correspond à :

\[\text{Variance expliquée de Dim i} = \frac{\text{valeur propre (eigenvalue) de Dim i}}{\text{somme des valeurs propres}} \times 100\]

La valeur propre (eigenvalue) mesure la quantité de variance capturée par l’axe. Plus la valeur propre est grande, plus l’axe est informative.

Ici chaque axe représente un profil d’expression génétique combiné :

  • Dim 1 : direction qui distingue les conditions les plus différentes

  • Dim 2 : direction qui capture le deuxième contraste le plus important

La variance expliquée indique combien de l’information totale (différences d’expression entre conditions) est conservée sur cet axe. Exemple : si Dim 1 explique 63 %, cela signifie que 63 % de la variabilité totale entre conditions est résumée sur ce seul axe.

Composante Eigenvalue % Variance % Cumulée
Dim 1 7.586 63.2 % 63.2 %
Dim 2 2.217 18.5 % 81.7 %
Dim 3 0.873 7.3 % 88.97 %
Dim 4 0.776 6.47 % 95.44 %
Dim 5 0.293 2.44 % 97.88 %
  • Dim 1 (63 %) : capture la majeure partie de la variation, probablement liée aux différences temporelles globales et aux types cellulaires majeurs

  • Dim 2 (18.5 %) : capture les différences secondaires,

  • Axes suivants (<10 %) : capturent des variations mineures, bruit ou différences très spécifiques


Seules les composantes avec une valeur propre > 1 sont considérées comme significatives. Ici :

  • Dim 1 : 7.586 → OK
  • Dim 2 : 2.217 → OK
  • Dim 3 : 0.873 < 1 → moins informative

On peut utiliser le critère du coude (scree plot). Il suffit d’observer le point où la courbe se stabilise (diminution rapide → “coudé”). Ici le coude est évident après Dim 2, les axes suivants apportent peu de variance.

On peut également utiliser un critère de variance cumulée, c’est à dire retenir des axes qui expliquent 80 % ou plus de la variance. Ici les 2 premiers axes expliquent 63.2 + 18.5 ≈ 81.7 %. Cela est suffisant pour résumer l’information principale dans 2 axes.


La proportion de variance expliquée par les deux premières composantes principales est 63.2 + 18.5 = 81.7 %. Plus de 80 % de l’information totale est conservée dans un plan 2D. Cela justifie la visualisation des individus et des variables sur un plan factoriel. Les axes 1 et 2 suffisent pour mettre en évidence les structures principales des données (regroupements, oppositions, profils dominants)


Synthèse :

Question Réponse détaillée
Que représente la variance expliquée ? La proportion de la variation totale capturée par chaque axe. Plus elle est grande, plus l’axe est informatif.
Combien de composantes retenir ? 2 axes principaux. Justification : valeur propre >1, coude du scree plot, variance cumulée >80 %.
Variance cumulée Dim1+Dim2 81.7 % → suffisant pour une bonne représentation des données.
Utilité Résumer la majorité de l’information, visualiser les relations entre gènes et conditions, réduire le bruit.
fviz_pca_var(pca.data, 
             col.var = "cos2",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE,
             title = "Cercle de Corrélation des Variables (cos2)")

4. Cercle de corrélation
  1. Identifiez deux variables fortement corrélées et deux variables faiblement corrélées.
  2. Que signifie la longueur et l’orientation des flèches ?
  3. Quelles variables ont une contribution importante sur l’axe 2?

Le cercle de corrélation est un outil graphique qui permet de visualiser :

  • La relation entre variables quantitatives et les axes principaux

  • Les corrélations entre variables

  • La contribution de chaque variable à chaque axe


Deux variables sont fortement corrélées si leurs flèches sont proches et orientées suivant la même direction. L’angle entre elles est proche de 0°.

Exemples attendus dans ce jeu de données :

Variables fortement corrélées Justification
Day_6_EPI et Day_7_EPI Même type cellulaire, jours consécutifs → profils d’expression similaires
Day_5_TE et Day_6_TE Même type cellulaire TE → corrélation positive élevée

Deux variables sont faiblement corrélées si leurs flèches sont perpendiculaires (angle ≈ 90°).

Exemples attendus :

Variables faiblement corrélées Justification
Day_3 et Day_7_TE Jour très éloigné et type cellulaire différent → profils indépendants
Day_4 et Day_6_PE Flèches orthogonales → absence de corrélation linéaire

La longueur des flèches représente la qualité de représentation sur le plan factoriel.

  • Longue flèche → la variable est bien représentée, proche du plan choisi (Dim1 × Dim2)

  • Courte flèche → variable mal représentée, sa variance est surtout sur d’autres axes

Exemple pratique :

  • Day_6_EPI : longue flèche → forte contribution aux axes principaux

  • Day_7_PE : courte flèche → beaucoup de variance sur axes non représentés (Dim3, Dim4…)


L’orientation des flèches, vue par l’angle entre flèches traduit la corrélation entre variables :

  • Angle proche de 0° → corrélation positive forte

  • Angle proche de 180° → corrélation négative forte

  • Angle proche de 90° → variables indépendantes

Ici les flèches proches traduisent des types cellulaires avec profils similaires, et des flèches perpendiculaires traduisent des types cellulaires différents ou jours éloignés.


Sur le cercle de corrélation Day_3 et Day_4 ont des flèches longues et fortement orientées verticalement (Dim 2). Cela indique qu’elles contribuent de manière significative à l’axe 2.

head(pca.data$ind$coord)
       Dim.1       Dim.2       Dim.3         Dim.4       Dim.5
1 -0.8860388 -0.05653948 -0.05987579  0.0326202352  0.03833300
2 -0.6057873  0.10852636 -0.12243416 -0.0690008780 -0.10503767
3 -0.3699260 -0.31957924  0.03212768  0.1043982993  0.31567397
4 -0.5063049  0.11052344 -0.11409912 -0.1403434496  0.02666491
5 -0.6891486 -0.07722587 -0.02877404  0.0005839167 -0.07581851
6 -0.7792027  0.06145232 -0.06881027  0.0769645114 -0.05851516
fviz_pca_ind(pca.data,  col.ind="cos2") +
  scale_color_gradient2(low="blue", mid="white", high="red", midpoint=0.50) +
  theme_minimal()

# Filtrer les individus avec cos² > 50%
ind_cos2 <- apply(pca.data$ind$cos2, 1, max) > 0.5

# Filtrer les variables avec cos² > 50%
var_cos2 <- apply(pca.data$var$cos2, 1, max) > 0.5

# Créer un graphique combiné des individus et des variables
fviz_pca_biplot(pca.data,
                select.ind = list(cos2 = 0.5), # Sélectionner les individus avec cos² > 50%
                select.var = list(cos2 = 0.5), # Sélectionner les variables avec cos² > 50%
                repel = TRUE, # Éviter le chevauchement des étiquettes
                title = "Biplot des Individus et des Variables (cos² > 50%)",
                col.ind = "blue", # Couleur des individus
                col.var = "red", # Couleur des variables
                geom.ind = "point"  
)

5. Représentation des individus

Que révèle la position des individus sur le plan des deux premiers axes (proximité, similarité, groupes, outliers) ?

Nous analysons la position des individus (gènes) sur le plan des deux premières composantes principales de l’ACP (Dim1 et Dim2) afin de comprendre leur similarité, la formation de groupes et la présence d’outliers.

  • Deux gènes proches dans le plan ont des profils d’expression similaires sur les 12 conditions.

  • La distance euclidienne dans le plan factoriel reflète la similarité après réduction de dimension.

  • Gènes éloignés : expression spécifique ou extrême dans certaines conditions. Peuvent représenter des marqueurs spécifiques ou des variations expérimentales.

  • Le cos² mesure la qualité de représentation d’un gène sur le plan Dim1 × Dim2 :

    • cos² > 0.5 → bien représenté, interprétation fiable (on a uniquement représenté ces individus)

    • cos² faible → beaucoup de variance sur d’autres axes

En conclusion, la projection des gènes sur le plan factoriel permet de visualiser la structure globale des profils d’expression, d’identifier des groupes cohérents, et de mettre en évidence les gènes spécifiques ou outliers, tout en restant justifiée par la variance expliquée et le cos².

Ici beaucoup de points sont concentrés proche de l’origine, sachant que cos² > 0.5. La position est bien représentée sur ce plan. Autrement dit, la position à proximité de l’origine est fiable, pas un artefact dû au choix du plan. La plupart des individus (genes) ont donc une expression relativement constante à travers les conditions.

Les références

Petropoulos, S., Edsgärd, D., Reinius, B., Deng, Q., Panula, S. P., Codeluppi, S., Reyes, A. P., Linnarsson, S., Sandberg, R., et Lanner, F. (2016). Single-cell RNA-seq reveals lineage and X chromosome dynamics in human preimplantation embryos. Cell 165: 1012‑1026.