ACP et données centrées réduites

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Frederic Rollot
Messages : 10
Enregistré le : 15 Juil 2011, 15:02

ACP et données centrées réduites

Messagepar Frederic Rollot » 01 Aoû 2011, 17:05

Mise à jour du mardi 9 aout à 21h43. Mon probleme a évolué, vous pouvez surement m'aider ! une version à jour de ma demande est visible sur le message numéro 6 de ce fil. Merci de votre aide.

Bonjour à tous,

Je tiens tout d'abord à vous remercier pour ce lieu d'échanges très bien entretenu sur le logiciel R.

Je réalise une étude sous R visant à montrer le lien entre la consommation de différentes substances (pour faire simple) suivant l'age des individus.

Je me place dans le cas suivant :
-Mes individus sont des ages
-Mes variables sont la consommation MOYENNE des différentes substances pour chaque age. Je prends donc la somme de la consommation pour chaque age divisée par le nombre d'individus exposés au risque.

Exemple

Age MoySub1 .... Effectifs
1 10,2 101
2 11,4 125
3 11,5 114
4 11,2 120
...

J'ai cependant des effectifs très différents suivant les ages (très peu à gauche et à droite et beaucoup de personnes aux alentours de 40 ans).

Ma question : faut il pondérer les données en fonction des effectifs de chaque age lors de l'acp ? Sachant que je travaille déjà sur des moyennes, je ne sais pas si cela est pertinent.

Dans le cas où je doive en tenir compte, je n'ai pas trouvé d'exemple type sous R, par exemple pour le calcul de la matrice des correlations ou l'ACP en elle meme avec dudi.pca...

Je vous remercie d'avance pour l'aide apportée.

Frederic Rollot

denis laloe
Messages : 119
Enregistré le : 28 Déc 2006, 13:05

Messagepar denis laloe » 02 Aoû 2011, 08:18

Bonjour
avec dudi.pca (du paquet ade4), vous pouvez pondérer les lignes en fonction de l'effectif, avec le paramètre row.w (row.w = Effectifs)
Vous pouvez également faire d'abord une ACP sur tous vos individus (dans ce cas vos variables sont les consommations individuelles) -> dudi.pca
puis une analyse entre classes avec la fonction "bca", où les classes sont constituées des âges des individus. "bca" pondère automatiquement les moyennes en fonction des effectifs, et vous donne une mesure de l'importance de l'âge dans la variabilité de vos mesures, avec des mesures du ratio "inertie entre âges"/ inertie totale, etc.
voir la doc de ade4 "within pca and between pca" pour plus de détails

Frederic Rollot
Messages : 10
Enregistré le : 15 Juil 2011, 15:02

Messagepar Frederic Rollot » 07 Aoû 2011, 10:52

Bonjour Denis et merci de votre réponse.

Le problème est que je travaille sur plus d'1 million de lignes, extraites avec SAS, et j'ai bien peur que ce traitement individuel soit compliqué avec R.
Ma méthode a été d'agréger au préalable les lignes par age afin de réduire nettement la quantité de données à traiter pour R.

La question actuelle est donc de savoir si, malgré le fait que je travaille sur des moyennes, je doive encore pondérer dans l'acp en fonction du nombre de personnes dans chaque classe. J'avoue ne pas savoir quoi faire.

Merci !

Frederic Rollot
Messages : 10
Enregistré le : 15 Juil 2011, 15:02

Messagepar Frederic Rollot » 07 Aoû 2011, 20:09

Rebonjour à tous,

Après réflexion, j'ai décidé de pondérer les observations.
Mon problème change donc - je possède désormais une matrice contenant en colonne 1 les effectifs de chaque classe et dans les colonnes 2 à 8 les mesures de 7 variables.

Effectifs Var1 Var2
13 17 3
24 14 2
......

Est ce que quelqu'un aurait la gentillesse de confirmer que les fonctions que j'utilise sont employées à bon escient ? J'ai cherché dans l'aide et sur internet, je souhaite à présent avoir confirmation que mon travail est juste.

On charge les données :
donnees<-read.table("C:\\ACP.csv",header=TRUE,sep=";")

tb4 contient les valeurs des variables :
tb4=donnees[,2:8]

POIDS contient les effectifs de chaque classe
poids=donnees[,1:1]

On calcule la matrice de variance covariance des données en tenant compte des poids (V=X’DX-gg’) avec g le centre de gravité.
cov.wt(tb4, wt = poids, method="ML") => Par défaut le centrage est déja réalisé donc on n'indique pas nécessairement Center=true. Par contre par défaut on réduit donc on indique à R de prendre la méthode ML pour ne pas diviser par l'écart type. C'est cela ?

