Comment inverser la PCA et reconstruire les variables originales à partir de plusieurs composantes principales?

113

L'analyse en composantes principales (ACP) peut être utilisée pour la réduction de la dimensionnalité. Une fois cette réduction de dimension effectuée, comment peut-on reconstruire approximativement les variables / entités d'origine à partir d'un petit nombre de composants principaux?

Sinon, comment peut-on supprimer ou écarter plusieurs composants principaux des données?

En d'autres termes, comment inverser la PCA?


Étant donné que la PCA est étroitement liée à la décomposition en valeurs singulières (SVD), la même question peut être posée comme suit: comment inverser la SVD?

amibe
la source
10
Je publie ce fil de questions-réponses car je suis fatigué de voir des dizaines de questions poser cette question et de ne pas pouvoir les fermer en double car nous n’avons pas de fil canonique sur ce sujet. Il y a plusieurs discussions similaires avec des réponses correctes mais toutes semblent avoir de sérieuses limitations, comme par exemple en se concentrant exclusivement sur R.
amoeba
4
J'apprécie l'effort. Je pense qu'il est absolument nécessaire de rassembler des informations sur PCA, ce qu'elle fait, ce qu'elle ne fait pas, dans un ou plusieurs fils de discussion de haute qualité. Je suis content que vous ayez pris l'initiative de le faire!
Sycorax
1
Je ne suis pas convaincu que cette réponse canonique "nettoyage" remplisse son rôle. Ce que nous avons ici est une excellente question générique et une réponse, mais chacune des questions comportait quelques subtilités sur la pratique de l’ACP qui sont perdues ici. Essentiellement, vous avez répondu à toutes les questions, traité PCA et éliminé les composants principaux inférieurs, où des détails riches et importants sont parfois masqués. De plus, vous êtes revenu à la notation des manuels d’algèbre linéaire, qui est précisément ce qui rend la PCA opaque pour beaucoup de gens, au lieu d’utiliser la lingua franca des statisticiens occasionnels, c’est-à-dire R.
Thomas Browne
1
@Thomas Merci. Je pense que nous avons un désaccord, heureux d'en discuter en chat ou en Meta. Très brièvement: (1) Il serait peut-être préférable de répondre à chaque question individuellement, mais la dure réalité est que cela ne se produit pas. Beaucoup de questions restent sans réponse, comme le vôtre l’aurait probablement fait. (2) La communauté ici préfère fortement les réponses génériques utiles pour beaucoup de gens; vous pouvez regarder quel type de réponses obtient le plus de votes. (3) Je suis d'accord sur les maths, mais c'est pourquoi j'ai donné le code R ici! (4) Pas d'accord sur la lingua franca; Personnellement, je ne connais pas R.
amibe
@ amoeba J'ai peur de ne pas savoir comment retrouver le chat car je n'ai jamais participé à des méta discussions auparavant.
Thomas Browne

Réponses:

147

PCA calcule les vecteurs propres de la matrice de covariance ("axes principaux") et les trie en fonction de leurs valeurs propres (quantité de variance expliquée). Les données centrées peuvent ensuite être projetées sur ces axes principaux pour produire des composantes principales ("scores"). Aux fins de la réduction de la dimensionnalité, il est possible de ne conserver qu'un sous-ensemble de composants principaux et d'éliminer le reste. (Voir ici pour l'introduction d' un profane à la PCA .)

Soit la matrice de données avec lignes (points de données) et colonnes (variables ou entités). Après avoir soustrait le vecteur moyen de chaque ligne, nous obtenons la centrée matrice de données . Soit la matrice de certains vecteurs propres que nous voulons utiliser; ce sont le plus souvent les vecteurs propres avec les plus grandes valeurs propres. Alors la matrice des projections PCA ("scores") sera simplement donnée par . n×pnpXrawn×pnpμXVp×kkkn×kZ=XV

