Introducción
El análisis de componentes principales (PCA) nos permite resumir y visualizar la información en un conjunto de datos que contiene individuos/observaciones descritas por múltiples variables cuantitativas interrelacionadas. Cada variable podría considerarse como una dimensión diferente. Si tiene más de 3 variables en sus conjuntos de datos, podría ser muy difícil visualizar un hiperespacio multidimensional.
El análisis de componentes principales se utiliza para extraer la información importante de una tabla de datos multivariada y para expresar esta información como un conjunto de pocas variables nuevas llamadas componentes principales. Estas nuevas variables corresponden a una combinación lineal de las originales. El número de componentes principales es menor o igual que el número de variables originales.
La información en un conjunto de datos dado corresponde a la variación total que contiene. El objetivo de PCA es identificar direcciones (o componentes principales) a lo largo de las cuales la variación en los datos es máxima.
En otras palabras, PCA reduce la dimensionalidad de los datos multivariados a dos o tres componentes principales, que se pueden visualizar gráficamente, con una mínima pérdida de información.
En este capítulo, describimos la idea básica de PCA y demostramos cómo calcular y visualizar PCA utilizando el software R. Además, mostraremos cómo revelar las variables más importantes que explican las variaciones en un conjunto de datos.
Paquetes R
Usaremos los dos paquetes FactoMineR, (para el análisis) y factoextra (para la visualización basada en ggplot?).
install.packages(c("FactoMineR", "factoextra"))
## Installing packages into '/cloud/lib/x86_64-pc-linux-gnu-library/4.3'
## (as 'lib' is unspecified)
library ("FactoMineR")
library ("factoextra")
## Loading required package: ggplot2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
Formato de datos:
Usaremos los conjuntos de datos de demostración decathlon2 del paquete factoextra:
data(decathlon2)
los datos utilizados aquí describen el rendimiento de los atletas durante dos eventos deportivos (Dectar y OlympicG). Contiene 27 individuos (atletas) descritos por 13 variables.
Tenga en cuenta que solo algunos de estos individuos y variables se utilizarán para realizar el análisis de componentes principales. Las coordenadas de los restantes individuos y variables en el mapa de factores se pronosticarán después del PCA.
Comenzamos subdividiendo individuos activos y variables activas para el análisis de componentes principales:
decathlon2.active <- decathlon2[1:23, 1:10]
head(decathlon2.active[, 1:6], 4)
## X100m Long.jump Shot.put High.jump X400m X110m.hurdle
## SEBRLE 11.04 7.58 14.83 2.07 49.81 14.69
## CLAY 10.76 7.40 14.26 1.86 49.37 14.05
## BERNARD 11.02 7.23 14.25 1.92 48.93 14.99
## YURKOV 11.34 7.09 15.19 2.10 50.42 15.31
Estandarización de datos
En el análisis de componentes principales, las variables a menudo se escalan (es decir, se estandarizan). Esto es especialmente recomendable cuando las variables se miden en diferentes escalas (por ejemplo: kilogramos, kilómetros, centímetros, …); de lo contrario, los resultados de PCA obtenidos se verán gravemente afectados.
El objetivo es hacer que las variables sean comparables. En general, las variables se escalan para tener i) desviación estándar uno y ii) media cero.
La estandarización de datos es un enfoque ampliamente utilizado en el contexto del análisis de datos de expresión génica antes del PCA y el análisis de agrupamiento. También podríamos querer escalar los datos cuando la media y/o la desviación estándar de las variables son muy diferentes.
Código R
Se puede utilizar la función PCA() [paquete FactoMineR]. Un formato simplificado es
library ("FactoMineR")
res.pca <- PCA(decathlon2.active, graph = FALSE)
print(res.pca)
## **Results for the Principal Component Analysis (PCA)**
## The analysis was performed on 23 individuals, described by 10 variables
## *The results are available in the following objects:
##
## name description
## 1 "$eig" "eigenvalues"
## 2 "$var" "results for the variables"
## 3 "$var$coord" "coord. for the variables"
## 4 "$var$cor" "correlations variables - dimensions"
## 5 "$var$cos2" "cos2 for the variables"
## 6 "$var$contrib" "contributions of the variables"
## 7 "$ind" "results for the individuals"
## 8 "$ind$coord" "coord. for the individuals"
## 9 "$ind$cos2" "cos2 for the individuals"
## 10 "$ind$contrib" "contributions of the individuals"
## 11 "$call" "summary statistics"
## 12 "$call$centre" "mean of the variables"
## 13 "$call$ecart.type" "standard error of the variables"
## 14 "$call$row.w" "weights for the individuals"
## 15 "$call$col.w" "weights for the variables"
Visualización e Interpretación
Usaremos el paquete factoextra R para ayudar en la interpretación de PCA. No importa qué función decida usar [stats::prcomp(), FactoMiner::PCA(), ade4::dudi.pca(), ExPosition::epPCA(], puede extraer y visualizar fácilmente los resultados de PCA usando Funciones de R proporcionadas en el paquete factoeztra R.
Valores propios / Varianzas
Como se describió en las secciones anteriores, los valores propios miden la cantidad de variación retenida por cada componente principal. Los valores propios son grandes para las primeras PC y pequeños para las PC posteriores. Es decir, las primeras PC corresponden a las direcciones con la máxima cantidad de variación en el conjunto de datos.
Examinamos los valores propios para determinar el número de componentes principales a considerar. Los valores propios y la proporción de varianzas (es decir, información) retenida por los componentes principales (PC) se pueden extraer utilizando la función get _eigenvalue() [factoextra package].
library ("factoextra")
eig.val <- get_eigenvalue(res.pca)
eig.val
## eigenvalue variance.percent cumulative.variance.percent
## Dim.1 4.1242133 41.242133 41.24213
## Dim.2 1.8385309 18.385309 59.62744
## Dim.3 1.2391403 12.391403 72.01885
## Dim.4 0.8194402 8.194402 80.21325
## Dim.5 0.7015528 7.015528 87.22878
## Dim.6 0.4228828 4.228828 91.45760
## Dim.7 0.3025817 3.025817 94.48342
## Dim.8 0.2744700 2.744700 97.22812
## Dim.9 0.1552169 1.552169 98.78029
## Dim.10 0.1219710 1.219710 100.00000
En nuestro análisis, los primeros tres componentes principales explican el 72% de la variación. Este es un porcentaje aceptablemente grande.
Un método alternativo para determinar el número de componentes principales es mirar un Scree Plot, que es el gráfico de valores propios ordenados de mayor a menor. El número de componente se determina en el punto, más allá del cual los valores propios restantes todos son relativamente pequeños y de tamaño comparable
El scree plot se puede producir utilizando la función fuiz _eíg() o fuiz_screeplot() [paquete factoeztra].
fviz_eig(res.pca, addlabels = TRUE, ylim = c(0, 50))
Gráfico de variables
Un método simple para extraer los resultados, para las variables, de una salida PCA es usar la función get_pca_var() [paquete factoeztra]. Esta función proporciona una lista de matrices que contienen todos los resultados de las variables activas (coordenadas, correlación entre variables y ejes, coseno al cuadrado y contribuciones)
var <- get_pca_var(res.pca)
var
## Principal Component Analysis Results for variables
## ===================================================
## Name Description
## 1 "$coord" "Coordinates for the variables"
## 2 "$cor" "Correlations between variables and dimensions"
## 3 "$cos2" "Cos2 for the variables"
## 4 "$contrib" "contributions of the variables"
Se puede acceder a los diferentes componentes de la siguiente manera:
Coordenadas head (var$coord)
Cos2: calidad en el mapa factore head (varf$cos?)
Aportes a los componentes principales head (var$contrib)
Describimos cómo visualizar variables y sacar conclusiones sobre sus correlaciones. A continuación, destacamos las variables según i) su calidad de representación en el mapa de factores o ii) sus contribuciones a los componentes principales.
Círculo de correlación
La correlación entre una variable y un componente principal (PC) se utiliza como las coordenadas de la variable en el PC. La representación de las variables difiere de la gráfica de las observaciones: las observaciones están representadas por sus proyecciones, pero las variables están representadas por sus correlaciones
head(var$coord, 4)
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## X100m -0.8506257 -0.17939806 0.3015564 0.0335732 -0.1944440
## Long.jump 0.7941806 0.28085695 -0.1905465 -0.1153896 0.2331567
## Shot.put 0.7339127 0.08540412 0.5175978 0.1284684 -0.2488129
## High.jump 0.6100840 -0.46521415 0.3300852 0.1445501 0.4027002
fviz_pca_var(res.pca, col.var = "black")
El gráfico anterior también se conoce como gráficos de correlación de variables. Muestra las relaciones entre todas las variables. Se puede interpretar de la siguiente manera:
Calidad de representación
La calidad de representación de las variables en el mapa de factores se llama cos? (coseno al cuadrado, coordenadas al cuadrado) . Puede acceder a cos2 de la siguiente manera:
head(var$cos2, 4)
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## X100m 0.7235641 0.032183664 0.09093628 0.00112716 0.03780845
## Long.jump 0.6307229 0.078880629 0.03630798 0.01331475 0.05436203
## Shot.put 0.5386279 0.007293864 0.26790749 0.01650412 0.06190783
## High.jump 0.3722025 0.216424207 0.10895622 0.02089474 0.16216747
library ("corrplot")
## corrplot 0.92 loaded
corrplot (var$cos2, is.corr=FALSE)
fviz_cos2(res.pca, choice = "var", axes = 1:2)
Es posible colorear las variables por su valor cos2 usando el argumento col.var = “cos2”. Esto produce un degradado de colores. En este caso, el argumento gradiente.cols se puede utilizar para proporcionar un color personalizado.
fviz_pca_var(res.pca, col.var = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE
)
Aportes de variables a PCs
Las contribuciones de las variables para explicar la variabilidad en un componente principal dado se expresan en porcentaje.
Las variables que están correlacionadas con PC1 (es decir, Dim.1) y PC2 (es decir, Dim.2) son las más importantes para explicar la variabilidad en el conjunto de datos.
Las variables que no se correlacionan con ningún PC o se correlacionan con las últimas dimensiones son variables de baja contribución y podrían eliminarse para simplificar el análisis general.
head(var$contrib, 4)
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## X100m 17.544293 1.7505098 7.338659 0.1375524 5.389252
## Long.jump 15.293168 4.2904162 2.930094 1.6248594 7.748815
## Shot.put 13.060137 0.3967224 21.620432 2.0140727 8.824401
## High.jump 9.024811 11.7715838 8.792888 2.5498795 23.115504
library ("corrplot")
corrplot (var$contrib, is.corr=FALSE)
La función fuiz_contrib() [paquete factoextra] se puede utilizar para dibujar un gráfico de barras de contribuciones variables. Si sus datos contienen muchas variables, puede decidir mostrar solo las principales variables contribuyentes. El siguiente código R muestra las 10 principales variables que contribuyen a los componentes principales
fviz_contrib(res.pca, choice = "var", axes = 1, top = 10)
fviz_contrib(res.pca, choice = "var", axes = 2, top = 10)
Las variables más importantes (o contribuyentes) se pueden resaltar en
el gráfico de correlación de la siguiente manera:
fviz_pca_var(res.pca, col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07")
)
Colorea por una variable continua personalizada
En las secciones anteriores, mostramos cómo colorear variables por sus contribuciones y su cos2. Tenga en cuenta que es posible colorear las variables por cualquier variable continua personalizada. La variable de color debe tener la misma longitud que el número de variables activas en el PCA (aquí n = 10).
set.seed(123)
my.cont.var <- rnorm(10)
fviz_pca_var(res.pca, col.var = my.cont.var,
gradient.cols = c("blue", "yellow", "red"),
legend.title = "Cont .Var")
Colorear por grupos
También es posible cambiar el color de las variables por grupos definidos por una variable cualitativa/categórica, también llamada factor en la terminología R.
set.seed(123)
res.km <- kmeans(var$coord, centers = 3, nstart = 25)
grp <- as.factor(res.km$cluster)
fviz_pca_var(res.pca, col.var = grp,
palette = c("#0073C2FF", "#EFC000FF", "#868686FF"),
legend.title = "Cluster")
Descripción de la dimensión
Tenga en cuenta también que la función dimdesc() [en FactoMineR], para la descripción de la dimensión, se puede utilizar para identificar las variables asociadas más significativas con un componente principal determinado.
res.desc <- dimdesc(res.pca, axes = c(1,2), proba = 0.05)
res.desc$Dim.1
##
## Link between the variable and the continuous variables (R-square)
## =================================================================================
## correlation p.value
## Long.jump 0.7941806 6.059893e-06
## Discus 0.7432090 4.842563e-05
## Shot.put 0.7339127 6.723102e-05
## High.jump 0.6100840 1.993677e-03
## Javeline 0.4282266 4.149192e-02
## X400m -0.7016034 1.910387e-04
## X110m.hurdle -0.7641252 2.195812e-05
## X100m -0.8506257 2.727129e-07
res.desc$Dim.2
##
## Link between the variable and the continuous variables (R-square)
## =================================================================================
## correlation p.value
## Pole.vault 0.8074511 3.205016e-06
## X1500m 0.7844802 9.384747e-06
## High.jump -0.4652142 2.529390e-02
Gráfica de individuos
Los resultados, para individuos, se pueden extraer usando la función get _pca_ind() [paquete factoeztra]. De manera similar a get _pca _var(), la función get pca _ind() proporciona una lista de matrices que contienen todos los resultados para los individuos (coordenadas, correlación entre variables y ejes, coseno al cuadrado y contribuciones)
ind <- get_pca_ind(res.pca)
ind
## Principal Component Analysis Results for individuals
## ===================================================
## Name Description
## 1 "$coord" "Coordinates for the individuals"
## 2 "$cos2" "Cos2 for the individuals"
## 3 "$contrib" "contributions of the individuals"
El fviz_pca_ind() se usa para producir el gráfico de individuos.
fviz_pca_ind(res.pca)
fviz_pca_ind(res.pca, col.ind = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE
)
También puede cambiar el tamaño del punto según el cos2 de los individuos correspondientes
fviz_pca_ind(res.pca, pointsize = "cos2",
pointshape = 21, fill = "#E7B800",
repel = TRUE)
Para crear un gráfico de barras de la calidad de representación (cos2) de los individuos en el mapa de factores, puede usar la función fuiz _cos2() como se describió anteriormente para las variables
fviz_contrib(res.pca, choice = "ind", axes = 1:2)
Colorear por una variable continua personalizada
En cuanto a las variables, los individuos pueden ser coloreados por cualquier variable continua personalizada especificando el argumento col.ind.
Colorea por grupos
Aquí, describimos cómo colorear individuos por grupo. Además, mostramos cómo agregar elipses de concentración y elipses de confianza por grupos. Para esto, usaremos los datos del iris como conjuntos de datos de demostración.
head(iris, 3)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
iris.pca <- PCA(iris[,-5], graph = FALSE)
En el siguiente código R: el argumento habillage o col.ind puede usarse para especificar la variable factor para colorear los individuos por grupos.
Para agregar una elipse de concentración alrededor de cada grupo, especifique el argumento addEllipses = TRUE. La paleta de argumentos se puede utilizar para cambiar los colores del grupo.
fviz_pca_ind(iris.pca,
geom.ind = "point",
col.ind = iris$Species,
palette = c("#00AFBB", "#E7B800", "#FC4E07"),
addEllipses = TRUE,
legend.title = "Groups"
)
Parámetros gráficos
Para cambiar fácilmente la gráfica de cualquier ggplots, puede usar la función ggpar()’ [ggpubrpackage]
ind.p <- fviz_pca_ind(iris.pca, geom = "point", col.ind = iris$Species)
ggpubr::ggpar(ind.p,
title = "Principal Component Analysis",
subtitle = "Iris data set",
caption = "Source: factoextra",
xlab = "PC1", ylab = "PC?",
legend.title = "Species", legend.position = "top",
ggtheme = theme_gray(), palette = "jco"
)
Biplot
fviz_pca_biplot(res.pca, repel = TRUE,
col.var = "#2E9FDF",
col.ind = "#696969"
)
Ahora, usando la salida de iris.pca, hagamos lo siguiente:
fviz_pca_biplot(iris.pca,
col.ind = iris$Species, palette = "jco",
addEllipses = TRUE, label = "var",
col.var = "black", repel = TRUE,
legend.title = "Species")
Para personalizar individuos y colores variables, usamos las funciones auxiliares fill palette() y color _palette() [en el paquete ggpubr.
fviz_pca_biplot(iris.pca,
geom.ind = "point",
pointshape = 21,
pointsize = 2.5,
fill.ind = iris$Species,
col.ind = "black",
col.var = factor(c("sepal", "sepal", "petal", "petal")),
legend.title = list(fill = "Species", color = "Clusters"),
repel = TRUE
)+
ggpubr::fill_palette("jco")+
ggpubr::color_palette ("npg")
Otro ejemplo complejo es colorear individuos por grupos (colores
discretos) y variables por sus contribuciones a los componentes
principales (colores degradados). Además, cambiaremos la transparencia
de las variables por sus contribuciones utilizando el argumento alfa.
var.
fviz_pca_biplot(iris.pca,
geom.ind = "point",
fill.ind = iris$Species, col.ind = "black",
pointshape = 21, pointsize =,
palette = "jco",
addEllipses = TRUE,
alpha.var ="contrib", col.var = "contrib",
gradient.cols = "RdYlBu",
legend.title = list(fill = "Species", color = "Contrib",
alpha = "Contrib")
)
res.pca <- PCA(decathlon2, ind.sup = 24:27,
quanti.sup = 11:12, quali.sup = 13, graph=FALSE)
Variables cuantitativas
res.pca$quanti.sup
## $coord
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## Rank -0.7014777 -0.24519443 -0.1834294 0.05575186 -0.07382647
## Points 0.9637075 0.07768262 0.1580225 -0.16623092 -0.03114711
##
## $cor
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## Rank -0.7014777 -0.24519443 -0.1834294 0.05575186 -0.07382647
## Points 0.9637075 0.07768262 0.1580225 -0.16623092 -0.03114711
##
## $cos2
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## Rank 0.4920710 0.060120310 0.03364635 0.00310827 0.0054503477
## Points 0.9287322 0.006034589 0.02497110 0.02763272 0.0009701427
fviz_pca_var (res.pca)
Individuos
Resultados previstos para los individuos suplementarios (ind.sup)
Visualizar todos los individuos (activos y suplementarios). En el gráfico, puede agregar también las variables cualitativas suplementarias (quali.sup), cuyas coordenadas son accesibles usando res.pca\(quali.supp\)coord.
res.pca$ind.sup
## $coord
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## KARPOV 0.7947206 0.77951227 -1.6330203 1.7242283 -0.75070396
## WARNERS -0.3864645 -0.12159237 -1.7387332 -0.7063341 -0.03230011
## Nool -0.5591306 1.97748871 -0.4830358 -2.2784526 -0.25461493
## Drews -1.1092038 0.01741477 -3.0488182 -1.5343468 -0.32642192
##
## $cos2
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## KARPOV 0.05104677 4.911173e-02 0.21553730 0.24028620 0.0455487744
## WARNERS 0.02422707 2.398250e-03 0.49039677 0.08092862 0.0001692349
## Nool 0.02897149 3.623868e-01 0.02162236 0.48108780 0.0060077529
## Drews 0.09207094 2.269527e-05 0.69560547 0.17617609 0.0079736753
##
## $dist
## KARPOV WARNERS Nool Drews
## 3.517470 2.482899 3.284943 3.655527
p <- fviz_pca_ind(res.pca, col.ind.sup = "blue", repel = TRUE)
p <- fviz_add(p, res.pca$quali.sup$coord, color = "red")
p
Variables cualitativas
las variables cualitativas suplementarias pueden ser también usadas para colrear indivduosp or grupos. Esto puede ayudar a interpetar los datos. Los conjuntos de datos decathlon2 contienen una variable cualitativa suplementaria en columnas 13 correspondiente a el tipo de competencia.
res.pca$quali
## $coord
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## Decastar -1.343451 0.1218097 -0.03789524 0.1808357 0.1343364
## OlympicG 1.231497 -0.1116589 0.03473730 -0.1657661 -0.1231417
##
## $cos2
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## Decastar 0.9051233 0.007440939 0.0007201669 0.01639956 0.009050062
## OlympicG 0.9051233 0.007440939 0.0007201669 0.01639956 0.009050062
##
## $v.test
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## Decastar -2.970766 0.4034256 -0.1528767 0.8971036 0.7202457
## OlympicG 2.970766 -0.4034256 0.1528767 -0.8971036 -0.7202457
##
## $dist
## Decastar OlympicG
## 1.412108 1.294433
##
## $eta2
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## Competition 0.4011568 0.00739783 0.001062332 0.03658159 0.02357972
fviz_pca_ind(res.pca, habillage = 13,
addEllipses =TRUE, ellipse.type = "confidence",
palette = "jco", repel = TRUE)