Capítulo 5: Análisis de corrsepondencia múltiple

El análisis de correspondencia múltiple (MCA) es una extensión del análisis de correspondencia simple para resumir y visualizar una tabla de datos que contiene más de dos variables categóricas. También puede verse como una generalización del análisis de componentes principales cuando las variables a analizar son categóricas en lugar de cuantitativas.

library("FactoMineR")
library("factoextra")
## Loading required package: ggplot2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
#se cargan los datos 
data(poison)
head(poison[, 1:7], 3)
##   Age Time   Sick Sex   Nausea Vomiting Abdominals
## 1   9   22 Sick_y   F Nausea_y  Vomit_n     Abdo_y
## 2   5    0 Sick_n   F Nausea_n  Vomit_n     Abdo_n
## 3   6   16 Sick_y   F Nausea_n  Vomit_y     Abdo_y

Se crea un Subconjunto solo de individuos activos y variables para análisis de correspondencia múltiple:

poison.active <- poison[1:55, 5:15]
head(poison.active[, 1:6], 3)
##     Nausea Vomiting Abdominals   Fever   Diarrhae   Potato
## 1 Nausea_y  Vomit_n     Abdo_y Fever_y Diarrhea_y Potato_y
## 2 Nausea_n  Vomit_n     Abdo_n Fever_n Diarrhea_n Potato_y
## 3 Nausea_n  Vomit_y     Abdo_y Fever_y Diarrhea_y Potato_y
# Summary of the 4 first variables
summary(poison.active)[, 1:4]
##       Nausea      Vomiting   Abdominals     Fever   
##  Nausea_n:43   Vomit_n:33   Abdo_n:18   Fever_n:20  
##  Nausea_y:12   Vomit_y:22   Abdo_y:37   Fever_y:35

Las funciones de resumen () devuelven el tamaño de cada categoría de variable. También es posible trazar la frecuencia de las categorías de variables. El código R a continuación, traza las primeras 4 columnas:

for (i in 1:4) {
plot(poison.active[,i], main=colnames(poison.active)[i],
ylab = "Count", col="steelblue", las = 2)
}

En el código R a continuación, el MCA se realiza solo en el activo individuos/variables:

res.mca <- MCA(poison.active, graph = FALSE)
print(res.mca)
## **Results of the Multiple Correspondence Analysis (MCA)**
## The analysis was performed on 55 individuals, described by 11 variables
## *The results are available in the following objects:
## 
##    name              description                       
## 1  "$eig"            "eigenvalues"                     
## 2  "$var"            "results for the variables"       
## 3  "$var$coord"      "coord. of the categories"        
## 4  "$var$cos2"       "cos2 for the categories"         
## 5  "$var$contrib"    "contributions of the categories" 
## 6  "$var$v.test"     "v-test for the categories"       
## 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"           "intermediate results"            
## 12 "$call$marge.col" "weights of columns"              
## 13 "$call$marge.li"  "weights of rows"

La visualización e interpretación de los datos se presenta a continuación.

La proporción de varianzas retenidas por las diferentes dimensiones (ejes) se puede extraer usando la función get_eigenvalue() [paquete factoextra] de la siguiente manera:

library("factoextra")
eig.val <- get_eigenvalue(res.mca)
head(eig.val)
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1 0.33523140        33.523140                    33.52314
## Dim.2 0.12913979        12.913979                    46.43712
## Dim.3 0.10734849        10.734849                    57.17197
## Dim.4 0.09587950         9.587950                    66.75992
## Dim.5 0.07883277         7.883277                    74.64319
## Dim.6 0.07108981         7.108981                    81.75217

Estos datos se grafican de la siguiente forma.

fviz_screeplot(res.mca, addlabels = TRUE, ylim = c(0, 45))

La función fviz_mca_biplot() [paquete factoextra] se usa para dibujar el biplot de individuos y categorías de variables:

fviz_mca_biplot(res.mca,
repel = TRUE, # Avoid text overlapping (slow if many point)
ggtheme = theme_minimal())

