Ricerca Sociale con R

Una wiki per l'analisi dei dati con R

Strumenti Utente

Strumenti Sito


r:analisi_esplorativa:analisi_in_componenti_principali

L'analisi in componenti principali

L'analisi in componenti principali (ACP) procede dal calcolo degli autovettori (i valori singolari) e degli autovalori di una matrice quadrata (ad esempio quella delle correlazioni).

Le componenti sono gli autovalori, vettori che hanno come origine la media delle variabili originarie, e rispetto ai quali è possibile assegnare un punteggio tanto ai casi, quanto alle variabili originarie. Solitamente, si utilizzano le prime due-tre componenti, e si salvano i valori degli scores dei casi (come nuove variabili di sintesi)

Una presentazione dettagliata della tecnica è disponibile su Wikipedia.

Per l'interpretazione semantica delle componenti (intese come variabili di sintesi), si terrà infine conto del rapporto fra variabili e componenti, si veda ACP: interpretazione dei risultati con Factoextra.

Vedi anche:

Testi in italiano, con esempi in campo sociologico sono (fra gli altri):

Slides del Laboratorio di ricerca sociale con R (maggio 2019)

Controllo dei dati

Per mostrare i comandi e gli output, utilizziamo il Datasets di esempio “USArrests”.

Di fondamentale importanza anche la preventiva analisi descrittiva delle variabili e delle relazione fra di loro, in quanto la tecnica presuppone l'andamento normale delle variabili e la relazione lineare fra di esse.

Per valutare la linearità delle relazioni fra le variabili contenute nel dataset, ad esempio con uno Scatterplot (grafico a dispersione).

> plot(USArrests)

Possiamo anche controllare la matrice delle correlazioni (eventualmente ricorrendo anche al mosaicplot).

> cor(USArrests)
             Murder   Assault   UrbanPop      Rape
Murder   1.00000000 0.8018733 0.06957262 0.5635788
Assault  0.80187331 1.0000000 0.25887170 0.6652412
UrbanPop 0.06957262 0.2588717 1.00000000 0.4113412
Rape     0.56357883 0.6652412 0.41134124 1.0000000

Ai fini della selezione delle variabili, è bene sottolineare che non avrebbe senso tentare una sintesi

  • se le variabili fossero tutte perfettamente correlate fra di loro (ne basterebbe una);
  • se le variabili non fossero affatto correlate (servirebbero tutte le componenti).

Se le variabili mostrano una buona correlazione, le prime componenti saranno sufficienti, e si otterrà una sintesi parsimoniosa e adeguata.

La funzione prcomp

La funzione prcomp() calcola i valori singolari della matrice normalizzata (e non gli autovalori della matrice delle correlazioni, come invece fa la funzione princomp).

prcomp(x, retx = TRUE, center = TRUE, scale. = FALSE,
       tol = NULL, ...)

Utilizziamo la funzione prcomp, con l'opzione scale=TRUE, ovvero normalizzando le variabili (varianza = 1).

> PCA <- prcomp(USArrests, scale = TRUE)

Per utilizzare solo alcune variabili e non altre, scriveremo:

> prcomp(USArrests[,c(1:2,4)], scale = TRUE) 

oppure:

> prcomp(~Murder + Assault + Rape, data = USArrests, 
          scale = TRUE)

Output

> PCA
Standard deviations (1, .., p=4):
[1] 1.5748783 0.9948694 0.5971291 0.4164494

Rotation (n x k) = (4 x 4):
                PC1        PC2        PC3         PC4
Murder   -0.5358995  0.4181809 -0.3412327  0.64922780
Assault  -0.5831836  0.1879856 -0.2681484 -0.74340748
UrbanPop -0.2781909 -0.8728062 -0.3780158  0.13387773
Rape     -0.5434321 -0.1673186  0.8177779  0.08902432

L'output prodotto richiamando l'oggetto PCA consiste nelle deviazioni standard delle componenti e nella matrice di rotazione (con i variable loadings)