On cherche à présent la matrice de corrélation qui correspond normalement à la matrice de variance covariance des données centrées réduites :
cov.wt(tb4, wt = poids,cor = TRUE)
=>A ce moment là, ce que je ne comprends pas, c'est que la matrice de variance covariance est différente de la matrice de correlation, alors qu'on est censé travailler sur des données centrées réduites ?

On cherche ensuite à faire une ACP sur données centrées réduites
=>Comment centrer réduire en tenant compte des poids ? J'utiliserais normalement scale auparavant, mais comment tenir compte des poids ?
On lance l'acp avec dudi.pca en tenant compte des poids :
dudi.pca(tb4f, row.w = poids)

Merci de vos éclairages !

denis laloe
Messages : 119
Enregistré le : 28 Déc 2006, 13:05

Messagepar denis laloe » 08 Aoû 2011, 08:17

Bonjour,
concernant le centrage/réduction d'une matrice en présence de poids,
la fonction scalewt d'ade4 le fait.

Sinon, il faut que vous constituiez un tableau de moyennes tabmoy pondérées par classe, et un vecteur de poids (= effectif de la classe / effectif total)

Le code source de la fonction bca dans ade4 (récupérable en tapant bca.dudi après avoir chargé ade4) vous fournit une manière de faire


Ensuite, vous faites passer dudi.pca
x<-dudi.pca(tabmoy,row.w=poisd)
La fonction effectue le centrage et réduction des données par défaut (les paramètres par défaut sont scale=T,center=T)

Frederic Rollot
Messages : 10
Enregistré le : 15 Juil 2011, 15:02

Messagepar Frederic Rollot » 09 Aoû 2011, 19:43

Bonjour et merci pour cette réponse.

J'ai donc retravaillé mes données sur votre conseil. Voici la matrice que j'importe sur R :

AGE POIDS v1 v2 v3 v4 v5 v6 v7
0 0.00219164507009893 139.892486066982 107.800781811553 83.2043403302253 163.207649877598 0.015729465076306 0.270075524766914 37.1916938382207
1 0.0173045873076176 78.1525192984544 115.857114386087 63.1531279716324 157.450913115788 9.39040641430786 24.1181409872658 15.9134770436452
...
On réalise l'import de la manière suivante :
donnees<-read.table("C:\\ACP.csv",header=TRUE,sep=";")
On sépare la matrice contenant les valeurs des variables du poids
tb4=donnees[,3:9]
poids=donnees[,2:2]

A ce moment là, tb4 contient les données NON centrées et NON réduites.

On cherche à présent la matrice de variance covariance en tenant compte des poids sur les données non centrées et non réduites
On utilise la fonction cov.wt

cov.wt(tb4, wt = poids, cor = TRUE, center = FALSE, method = c("ML"))

J'obtiens cela :

$cov
v1 v2 v3 v4 v5 v6 v7
v1 3549.883 3368.899 3549.525 4002.251 5333.255 6423.897 1162.7572
v2 3368.899 3831.673 3706.116 3951.556 5412.253 6576.100 1259.0951
v3 3549.525 3706.116 3871.077 4028.697 5914.789 7056.121 1328.2872
v4 4002.251 3951.556 4028.697 4747.734 6029.531 7137.475 1245.9447
v5 5333.255 5412.253 5914.789 6029.531 11259.882 11222.380 1872.0820
v6 6423.897 6576.100 7056.121 7137.475 11222.380 14140.341 2379.8745
v7 1162.757 1259.095 1328.287 1245.945 1872.082 2379.874 616.4975

$center
[1] 0

$n.obs
[1] 80

$wt
[1] 0.0021916451 0.0173045873 0.0196710064 0.0191484333 0.0193617751 0.0187069259 0.0180839094 0.0178525393 0.0180694118 0.0171497332 0.0170479240 0.0167372413 0.0162735880
[14] 0.0159204808 0.0156896081 0.0155054082 0.0144728760 0.0140761170 0.0133207632 0.0122511350 0.0105632521 0.0089934535 0.0084907880 0.0081803703 0.0095023566 0.0112243512
[27] 0.0130485016 0.0143378765 0.0164140098 0.0182673877 0.0188111405 0.0189329959 0.0183600278 0.0190222889 0.0191143705 0.0187674684 0.0202371987 0.0209865879 0.0215920328
[40] 0.0214298117 0.0211446261 0.0200654456 0.0192538995 0.0192692247 0.0192451381 0.0194778169 0.0189749639 0.0184780265 0.0171281010 0.0166063065 0.0160911819 0.0153433216
[53] 0.0147167418 0.0138852146 0.0132397709 0.0123850663 0.0119401628 0.0111610405 0.0105077936 0.0093575603 0.0079230791 0.0064068025 0.0053096346 0.0043342365 0.0037333129
[66] 0.0028615993 0.0020212537 0.0017473491 0.0016628587 0.0012631358 0.0011051628 0.0011325475 0.0010951335 0.0010602228 0.0009216152 0.0008545537 0.0008393508 0.0008383071
[79] 0.0007493485 0.0007577143