La función get_mca_var() [de facto extra] se utiliza para extraer los resultados de las categorías de variables. Esta función devuelve una lista que contiene las coordenadas, el cos2 y la contribución de las categorías de variables:

var <- get_mca_var(res.mca)
var
## Multiple Correspondence Analysis Results for variables
##  ===================================================
##   Name       Description                  
## 1 "$coord"   "Coordinates for categories" 
## 2 "$cos2"    "Cos2 for categories"        
## 3 "$contrib" "contributions of categories"

Se puede acceder a los diferentes componentes de la siguiente manera:

# Coordinates
head(var$coord)
##               Dim 1       Dim 2        Dim 3       Dim 4       Dim 5
## Nausea_n  0.2673909  0.12139029 -0.265583253  0.03376130  0.07370500
## Nausea_y -0.9581506 -0.43498187  0.951673323 -0.12097801 -0.26410958
## Vomit_n   0.4790279 -0.40919465  0.084492799  0.27361142  0.05245250
## Vomit_y  -0.7185419  0.61379197 -0.126739198 -0.41041713 -0.07867876
## Abdo_n    1.3180221 -0.03574501 -0.005094243 -0.15360951 -0.06986987
## Abdo_y   -0.6411999  0.01738946  0.002478280  0.07472895  0.03399075
# Cos2: quality on the factore map
head(var$cos2)
##              Dim 1        Dim 2        Dim 3       Dim 4       Dim 5
## Nausea_n 0.2562007 0.0528025759 2.527485e-01 0.004084375 0.019466197
## Nausea_y 0.2562007 0.0528025759 2.527485e-01 0.004084375 0.019466197
## Vomit_n  0.3442016 0.2511603912 1.070855e-02 0.112294813 0.004126898
## Vomit_y  0.3442016 0.2511603912 1.070855e-02 0.112294813 0.004126898
## Abdo_n   0.8451157 0.0006215864 1.262496e-05 0.011479077 0.002374929
## Abdo_y   0.8451157 0.0006215864 1.262496e-05 0.011479077 0.002374929
# Contributions to the principal components
head(var$contrib)
##              Dim 1       Dim 2        Dim 3      Dim 4      Dim 5
## Nausea_n  1.515869  0.81100008 4.670018e+00 0.08449397 0.48977906
## Nausea_y  5.431862  2.90608363 1.673423e+01 0.30277007 1.75504164
## Vomit_n   3.733667  7.07226253 3.627455e-01 4.25893721 0.19036376
## Vomit_y   5.600500 10.60839380 5.441183e-01 6.38840581 0.28554563
## Abdo_n   15.417637  0.02943661 7.192511e-04 0.73219636 0.18424268
## Abdo_y    7.500472  0.01432051 3.499060e-04 0.35620363 0.08963157

Para visualizar la correlación entre las variables y las dimensiones principales de MCA se plantea lo siguiente.

fviz_mca_var(res.mca, choice = "mca.cor",
             repel = TRUE, # Avoid text overlapping (slow)
             ggtheme = theme_minimal())

El siguiente código R muestra las coordenadas de cada categoría de variable en cada dimensión (1, 2 y 3)

head(round(var$coord, 2), 4)
##          Dim 1 Dim 2 Dim 3 Dim 4 Dim 5
## Nausea_n  0.27  0.12 -0.27  0.03  0.07
## Nausea_y -0.96 -0.43  0.95 -0.12 -0.26
## Vomit_n   0.48 -0.41  0.08  0.27  0.05
## Vomit_y  -0.72  0.61 -0.13 -0.41 -0.08

Use la función fviz_mca_var() [de factoextra] para visualizar solo categorías de variables:

fviz_mca_var(res.mca,
repel = TRUE, # Avoid text overlapping (slow)
ggtheme = theme_minimal())

Es posible cambiar el color y la forma de los puntos variables usando los argumentos col.var y shape.var de la siguiente manera.