> summary(PCA)
Importance of components:
                          PC1    PC2     PC3     PC4
Standard deviation     1.5749 0.9949 0.59713 0.41645
Proportion of Variance 0.6201 0.2474 0.08914 0.04336
Cumulative Proportion  0.6201 0.8675 0.95664 1.00000

Il comando summary(), in questo caso, restituisce una serie di valori che consentono di valutare la rilevanza relativa di ciascuna componente, ovvero: la deviazione standard di ciascuna componente; la proporzione di varianza spiegata, e le proporzioni cumulate.

> str(PCA)
List of 5
 $ sdev    : num [1:4] 1.575 0.995 0.597 0.416
 $ rotation: num [1:4, 1:4] -0.536 -0.583 -0.278 -0.543 0.418 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:4] "Murder" "Assault" "UrbanPop" "Rape"
  .. ..$ : chr [1:4] "PC1" "PC2" "PC3" "PC4"
 $ center  : Named num [1:4] 7.79 170.76 65.54 21.23
  ..- attr(*, "names")= chr [1:4] "Murder" "Assault" "UrbanPop" "Rape"
 $ scale   : Named num [1:4] 4.36 83.34 14.47 9.37
  ..- attr(*, "names")= chr [1:4] "Murder" "Assault" "UrbanPop" "Rape"
 $ x       : num [1:50, 1:4] -0.976 -1.931 -1.745 0.14 -2.499 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:50] "Alabama" "Alaska" "Arizona" "Arkansas" ...
  .. ..$ : chr [1:4] "PC1" "PC2" "PC3" "PC4"
 - attr(*, "class")= chr "prcomp"

L'oggetto (output) PCA creato dall'analisi in componenti principali contiene i seguenti valori:

  • sdev = deviazioni standard delle componenti principali
  • rotation = la matrice di rotazione con i variable loadings (consente di interpretare i fattori, in base al peso che hanno le variabili nel definirli)
  • x = le coordinate fattoriali dei casi (se retx=TRUE, come di default)
  • center = il valore corrispondente all'attuale origine dell'asse, per ciascuna variabile (se center=TRUE, come di default)
  • scale = come center, ma per la varianza di ciascuna variabile (se scale=TRUE)

Ogni elemento della lista può essere richiamato con $. Quindi, per ottenere le coordinate fattoriali:

> PCA$x
                       PC1         PC2         PC3          PC4
Alabama        -0.97566045  1.12200121 -0.43980366  0.154696581
Alaska         -1.93053788  1.06242692  2.01950027 -0.434175454
Arizona        -1.74544285 -0.73845954  0.05423025 -0.826264240
Arkansas        0.13999894  1.10854226  0.11342217 -0.180973554
....

La matrice delle correlazioni fra i nuovi valori e i vecchi si ottiene con il comando cor() applicato alle due matrici.

> cor(USArrests, PCA$x)
                PC1        PC2        PC3         PC4
Murder   -0.8439764  0.4160354 -0.2037600  0.27037052
Assault  -0.9184432  0.1870211 -0.1601192 -0.30959159
UrbanPop -0.4381168 -0.8683282 -0.2257242  0.05575330
Rape     -0.8558394 -0.1664602  0.4883190  0.03707412

Grafici

La funzione plot() restituisce il grafico a barre delle componenti:

plot(PCA)

Per avere il grafico a punti e linee, scriveremo:

screeplot(PCA, type="l")

La funzione biplot() fornisce invece una rappresentazione sintetica dei casi e delle variabili sul piano fattoriale, utilizzando la matrice PCA$x, che può eventualmente essere esportata per includere le coordinate fattoriali come variabili nella matrice originaria:

biplot(PCA)

Script

prcomp-ex.R
plot(USArrests)
PCA<-prcomp(USArrests, scale = TRUE)
print(PCA)
summary(PCA)
plot(PCA)
biplot(PCA)
PCA$x
cor(USArrests, PCA$x)

La funzione princomp

