Les composantes de l'ACP représentent-elles vraiment un pourcentage de variance? Peuvent-ils totaliser plus de 100%?

13

Le "Machine Learning For Hackers" d'O'Reilly dit que chaque composant principal représente un pourcentage de la variance. J'ai cité la partie pertinente de la page ci-dessous (chapitre 8, p.207). S'adressant à un autre expert, ils ont convenu qu'il s'agissait du pourcentage.

Cependant, les 24 composants totalisent 133,2095%. Comment est-ce possible?

Après nous être convaincus que nous pouvons utiliser PCA, comment faisons-nous cela dans R? Encore une fois, c'est un endroit où R brille: l'intégralité de PCA peut être effectuée en une seule ligne de code. Nous utilisons la fonction princomp pour exécuter PCA:

pca <- princomp(date.stock.matrix[,2:ncol(date.stock.matrix)])

Si nous tapons simplement pca dans R, nous verrons un bref résumé des principaux composants:

Call:
princomp(x = date.stock.matrix[, 2:ncol(date.stock.matrix)])
Standard deviations:
Comp.1 Comp.2 Comp.3 Comp.4 Comp.5 Comp.6 Comp.7
29.1001249 20.4403404 12.6726924 11.4636450 8.4963820 8.1969345 5.5438308
Comp.8 Comp.9 Comp.10 Comp.11 Comp.12 Comp.13 Comp.14
5.1300931 4.7786752 4.2575099 3.3050931 2.6197715 2.4986181 2.1746125
Comp.15 Comp.16 Comp.17 Comp.18 Comp.19 Comp.20 Comp.21
1.9469475 1.8706240 1.6984043 1.6344116 1.2327471 1.1280913 0.9877634
Comp.22 Comp.23 Comp.24
0.8583681 0.7390626 0.4347983
24 variables and 2366 observations.

Dans ce résumé, les écarts-types nous indiquent dans quelle mesure la variance de l'ensemble de données est expliquée par les différentes composantes principales. La première composante, appelée Comp.1, représente 29% de la variance, tandis que la composante suivante représente 20%. À la fin, la dernière composante, Comp.24, représente moins de 1% de la variance. Cela suggère que nous pouvons en apprendre beaucoup sur nos données en examinant simplement le premier composant principal.

[Le code et les données peuvent être trouvés sur github .]

Darren Cook
la source
6
Je pense que l'interprétation de l'auteur de la Standard deviationsest légèrement décalée. Étant donné que les écarts-types sont en fait des écarts-types, nous devons les mettre au carré pour voir quelle proportion de la variance chaque composant représente. La première composante représenterait pour cent de la variance totale. 100×29.1001249229.10012492++0.43479832
supposé normal
4
Cette question découle de deux erreurs fondamentales, je le crains: (1) il manque le titre annonçant que les nombres sont des «écarts-types» et les confond avec les écarts et (2) il suppose que ces nombres sont des pourcentages, mais ils ne le sont pas. (Leurs unités sont quelles que soient les valeurs mesurées: en dollars ou en pourcentage de changement par an ou autre.) Il n'y a aucun bug ici: le commentaire de @Max explique comment trouver le pourcentage de la variance totale.
whuber
1
@whuber Peut-être aurais-je dû utiliser "typo" au lieu de "bug"? :-) " Comp.1, explique 29% de la variance " est faux et devrait se lire " Comp.1, explique 46% de la variance "
Darren Cook
1
Merci, Darren: J'ai mal compris que la confusion était présente dans le livre et j'ai pris "bug" pour me référer au Rlogiciel lui-même. Trouver cette erreur était une bonne prise (j'espère que vous avez trouvé gratifiant de découvrir ce qui se passe vraiment avec PCA)!
whuber
5
Oui, c'est incontestablement un bug dans le livre. Il y a quelques endroits où j'ai abusé des écarts-types au lieu des écarts. (Par exemple, il y a un moment où nous utilisons RMSE au lieu de MSE pour calculer le R au carré.) J'espère que nous aurons le temps de nous asseoir et de corriger ce genre de bogues dans un avenir proche.
John Myles White

Réponses:

11

Utilisez summary.princomppour voir la "Proportion de variance" et la "Proportion cumulée".

pca <- princomp(date.stock.matrix[,2:ncol(date.stock.matrix)])
summary(pca)
Joshua Ulrich
la source
1
Merci Joshua. Donc, la première composante est en fait 46% de la variance. J'enverrai un rapport de bogue au livre.
Darren Cook
Comment la «proportion de variance» est-elle calculée? Le nombre indiqué est 0,4600083. Mais sqrt(pca$sdev[1]/sum(pca$sdev))(grosso modo sqrt(29.1/133.2)) donne 0,4673904.
Darren Cook
3
@DarrenCook: sdevimplique que vous regardez l' écart-type , c'est-à-dire la racine carrée de la variance (ou , en utilisant la notation de ma réponse), ce qui devrait expliquer la différence. Essayezplutôt. λipca$sdev[1]^2/sum(pca$sdev^2)
MånsT
2
@DarrenCook: utilisez la source ... stats:::print.summary.princompvous montre qu'il équerre le sdevcomposant, ce qui stats:::princomp.defaultmontre sqrtla valeur propre.
Joshua Ulrich
11

Ils devraient totaliser 100 %.

La variance totale d'une variable aléatoire X à variables avec matrice de covariance Σ est définie comme t r ( Σ ) = σ 11 + σ 22 + + σ p p .pXΣ

tr(Σ)=σ11+σ22++σpp.

Or, la trace d'une matrice symétrique est la somme de ses valeurs propres Ainsi, la variance totale est t r ( Σ ) = λ 1 + + λ p si nous utilisons λ i pour désigner les valeurs propres de Σ . Notez que λ p0 puisque les matrices de covariance sont semi-définies positives , de sorte que la variance totale n'est pas négative.λ1λ2λp.

tr(Σ)=λ1++λp
λiΣλp0

Mais les principales composantes sont données par , où e i est le i : e vecteur propre (normalisé pour avoir une longueur 1 ), correspondant à la valeur propre λ i . Sa variance est V a r ( e i X ) = e i Σ e i = λ i e i e i = λ i et donc les k premières composantes principales constituent ( λeiXeii1λi

Var(eiX)=eiΣei=λieiei=λi
k de la variance totale. En particulier, ils représentent100%de la variance totale lorsquek=p.
(λ1++λkλ1++λp100) %
100 %k=p
MånsT
la source
1
Avez-vous vu le commentaire (plus récent) de @Max sur la question? Il a cloué la réponse.
whuber
@whuber: Je ne l'avais pas vu, alors merci. J'ai fait une remarque similaire dans un commentaire à la réponse de Joshua.
MånsT
4

Voici du code R pour compléter les réponses précédentes ( pca[["sdev"]]est généralement écrit pca$sdev, mais il provoque un mauvais formatage dans l'extrait ci-dessous).

# Generate a dummy dataset.
set.seed(123)
x <- matrix(rnorm(400, sd=3), ncol=4)
# Note that princomp performs an unscaled PCA.
pca1 <- princomp(x)
# Show the fraction variance of each PC.
pca1[["sdev"]]^2
cumsum(pca1[["sdev"]]^2)/sum(pca1[["sdev"]]^2)
# Perform a scaled PCA.
pca2 <- princomp(x, cor=TRUE)
pca2[["sdev"]]^2
cumsum(pca2[["sdev"]]^2)/sum(pca2[["sdev"]]^2)

Ainsi, comme le souligne @Max, travailler avec la variance au lieu de l'écart-type et ne pas oublier de diviser par la variance totale résout le problème.

gui11aume
la source