fviz_mca_var(res.mca, col.var="black", shape.var = 15,
repel = TRUE)

Las dos dimensiones 1 y 2 son suficientes para retener el 46% de la inercia total (variación) contenida en los datos. No todos los puntos se muestran igual de bien en las dos dimensiones. La calidad de la representación se denomina coseno al cuadrado (cos2), que mide el grado de asociación entre las categorías de variables y un eje particular.

En R es posible conocer estos valores de la siguiente forma.

head(var$cos2, 4)
##              Dim 1      Dim 2      Dim 3       Dim 4       Dim 5
## Nausea_n 0.2562007 0.05280258 0.25274850 0.004084375 0.019466197
## Nausea_y 0.2562007 0.05280258 0.25274850 0.004084375 0.019466197
## Vomit_n  0.3442016 0.25116039 0.01070855 0.112294813 0.004126898
## Vomit_y  0.3442016 0.25116039 0.01070855 0.112294813 0.004126898

Esto permite la realización de la siguiente gráfica.

# Color by cos2 values: quality on the factor map
fviz_mca_var(res.mca, col.var = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE, # Avoid text overlapping
ggtheme = theme_minimal())

# Change the transparency by cos2 values
fviz_mca_var(res.mca, alpha.var="cos2",
repel = TRUE,
ggtheme = theme_minimal())

Puede visualizar el cos2 de las categorías de fila en todas las dimensiones usando el paquete corrplot:

library("corrplot")
## corrplot 0.92 loaded
corrplot(var$cos2, is.corr=FALSE)

# Cos2 of variable categories on Dim.1 and Dim.2
fviz_cos2(res.mca, choice = "var", axes = 1:2)

La contribución de las categorías de variables (en %) a la definición de las dimensiones se puede extraer de la siguiente manera

head(round(var$contrib,2), 4)
##          Dim 1 Dim 2 Dim 3 Dim 4 Dim 5
## Nausea_n  1.52  0.81  4.67  0.08  0.49
## Nausea_y  5.43  2.91 16.73  0.30  1.76
## Vomit_n   3.73  7.07  0.36  4.26  0.19
## Vomit_y   5.60 10.61  0.54  6.39  0.29
# Contributions of rows to dimension 1
fviz_contrib(res.mca, choice = "var", axes = 1, top = 15)

# Contributions of rows to dimension 2
fviz_contrib(res.mca, choice = "var", axes = 2, top = 15)

# Total contribution to dimension 1 and 2
fviz_contrib(res.mca, choice = "var", axes = 1:2, top = 15)

Las categorías de variables más importantes (o contribuyentes) se pueden resaltar en el diagrama de dispersión de la siguiente manera:

fviz_mca_var(res.mca, col.var = "contrib",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE, # avoid text overlapping (slow)
             ggtheme = theme_minimal()
)

También es posible controlar la transparencia de las categorías de variables según sus valores de contribución utilizando la opción alpha.var = “contrib”.

# Change the transparency by contrib values
fviz_mca_var(res.mca, alpha.var="contrib",
repel = TRUE, ggtheme = theme_minimal())

La función get_mca_ind()[de factoextra] se utiliza para extraer los resultados de las personas. Esta función devuelve una lista que contiene las coordenadas, el cos2 y las contribuciones de los individuos.

ind <- get_mca_ind(res.mca)
ind
## Multiple Correspondence Analysis Results for individuals
##  ===================================================
##   Name       Description                       
## 1 "$coord"   "Coordinates for the individuals" 
## 2 "$cos2"    "Cos2 for the individuals"        
## 3 "$contrib" "contributions of the individuals"

Se hace lo siguiente para obtener acceso a los diferentes componentes.