La funzione princomp, calcola l'ACP con la risoluzione matriciale, ovvero calcolando gli autovalori delle matrice delle correlazioni o delle covarianze (e non della matrice originaria).

princomp(x, cor = FALSE, scores = TRUE, covmat = NULL,
         subset = rep(TRUE, nrow(as.matrix(x))), ...)
> PCA1 <- princomp(USArrests, cor = TRUE)

Output

Le funzioni summary(), plot() screeplot() e biplot() restituiscono risultati analoghi a quelli visti sopra:

> summary(PCA1)
Importance of components:
                          Comp.1    Comp.2    Comp.3     Comp.4
Standard deviation     1.5748783 0.9948694 0.5971291 0.41644938
Proportion of Variance 0.6200604 0.2474413 0.0891408 0.04335752
Cumulative Proportion  0.6200604 0.8675017 0.9566425 1.00000000
> PCA1
Call:
princomp(x = USArrests, cor = TRUE)

Standard deviations:
   Comp.1    Comp.2    Comp.3    Comp.4 
1.5748783 0.9948694 0.5971291 0.4164494 

4  variables and  50 observations.

L'output prodotto richiamandoPCA1 non contiene invece la matrice delle componenti (variable loadings), che può essere però chiamata con il comando:

> loadings(PCA1)
Loadings:
         Comp.1 Comp.2 Comp.3 Comp.4
Murder   -0.536  0.418 -0.341  0.649
Assault  -0.583  0.188 -0.268 -0.743
UrbanPop -0.278 -0.873 -0.378  0.134
Rape     -0.543 -0.167  0.818       

               Comp.1 Comp.2 Comp.3 Comp.4
SS loadings      1.00   1.00   1.00   1.00
Proportion Var   0.25   0.25   0.25   0.25
Cumulative Var   0.25   0.50   0.75   1.00

oppure anche con

> PCA1$loadings

In questo caso, i pesi fattoriali (variable loadings) si riferiscono agli autovalori della matrice delle correlazioni.

L'oggetto (output) PCA1 è però diverso, in quanto diverso è il metodo di calcolo delle componenti.

> str(PCA1)
List of 7
 $ sdev    : Named num [1:4] 1.575 0.995 0.597 0.416
  ..- attr(*, "names")= chr [1:4] "Comp.1" "Comp.2" "Comp.3" "Comp.4"
 $ loadings: 'loadings' num [1:4, 1:4] 0.536 0.583 0.278 0.543 0.418 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:4] "Murder" "Assault" "UrbanPop" "Rape"
  .. ..$ : chr [1:4] "Comp.1" "Comp.2" "Comp.3" "Comp.4"
 $ center  : Named num [1:4] 7.79 170.76 65.54 21.23
  ..- attr(*, "names")= chr [1:4] "Murder" "Assault" "UrbanPop" "Rape"
 $ scale   : Named num [1:4] 4.31 82.5 14.33 9.27
  ..- attr(*, "names")= chr [1:4] "Murder" "Assault" "UrbanPop" "Rape"
 $ n.obs   : int 50
 $ scores  : num [1:50, 1:4] 0.986 1.95 1.763 -0.141 2.524 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:50] "Alabama" "Alaska" "Arizona" "Arkansas" ...
  .. ..$ : chr [1:4] "Comp.1" "Comp.2" "Comp.3" "Comp.4"
 $ call    : language princomp(x = USArrests, cor = TRUE)
 - attr(*, "class")= chr "princomp"
  • sdev = deviazioni standard delle componenti principali
  • loadings (anziché rotation) = la matrice con i component loadings
  • scores (anziché x) = le coordinate fattoriali dei casi (può essere omessa, con retx=FALSE)
  • center = in questo caso, le medie delle variabili
  • scale = in questo caso, le deviazioni standard delle variabili

Quindi, per ottenere le coordinate dei casi, il comando sarà:

> PCA1$scores
                    Comp.1      Comp.2      Comp.3       Comp.4