$cor
v1 v2 v3 v4 v5 v6 v7
v1 1.0000000 0.9134541 0.9575189 0.9748866 0.8435647 0.9066957 0.7859888
v2 0.9134541 1.0000000 0.9622964 0.9264688 0.8239806 0.8933965 0.8192164
v3 0.9575189 0.9622964 1.0000000 0.9397353 0.8958936 0.9537185 0.8598257
v4 0.9748866 0.9264688 0.9397353 1.0000000 0.8246572 0.8711068 0.7282657
v5 0.8435647 0.8239806 0.8958936 0.8246572 1.0000000 0.8893815 0.7105461
v6 0.9066957 0.8933965 0.9537185 0.8711068 0.8893815 1.0000000 0.8060434
v7 0.7859888 0.8192164 0.8598257 0.7282657 0.7105461 0.8060434 1.0000000


1) Là où je pèche, c'est sur center et sur method.
L'aide me dit :

center either a logical or a numeric vector specifying the centers to be used when computing covariances. If TRUE, the (weighted) mean of each variable is used, if FALSE, zero is used. If center is numeric, its length must equal the number of columns of x.


Comme je comprends, on calcule la matrice de variance covariance sur données centrées si on indique TRUE et sur les données non centrées si on indique FALSE. Est-ce bien cela ? Dans mon cas, je ne veux pas calculer la matrice de variance covariance sur les données centrées donc je mets FALSE.

Idem, pour method :
method string specifying how the result is scaled, see ‘Details’ below.
By default, method = "unbiased", The covariance matrix is divided by one minus the sum of squares of the weights, so if the weights are the default (1/n) the conventional unbiased estimate of the covariance matrix with divisor (n - 1) is obtained. This differs from the behaviour in S-PLUS which corresponds to method = "ML" and does not divide.

Je ne veux pas travailler sur des données centrées réduites à cette étape, donc je mets FALSE.

A present, a titre de verification, on centre et on reduit les données avec SCALEWT.

On centre et on réduit la matrice pour calculer la matrice des corrélations.
i=scalewt(tb4,wt=poids)
2)Pourriez-vous me confirmer svp que la réduction est réalisée avec l'écart type (et pas la variance ?)

On demande le calcul de la matrice de variance covariance
cov.wt(i, wt = poids, cor = TRUE, center = FALSE, method = c("ML"))

$cov
v1 v2 v3 v4 v5 v6 v7
v1 1.0000000 0.58163327 0.8622519 0.8991349 0.38785959 0.5677345 0.30720788
v2 0.5816333 1.00000000 0.5171192 0.7157036 -0.04696801 0.1391073 0.30231069
v3 0.8622519 0.51711917 1.0000000 0.7618955 0.50929085 0.7001930 0.53993404
v4 0.8991349 0.71570362 0.7618955 1.0000000 0.32491999 0.4113968 0.12428375
v5 0.3878596 -0.04696801 0.5092909 0.3249200 1.00000000 0.5176850 0.08420861
v6 0.5677345 0.13910728 0.7001930 0.4113968 0.51768501 1.0000000 0.32096163
v7 0.3072079 0.30231069 0.5399340 0.1242838 0.08420861 0.3209616 1.00000000

$center
[1] 0

$n.obs
[1] 80