Ceci est illustré sur la figure ci-dessous: la première sous-parcelle affiche des données centrées (les mêmes que celles que j'utilise dans mes animations dans le fil lié) et ses projections sur le premier axe principal. La deuxième sous-parcelle ne montre que les valeurs de cette projection; la dimensionnalité a été réduite de deux à un:

entrez la description de l'image ici

Afin de pouvoir reconstituer les deux variables d'origine à partir de cette composante principale, nous pouvons le relier à dimensions avec . En effet, les valeurs de chaque PC doivent être placées sur le même vecteur que celui utilisé pour la projection; compare les sous-parcelles 1 et 3. Le résultat est alors donné par . Je l'affiche sur la troisième intrigue secondaire ci-dessus. Pour obtenir la reconstruction finale , nous devons ajouter le vecteur moyen à celui-ci:pVX^=ZV=XVVX^rawμ

PCA reconstruction=PC scoresEigenvectors+Mean

Notez que l'on peut aller directement de la première sous-parcelle à la troisième en multipliant avec la matrice ; cela s'appelle une matrice de projection . Si tous les vecteurs propres sont utilisés, alors est la matrice identité (aucune réduction de dimensionnalité n’est effectuée, la "reconstruction" est donc parfaite). Si seul un sous-ensemble de vecteurs propres est utilisé, ce n'est pas une identité.XVVpVV

Cela fonctionne pour un point arbitraire dans l’espace PC; il peut être mappé sur l'espace d'origine via .zx^=zV

Jeter (enlever) les principaux ordinateurs

Parfois, on veut jeter (enlever) un ou plusieurs des principaux ordinateurs et garder le reste, au lieu de garder les principaux et laisser de côté (comme ci-dessus). Dans ce cas, toutes les formules restent exactement les mêmes , mais devrait contenir tous les axes principaux à l' exception de ceux que l'on souhaite ignorer. En d'autres termes, devrait toujours inclure tous les PC que l'on veut garder.VV

Mise en garde à propos de la PCA sur la corrélation

Lorsque l'ACP est effectuée sur la matrice de corrélation (et non sur la matrice de covariance), les données brutes sont non seulement centrées en soustrayant mais également mises à l'échelle en divisant chaque colonne par son écart type . Dans ce cas, pour reconstruire les données d'origine, il faut redimensionner les colonnes de avec et ensuite seulement rajouter le vecteur moyen .XrawμσiX^σiμ


Exemple de traitement d'image

Ce sujet est souvent abordé dans le contexte du traitement d'images. Considérez Lenna - l’une des images standard dans la littérature sur le traitement des images (suivez les liens pour trouver sa provenance). Ci-dessous, à gauche, la variante en niveaux de gris de cette image (fichier disponible ici ).512×512

Deux versions en niveaux de gris de l'image Lenna.  Celui de droite est granuleux mais clairement reconnaissable.

Nous pouvons traiter cette image en niveaux de gris comme une matrice de données . J'exécute la PCA et calcule utilisant les 50 premiers composants principaux. Le résultat est affiché à droite.512×512XrawX^raw


Revenir en SVD

La PCA est très étroitement liée à la décomposition en valeurs singulières (SVD), voir Relation entre la SVD et la PCA. Comment utiliser SVD pour effectuer une PCA? pour plus de détails. Si une matrice est SVD-ed sous la forme , on sélectionne un vecteur de dimension qui représente le point dans l' espace "réduit". de dimensions, puis pour le mapper à dimensions, il faut le multiplier par .n×pXX=USVkzUkpS1:k,1:kV:,1:k


Exemples dans R, Matlab, Python et Stata

Je vais effectuer une ACP sur les données de l’iris de Fisher , puis la reconstruire en utilisant les deux premières composantes principales. Je fais de la PCA sur la matrice de covariance, pas sur la matrice de corrélation, c’est-à-dire que je ne mets pas à l’échelle les variables ici. Mais je dois encore ajouter la moyenne en arrière. Certains paquets, comme Stata, s'en occupent grâce à la syntaxe standard. Merci à @StasK et @Kodiologist pour leur aide concernant le code.

Nous allons vérifier la reconstruction du premier point de donnée, qui est:

5.1        3.5         1.4        0.2

Matlab

load fisheriris
X = meas;
mu = mean(X);

[eigenvectors, scores] = pca(X);

nComp = 2;
Xhat = scores(:,1:nComp) * eigenvectors(:,1:nComp)';
Xhat = bsxfun(@plus, Xhat, mu);

Xhat(1,:)

Sortie:

5.083      3.5174      1.4032     0.21353

R

X = iris[,1:4]
mu = colMeans(X)

Xpca = prcomp(X)

nComp = 2
Xhat = Xpca$x[,1:nComp] %*% t(Xpca$rotation[,1:nComp])
Xhat = scale(Xhat, center = -mu, scale = FALSE)

Xhat[1,]

Sortie:

Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
   5.0830390    3.5174139    1.4032137    0.2135317

Voir aussi la réponse ci-dessous pour un exemple R reconstitué de reconstruction d'images en PCA .

Python

import numpy as np
import sklearn.datasets, sklearn.decomposition

X = sklearn.datasets.load_iris().data
mu = np.mean(X, axis=0)

pca = sklearn.decomposition.PCA()
pca.fit(X)

nComp = 2
Xhat = np.dot(pca.transform(X)[:,:nComp], pca.components_[:nComp,:])
Xhat += mu

print(Xhat[0,])

Sortie:

[ 5.08718247  3.51315614  1.4020428   0.21105556]

Notez que cela diffère légèrement des résultats dans d'autres langues. En effet, la version Python du jeu de données Iris contient des erreurs .

Stata

webuse iris, clear
pca sep* pet*, components(2) covariance
predict _seplen _sepwid _petlen _petwid, fit
list in 1

  iris   seplen   sepwid   petlen   petwid    _seplen    _sepwid    _petlen    _petwid  
setosa      5.1      3.5      1.4      0.2   5.083039   3.517414   1.403214   .2135317  
amibe
la source
1
Dans MATLAB, vous pouvez extraire mu des sorties PCA standard, mais également indiquer le nombre de composants dans les entrées.
Aksakal
2
@Aksakal, j'ai essayé de rendre les trois extraits de code aussi similaires (et aussi clairs) que possible; en particulier, je voulais calculer à la main avant d'appeler pca (), exécuter PCA avec tous les composants et n'utiliser que des composants lors de l'exécution d'un produit scalaire entre scores et vecteurs propres. J'ai maintenant modifié le code Python pour suivre le même schéma. μnComp
amibe
3
Je supprimerais tout élément de la réponse qui n’est pas lié à la réponse directe à la question, comme l’image et le traitement de cette jolie fille. Si quelqu'un ne s'intéresse pas aux images, la consommation est difficile. Rappelez-vous que quiconque pose la question est déjà profondément confus.
Aksakal
5
Lenna est un jeu de données aussi standard que l'iris.
StasK
2
@ amoeba Je parlais de taille, de résolution en bits et même de pixels noirs dans la bordure. Je n'ai pas de version définitive http://www.ece.rice.edu/~wakin/images/ : "Il semble y avoir de nombreuses versions de l'image de test de Lena (" Lenna ") disponibles. Ce problème a été noté par Shapiro dans son article de 1993 zerotree, et cela reste étonnamment vrai aujourd'hui "
Laurent Duval