maxO3 T9 T12 T15 Ne9 Ne12 Ne15 Vx9 Vx12 Vx15 maxO3v vent pluie
1 13 9 16 19 6 11 13 6 14 14 5 11 8
ENSAI - CREST
https://marieetienne.github.io/MAF/
2026-11-04
Constat empirique
Les tableaux analysés par ACP sont souvent incomplets :
Exemples concrets
Environnement : stations × variables physico-chimiques → capteurs défaillants, données non synchrones.
Écologie : espèces × traits fonctionnels → traits manquants pour certaines espèces.
Socio-économie : individus × indicateurs → non-réponse partielle aux questionnaires.
Objectif de l’ACP
Résumer la structure de dépendance globale entre variables
→ difficile si le tableau est incomplet.
112 mesures journalières de variables météorologiques (vitesse du vent, température, précipitations, etc.) ainsi que la concentration d’ozone, relevées à Rennes (France) durant l’été 2001.
11 variables continues et 2 variables catégorielles comportant 2 ou 4 modalités.
Cet exemple est issu du package R missMDA
Approche naïve - Conserver uniquement les lignes sans valeurs manquantes.
Conséquences - Forte réduction de la taille de l’échantillon. - Perte d’information multivariée. - Biais potentiel si les manquants ne sont pas MCAR.
Une ACP « propre » sur peu de données peut être moins informative qu’une ACP bien traitée sur des données incomplètes.
n
1 112
n
1 30
0 1 2 3 4 5
30 38 30 10 3 1
C’est bien dommage !!!
vision schématique
\[\mathbf{X} = \begin{pmatrix} x_{11} & x_{12} & \bullet & x_{14} \\ x_{21} & \bullet & x_{23} & x_{24} \\ x_{31} & x_{32} & x_{33} & \bullet \end{pmatrix}\] \(\bullet\) : valeur manquante
On peut calculer une matrice de corrélation à partir des couples de données disponibles.
Problème
Conséquence
Question statistique
Deux grandes familles de réponses
Compléter les données (imputation)
Modéliser directement la structure latente (ACP comme modèle factoriel)
👉 Les deux approches sont étroitement liées.
Données et notations
\(\mathbf{X} \in \mathbb{R}^{n \times p}\) : matrice de données (souvent centrée, éventuellement réduite).
\(\mathbf{R} \in {0,1}^{n \times p}\) : indicateurs de données manquantes : \[r_{ij} = \begin{cases} 1 & \text{si } x_{ij} \text{ est observé} \\ 0 & \text{si } x_{ij} \text{ est manquant} \end{cases}\]
Décomposition : \(\mathbf{X} = (\mathbf{X}*{obs},* \mathbf{X}{mis})\).
ACP complète \[\hat{\Sigma} = \frac{1}{n}\mathbf{X}^\top \mathbf{X}\]
Mécanismes des données manquantes
Impact sur l’ACP - \(\hat{\Sigma}\) n’est plus directement calculable ; estimations ad hoc \(\Rightarrow\) biais possibles. - Distorsion des inerties et des sous-espaces principaux.
Principe
Quel remplacement ponctuel ?
Moyenne (si centrée : \(0\)) : \(\tilde{x}_{ij} = \bar{x}_j\)
Régression : On ajuste un modèle sur les données disponibles
\[x_{ij} = \beta_{0}^j +* \sum_{k\neq j}\beta_{k}^j x_{ik} + \varepsilon_{i}^j\] et on prédit
\[\hat{x}^{miss}_{ij} = \beta_{0}^j +* \sum_{k\neq j}\beta_{k}^j x_{ik}\]
Problèmes - Incertitude sur \(\mathbf{X}_{mis}\) ignorée \(\Rightarrow\) variances souvent sous-estimées, corrélations modifiées.
Principe - Générer (M) complétions : \[\tilde{\mathbf{X}}^{(1)}, \ldots, \tilde{\mathbf{X}}^{(M)}\] en simulant \(\mathbf{X}*{mis}\) selon une loi approchant \(p(\mathbf{X}{mis}\mid \mathbf{X}_{obs})\) (souvent sous MAR + modèle).
Analyse - ACP sur chaque \(\tilde{\mathbf{X}}^{(m)}\) \(\Rightarrow\) (M) jeux (valeurs propres, charges, scores).
Combinaison (une option simple)
\[\bar{\Sigma}=\frac{1}{M}\sum_{m=1}^M \hat{\Sigma}^{(m)} \] puis ACP de \(\bar{\Sigma}.\)
1) Diagnostiquer les manquants - Taux global + par variable/individu ; structure (blocs, monotone, etc.). - Tester/argumenter (au moins qualitativement) MCAR vs MAR vs MNAR.
2) Pré-traitement cohérent - Décider centrage / réduction (important en ACP sur corrélation). - Idéalement : inclure ce pré-traitement dans le modèle d’imputation (ou le reproduire à l’identique après imputation).
3) Choisir la stratégie - Exploration rapide : imputation simple (moyenne / kNN / ACP itérative). - Inférence / reporting : imputation multiple (MI), surtout sous MAR.
4) Estimer l’ACP - Sur () (simple) ou sur chaque (^{(m)}) (IM). - Attention à l’alignement des axes si besoin (indétermination du signe / rotations).
5) Diagnostics & sensibilité - Stabilité des charges/axes (bootstrap ou IM). - Sensibilité au nombre de composantes (q), au modèle d’imputation, et (si plausible) scénarios MNAR.
Modèle - Pour l’individu (i) : \[\mathbf{x}_i = \boldsymbol{\mu} + \mathbf{L}\mathbf{z}_i + \boldsymbol{\varepsilon}_i\] où - \(\mathbf{z}_i \in \mathbb{R}^q\) : facteurs latents (scores), - \(\mathbf{L} \in \mathbb{R}^{p\times q}\) : charges (loadings), - \(\boldsymbol{\varepsilon}_i \sim \mathcal{N}(\mathbf{0}, \sigma^2\mathbf{I}_p)\) (hypothèse “bruit isotrope”).
Lien avec l’ACP - Si \(\mathbf{z}_i \sim \mathcal{N}(0,\mathbf{I}_q)\), alors : \[\mathrm{Cov}(\mathbf{x}_i)=\mathbf{L}\mathbf{L}\top+\sigma2\mathbf{I}_p\] - L’estimation des paramètres (par maximum de vraisemblance ou EM, cf cours statistique inférentielle) mène à un sous-espace proche de celui de l’ACP (cas \(\sigma^2 I\) : “probabilistic PCA”).
Pourquoi utile avec des manquants ? - Le cadre probabiliste donne naturellement \(p(\mathbf{X}^{mis}\mid \mathbf{X}{obs})\). - EM : E-step (espérances conditionnelles des facteurs et/ou manquants), M-step (mise à jour de \(\mathbf{L},\sigma^2)\).
library(missMDA)
library(FactoMineR)
library(palmerpenguins)
library(mice)
data(penguins)
# Exemple : jeu de données continu avec manquants
X <- scale(penguins[, 3:6])
dim(X)
X_no_na <- X |> as.data.frame() |> drop_na()
dim(X_no_na)
# ici juste pour l'exemple set.seed(1)
prop_na <- 0.15
Xmiss <- X
Xmiss[sample(x= length(Xmiss), size = round(0.15*length(Xmiss)))] <- NA
X_no_na <- Xmiss |> as.data.frame() |> drop_na()
dim(X_no_na)
# --- (A) Imputation ACP itérative (missMDA) ---
# Choisir nb de composantes pour l'imputation (validation croisée)
ncp <- estim_ncpPCA(Xmiss, ncp.max = 5)$ncp ## on teste la reconstruction par validation croisée
Xmiss_pca <- imputePCA(Xmiss, ncp = ncp)$completeObs
res_pca <- PCA(Xmiss_pca, graph = FALSE)
# --- (B) Imputation multiple (mice) ---
X_miss_df <- as.data.frame(Xmiss)
# Méthode par défaut (pmm) souvent robuste ; adapter selon contexte
Xmiss_im <- mice(X_miss_df,
m = 20,
method = "pmm", seed = 1, printFlag = FALSE) # methode pmm regression multiple aà expliquer
# ACP sur chaque jeu imputé
pcas <- lapply(1:Xmiss_im$m,
function(m){
dta_m <- complete(Xmiss_im, m)
PCA(dta_m, graph = FALSE) })
# Combinaison simple : moyenne des matrices de covariance
Sigmas <- lapply(1:Xmiss_im$m,
function(m){
dta_m <- as.matrix(complete(Xmiss_im, m))
cov(dta_m) # si déjà centré/réduit : attention aux conventions
})
Sigma_bar <- Reduce("+", Sigmas) / Xmiss_im$m
# ACP sur Sigma_bar : via eigen-decomposition
# Base de référence : plan (PC1, PC2) de Sigma_bar
eig_bar <- eigen(Sigma_bar)
U <- eig_bar$vectors[, 1:2, drop = FALSE] # p x 2 (orthonormé)
# Fonction : angles principaux (en degrés) entre deux plans 2D
principal_angles_2d <- function(U, V) {
# cosinus des angles = valeurs singulières de t(U) %*% V
sv <- svd(t(U) %*% V, nu = 0, nv = 0)$d
sv <- pmin(1, pmax(0, sv)) # sécurité numérique
acos(sv) * 180 / pi # angles en degrés
}
# Angles entre le plan de Sigma_bar et le plan de chaque imputation
angles_deg <- sapply(seq_along(Sigmas), function(m) {
eig_m <- eigen(Sigmas[[m]])
V <- eig_m$vectors[, 1:2, drop = FALSE]
principal_angles_2d(U, V) # renvoie 2 angles : theta1 <= theta2
})
rownames(angles_deg) <- c("theta1_deg", "theta2_deg")
colnames(angles_deg) <- paste0("imp", seq_along(Sigmas))
# Résumé utile
t(apply(angles_deg, 1, summary))
# ou visualiser rapidement
angles_deg[, 1:5]