# Coordinates of column points
head(ind$coord)
##        Dim 1       Dim 2       Dim 3       Dim 4       Dim 5
## 1 -0.4525811 -0.26415072  0.17151614  0.01369348 -0.11696806
## 2  0.8361700 -0.03193457 -0.07208249 -0.08550351  0.51978710
## 3 -0.4481892  0.13538726 -0.22484048 -0.14170168 -0.05004753
## 4  0.8803694 -0.08536230 -0.02052044 -0.07275873 -0.22935022
## 5 -0.4481892  0.13538726 -0.22484048 -0.14170168 -0.05004753
## 6 -0.3594324 -0.43604390 -1.20932223  1.72464616  0.04348157
# Quality of representation
head(ind$cos2)
##        Dim 1        Dim 2        Dim 3        Dim 4        Dim 5
## 1 0.34652591 0.1180447167 0.0497683175 0.0003172275 0.0231460846
## 2 0.55589562 0.0008108236 0.0041310808 0.0058126211 0.2148103098
## 3 0.54813888 0.0500176790 0.1379484860 0.0547920948 0.0068349171
## 4 0.74773962 0.0070299584 0.0004062504 0.0051072923 0.0507479873
## 5 0.54813888 0.0500176790 0.1379484860 0.0547920948 0.0068349171
## 6 0.02485357 0.0365775483 0.2813443706 0.5722083217 0.0003637178
# Contributions
head(ind$contrib)
##      Dim 1      Dim 2        Dim 3        Dim 4      Dim 5
## 1 1.110927 0.98238297  0.498254685  0.003555817 0.31554778
## 2 3.792117 0.01435818  0.088003703  0.138637089 6.23134138
## 3 1.089470 0.25806722  0.856229950  0.380768961 0.05776914
## 4 4.203611 0.10259105  0.007132055  0.100387990 1.21319013
## 5 1.089470 0.25806722  0.856229950  0.380768961 0.05776914
## 6 0.700692 2.67693398 24.769968729 56.404214518 0.04360547

La función fviz_mca_ind() [de facto extra] se usa para visualizar solo individuos. También es posible colorear a los individuos por sus valores de cos2. Se realiza de la siguiente forma.

fviz_mca_ind(res.mca, col.ind = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE, # Avoid text overlapping (slow if many points)
ggtheme = theme_minimal())

El siguiente código R crea un gráfico de barras de individuos cos2 y contribuciones.

# Cos2 of individuals
fviz_cos2(res.mca, choice = "ind", axes = 1:2, top = 20)

# Contribution of individuals to the dimensions
fviz_contrib(res.mca, choice = "ind", axes = 1:2, top = 20)

En R también es posible colorear individuos por grupos.

fviz_mca_ind(res.mca,
label = "none", # hide individual labels
habillage = "Vomiting", # color by groups
palette = c("#00AFBB", "#E7B800"),
addEllipses = TRUE, ellipse.type = "confidence",
ggtheme = theme_minimal())

# habillage = index of the column to be used as grouping variable
fviz_mca_ind(res.mca, habillage = 2, addEllipses = TRUE)

fviz_mca_ind(res.mca, habillage = poison$Vomiting, addEllipses = TRUE)

Si se busca colorear individuos usando múltiples variables categóricas al mismo tiempo se emplea la función fviz_ellipses().

fviz_ellipses(res.mca, c("Vomiting", "Fever"),
geom = "point")
## Warning: `gather_()` was deprecated in tidyr 1.2.0.
## ℹ Please use `gather()` instead.
## ℹ The deprecated feature was likely used in the factoextra package.
##   Please report the issue at <https://github.com/kassambara/factoextra/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

También se pueden especificar índices de variables categóricas

fviz_ellipses(res.mca, 1:4, geom = "point")

La función dimdesc() [en FactoMineR] se puede utilizar para identificar las variables más correlacionadas con una dimensión dada.

res.desc <- dimdesc(res.mca, axes = c(1,2))
# Description of dimension 1
res.desc[[1]]
## 
## Link between the variable and the categorical variable (1-way anova)
## =============================================
##                   R2      p.value
## Abdominals 0.8451157 4.055640e-23
## Diarrhae   0.7994680 3.910776e-20
## Fever      0.7846788 2.600566e-19
## Mayo       0.3829749 4.756234e-07
## Vomiting   0.3442016 2.510738e-06
## Nausea     0.2562007 8.062777e-05
## Cheese     0.1944181 7.534834e-04
## 
## Link between variable and the categories of the categorical variables
## ================================================================
##                       Estimate      p.value
## Abdominals=Abdo_n    0.5671866 4.055640e-23
## Diarrhae=Diarrhea_n  0.5380920 3.910776e-20
## Fever=Fever_n        0.5330918 2.600566e-19
## Mayo=Mayo_n          0.4644981 4.756234e-07
## Vomiting=Vomit_n     0.3466915 2.510738e-06
## Nausea=Nausea_n      0.3547892 8.062777e-05
## Cheese=Cheese_n      0.3830043 7.534834e-04
## Cheese=Cheese_y     -0.3830043 7.534834e-04
## Nausea=Nausea_y     -0.3547892 8.062777e-05
## Vomiting=Vomit_y    -0.3466915 2.510738e-06
## Mayo=Mayo_y         -0.4644981 4.756234e-07
## Fever=Fever_y       -0.5330918 2.600566e-19
## Diarrhae=Diarrhea_y -0.5380920 3.910776e-20
## Abdominals=Abdo_y   -0.5671866 4.055640e-23
# Description of dimension 2
res.desc[[2]]
## 
## Link between the variable and the categorical variable (1-way anova)
## =============================================
##                  R2      p.value
## Courgette 0.4464145 2.500166e-08
## Potato    0.3957543 2.690662e-07
## Vomiting  0.2511604 9.728027e-05
## Icecream  0.1409011 4.743927e-03
## 
## Link between variable and the categories of the categorical variables
## ================================================================
##                       Estimate      p.value
## Courgette=Courg_n    0.4176013 2.500166e-08
## Potato=Potato_y      0.4977523 2.690662e-07
## Vomiting=Vomit_y     0.1838104 9.728027e-05
## Icecream=Icecream_n  0.2597197 4.743927e-03
## Icecream=Icecream_y -0.2597197 4.743927e-03
## Vomiting=Vomit_n    -0.1838104 9.728027e-05
## Potato=Potato_n     -0.4977523 2.690662e-07
## Courgette=Courg_y   -0.4176013 2.500166e-08

Para hacer un biplot de individuos y categorías variables se escribe lo siguiente.

# Biplot of individuals and variable categories
fviz_mca_biplot(res.mca, repel = TRUE,
ggtheme = theme_minimal())

fviz_mca_var(res.mca, choice = "mca.cor",
repel = TRUE)

El siguiente código R traza categorías de variables cualitativas (variables activas y complementarias):

fviz_mca_var(res.mca, repel = TRUE,
ggtheme= theme_minimal())

fviz_mca_ind(res.mca,
label = "ind.sup", #Show the label of ind.sup only
ggtheme = theme_minimal())

Si tiene muchos individuos/categorías de variables, es posible visualizar solo algunos de ellos usando los argumentos select.ind y select.var

# Visualize variable categories with cos2 >= 0.4
fviz_mca_var(res.mca, select.var = list(cos2 = 0.4))

# Top 10 active variables with the highest cos2
fviz_mca_var(res.mca, select.var= list(cos2 = 10))

# Select by names
name <- list(name = c("Fever_n", "Abdo_y", "Diarrhea_n",
"Fever_Y", "Vomit_y", "Vomit_n"))
fviz_mca_var(res.mca, select.var = name)

# top 5 contributing individuals and variable categories
fviz_mca_biplot(res.mca, select.ind = list(contrib = 5),
select.var = list(contrib = 5),
ggtheme = theme_minimal())

Independientemente de las funciones que decida usar, en la lista anterior, el paquete factoextra puede manejar la salida.

fviz_eig(res.mca) # Scree plot

fviz_mca_biplot(res.mca) # Biplot of rows and columns