Alabama        -0.98556588  1.13339238 -0.44426879  0.156267145
Alaska         -1.95013775  1.07321326  2.04000333 -0.438583440
Arizona        -1.76316354 -0.74595678  0.05478082 -0.834652924
Arkansas        0.14142029  1.11979678  0.11457369 -0.182810896
....

Ed è con la matrice PCA1$scores che si potrà anche calcolare la matrice delle correlazioni variabili-componenti:

> cor(USArrests, PCA1$scores)
             Comp.1     Comp.2     Comp.3      Comp.4
Murder   -0.8439764  0.4160354 -0.2037600  0.27037052
Assault  -0.9184432  0.1870211 -0.1601192 -0.30959159
UrbanPop -0.4381168 -0.8683282 -0.2257242  0.05575330
Rape     -0.8558394 -0.1664602  0.4883190  0.03707412

Rotazione degli assi

Infine, volendo ruotare gli autovalori [o alcuni di essi] con il metodo varimax o promax:

> varimax(PCA1$loadings[,1:2])

oppure

> promax(PCA1$loadings[,1:2])

restituisce direttamente i valori degli autovalori ruotati.

- Per la rotazione dei fattori e il calcolo dei punteggi individuali, vedi anche ACP con rotazione delle componenti

Script

princomp-ex.R
PCA1<-princomp(USArrests, cor = TRUE)
print(PCA1)
loadings(PCA1)
summary(PCA1)
PCA1$scores
plot(PCA1)
biplot(PCA1)
PCA1$scores
cor(USArrests, PCA1$scores)
varimax(PCA1$loadings[,1:2])
promax(PCA1$loadings[,1:2])

Con FactoMiner

Vedi L'analisi in componenti principali con FactoMineR

FactoMiner propone una interfaccia interattiva: con_factoshiny

In RCommander

Utilizzando lo stesso esempio di prima, possiamo vedere come viene utilizzata in RCommander.

Come prima cosa, carichiamo il dataset “USArrests” (Dati / Dati presenti nei pacchetti / Leggi i dati da un pacchetto caricato → scrivere il nome del dataset).

Poi selezioniamo la funzione “Analisi delle componenti principali”, nel Menu “Statistiche / Analisi dimensionale”.


Infine selezioniamo le opzioni dalla finestra di dialogo:


Rcmdr>  .PC <- princomp(~Assault+Murder+Rape+UrbanPop, cor=TRUE, data=USArrests)

L'output automatico di RCommander è composto da:

- La matrice dei component loadings

Rcmdr>  unclass(loadings(.PC))  # component loadings
Comp.1     Comp.2     Comp.3      Comp.4
Assault  -0.5831836  0.1879856  0.2681484  0.74340748
Murder   -0.5358995  0.4181809  0.3412327 -0.64922780
Rape     -0.5434321 -0.1673186 -0.8177779 -0.08902432
UrbanPop -0.2781909 -0.8728062  0.3780158 -0.13387773

- La varianza delle componenti, ovvero la deviazione standard al quadrato (sd^2)

Rcmdr>  .PC$sd^2  # component variances
Comp.1    Comp.2    Comp.3    Comp.4 
2.4802416 0.9897652 0.3565632 0.1734301

- La funzione summary(), che corrisponde a quella vista sopra

Rcmdr>  summary(.PC) # proportions of variance
Importance of components:
  Comp.1    Comp.2    Comp.3     Comp.4
Standard deviation     1.5748783 0.9948694 0.5971291 0.41644938
Proportion of Variance 0.6200604 0.2474413 0.0891408 0.04335752
Cumulative Proportion  0.6200604 0.8675017 0.9566425 1.00000000

- E infine, se lo si è selezionato, il grafico delle componenti

Rcmdr>  screeplot(.PC)


Attenzione: RCommander elimina l'oggetto contenente gli output alla fine della procedura:

Rcmdr>  remove(.PC)

Domande? Scrivimi

Messenger Telegram Email
r/analisi_esplorativa/analisi_in_componenti_principali.txt · Ultima modifica: 05/09/2025 16:48 da Agnese Vardanega