$wt
[1] 0.0021916451 0.0173045873 0.0196710064 0.0191484333 0.0193617751 0.0187069259 0.0180839094 0.0178525393 0.0180694118 0.0171497332 0.0170479240 0.0167372413 0.0162735880
[14] 0.0159204808 0.0156896081 0.0155054082 0.0144728760 0.0140761170 0.0133207632 0.0122511350 0.0105632521 0.0089934535 0.0084907880 0.0081803703 0.0095023566 0.0112243512
[27] 0.0130485016 0.0143378765 0.0164140098 0.0182673877 0.0188111405 0.0189329959 0.0183600278 0.0190222889 0.0191143705 0.0187674684 0.0202371987 0.0209865879 0.0215920328
[40] 0.0214298117 0.0211446261 0.0200654456 0.0192538995 0.0192692247 0.0192451381 0.0194778169 0.0189749639 0.0184780265 0.0171281010 0.0166063065 0.0160911819 0.0153433216
[53] 0.0147167418 0.0138852146 0.0132397709 0.0123850663 0.0119401628 0.0111610405 0.0105077936 0.0093575603 0.0079230791 0.0064068025 0.0053096346 0.0043342365 0.0037333129
[66] 0.0028615993 0.0020212537 0.0017473491 0.0016628587 0.0012631358 0.0011051628 0.0011325475 0.0010951335 0.0010602228 0.0009216152 0.0008545537 0.0008393508 0.0008383071
[79] 0.0007493485 0.0007577143

$cor
v1 v2 v3 v4 v5 v6 v7
v1 1.0000000 0.58163327 0.8622519 0.8991349 0.38785959 0.5677345 0.30720788
v2 0.5816333 1.00000000 0.5171192 0.7157036 -0.04696801 0.1391073 0.30231069
v3 0.8622519 0.51711917 1.0000000 0.7618955 0.50929085 0.7001930 0.53993404
v4 0.8991349 0.71570362 0.7618955 1.0000000 0.32491999 0.4113968 0.12428375
v5 0.3878596 -0.04696801 0.5092909 0.3249200 1.00000000 0.5176850 0.08420861
v6 0.5677345 0.13910728 0.7001930 0.4113968 0.51768501 1.0000000 0.32096163
v7 0.3072079 0.30231069 0.5399340 0.1242838 0.08420861 0.3209616 1.00000000


Point positif, la matrice de variance covariance des données centrées réduite est égale à la matrice des correlations.

3)Par contre, comment se fait il que la matrice de correlation ne soit pas la meme que la matrice de correlation sur données non centrées et non réduites ?

Enfin, je lance l'ACP en pondérant sur le tableau principal :
x<-dudi.pca(tb4,row.w=poids)
4)On utilise le talbeau initial pour l'acp et on pondere. Quand on centre et on réduit ici, le fait on par l'écart type ou la variance ?

Merci d'avance pour vos réponses !

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 16 Aoû 2011, 14:00

Bonjour,

1) si tu indiques TRUE a center alors il calcule les moyennes de tes colonnes et les centres sur ces moyennes, mais tu peux aussi lui donner un vecteur de valeurs numériques pour centrer les colonnes. SI tu lui indiques FALSE alors pas de centrage. Pour ce qui est des méthodes je prendrais celle par défaut, sinon il te faut voir dans l'aide de S+ comment est calculée la matrice de variance covariance pondérée.

2) une réduction est toujours faite avec l'écart type et non la variance, voir tout cours de stats.

Code : Tout sélectionner

set.seed(100)
x <- rnorm(100,5)
dim(x) <- c(20,5)
poids <- runif(20)
poids <- poids/sum(poids)

# moyenne pondérée
mn <-  colSums(x*poids)
# variance pondérée
vn <- colSums(poids*t(t(x)-mn)^2)
diag(cov.wt(x, poids, method="ML")$cov)

# centrée et reduire :
xcr <- t((t(x)-mn)/sqrt(vn))

# comparaison avec le tableau d'ade4
all.equal(as.matrix(dudi.pca(x, row.w=poids, scannf=F)$tab), xcr, check.attr=F)
[1] TRUE


3) la matrice de corrélation est la même sur des données centrées réduites que sur les données brutes :

Code : Tout sélectionner

all.equal(cor(x), cor(xcr))
[1] TRUE


4) l'écart type, toujours.

Maxime

Frederic Rollot
Messages : 10
Enregistré le : 15 Juil 2011, 15:02

Messagepar Frederic Rollot » 17 Aoû 2011, 07:07

Merci beaucoup !

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 17 Aoû 2011, 08:26

re,

en fait je n'ai pas pris la méthode par défault mais celle avec "ML", qui correspond ni plus ni moins à l'estimation de la variance avec cette formule :
Image avec wi les poids et Image qui est de 1 avec des poids normalisés.

maxime

Frederic Rollot
Messages : 10
Enregistré le : 15 Juil 2011, 15:02

Messagepar Frederic Rollot » 17 Aoû 2011, 11:17

Merci de la précision !


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité