Capítulo 6: Análisis factorial de datos mixtos en R

El análisis factorial de datos mixtos (FAMD) es un método componente principal dedicado a analizar un conjunto de datos que contiene variables cuantitativas y cualitativas. Permite analizar la similitud entre individuos teniendo en cuenta una mezcla de tipos de variables. Además, se puede explorar la asociación entre todas las variables, tanto cuantitativas como cualitativas.

Como en los anteriores cápitulos, en principio, también se cargan las librerías.

#install.packages(c("FactoMineR", "factoextra"))
library("FactoMineR")
library("factoextra")
## Loading required package: ggplot2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa

También, se cargan los datos correspondientes que se utilizaran posteriormente.

library("FactoMineR")
data(wine)
df <- wine[,c(1,2, 16, 22, 29, 28, 30,31)]
head(df[, 1:7], 4)
##           Label Soil Plante Acidity Harmony Intensity Overall.quality
## 2EL      Saumur Env1  2.000   2.107   3.143     2.857           3.393
## 1CHA     Saumur Env1  2.000   2.107   2.964     2.893           3.214
## 1FON Bourgueuil Env1  1.750   2.179   3.143     3.074           3.536
## 1VAU     Chinon Env2  2.304   3.179   2.038     2.462           2.464
str(df)
## 'data.frame':    21 obs. of  8 variables:
##  $ Label          : Factor w/ 3 levels "Saumur","Bourgueuil",..: 1 1 2 3 1 2 2 1 3 1 ...
##  $ Soil           : Factor w/ 4 levels "Reference","Env1",..: 2 2 2 3 1 1 1 2 2 3 ...
##  $ Plante         : num  2 2 1.75 2.3 1.76 ...
##  $ Acidity        : num  2.11 2.11 2.18 3.18 2.57 ...
##  $ Harmony        : num  3.14 2.96 3.14 2.04 3.64 ...
##  $ Intensity      : num  2.86 2.89 3.07 2.46 3.64 ...
##  $ Overall.quality: num  3.39 3.21 3.54 2.46 3.74 ...
##  $ Typical        : num  3.25 3.04 3.18 2.25 3.44 ...

Para computar el FAMD se realiza lo siguiente:

library(FactoMineR)
res.famd <- FAMD(df, graph = FALSE)
print(res.famd)
## *The results are available in the following objects:
## 
##   name          description                             
## 1 "$eig"        "eigenvalues and inertia"               
## 2 "$var"        "Results for the variables"             
## 3 "$ind"        "results for the individuals"           
## 4 "$quali.var"  "Results for the qualitative variables" 
## 5 "$quanti.var" "Results for the quantitative variables"

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

library("factoextra")
eig.val <- get_eigenvalue(res.famd)
head(eig.val) 
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  4.8315174        43.922886                    43.92289
## Dim.2  1.8568797        16.880724                    60.80361
## Dim.3  1.5824794        14.386176                    75.18979
## Dim.4  1.1491200        10.446546                    85.63633
## Dim.5  0.6518053         5.925503                    91.56183

La función fviz_eig() o fviz_screeplot() [paquete factoextra] se puede utilizar para dibujar el diagrama de pedregal (los porcentajes de inercia explicados por cada dimensión FAMD):

fviz_screeplot(res.famd)

La función fviz_eig() o fviz_screeplot() [paquete factoextra] se puede utilizar para dibujar el diagrama de pedregal (los porcentajes de inercia explicados por cada dimensión FAMD):

var <- get_famd_var(res.famd)
var
## FAMD results for variables 
##  ===================================================
##   Name       Description                      
## 1 "$coord"   "Coordinates"                    
## 2 "$cos2"    "Cos2, quality of representation"
## 3 "$contrib" "Contributions"

Se puede acceder a la diferencia entre estos datos de la siguiente forma.

# Coordinates of variables
head(var$coord)
##                     Dim.1       Dim.2       Dim.3       Dim.4        Dim.5
## Plante          0.7344160 0.060551966 0.105902048 0.004011299 0.0010340559
## Acidity         0.1732738 0.491118153 0.126394029 0.115376784 0.0045862935
## Harmony         0.8943968 0.023628146 0.040124469 0.003653813 0.0086624633
## Intensity       0.6991811 0.134639254 0.065382234 0.023214984 0.0064730431
## Overall.quality 0.9115699 0.005246728 0.009336677 0.005445276 0.0007961880
## Typical         0.7808611 0.027094327 0.001549791 0.083446627 0.0005912942
# Cos2: quality of representation on the factore map
head(var$cos2)
##                      Dim.1        Dim.2        Dim.3        Dim.4        Dim.5
## Plante          0.53936692 3.666541e-03 1.121524e-02 1.609052e-05 1.069272e-06
## Acidity         0.03002381 2.411970e-01 1.597545e-02 1.331180e-02 2.103409e-05
## Harmony         0.79994566 5.582893e-04 1.609973e-03 1.335035e-05 7.503827e-05
## Intensity       0.48885427 1.812773e-02 4.274836e-03 5.389355e-04 4.190029e-05
## Overall.quality 0.83095973 2.752815e-05 8.717353e-05 2.965103e-05 6.339153e-07
## Typical         0.60974400 7.341026e-04 2.401853e-06 6.963340e-03 3.496288e-07
# Contributions to the  dimensions
head(var$contrib)
##                     Dim.1      Dim.2      Dim.3      Dim.4      Dim.5
## Plante          15.200526  3.2609526 6.69215972  0.3490757 0.15864490
## Acidity          3.586323 26.4485720 7.98708850 10.0404466 0.70362936
## Harmony         18.511716  1.2724651 2.53554453  0.3179662 1.32899551
## Intensity       14.471254  7.2508336 4.13163258  2.0202401 0.99309457
## Overall.quality 18.867156  0.2825562 0.59000304  0.4738648 0.12215119
## Typical         16.161818  1.4591321 0.09793437  7.2617850 0.09071638

Estas variables se gráfican a continuación.

# Plot of variables
fviz_famd_var(res.famd, repel = TRUE)

# Contribution to the first dimension
fviz_contrib(res.famd, "var", axes = 1)

# Contribution to the second dimension
fviz_contrib(res.famd, "var", axes = 2)

Para extraer los resultados de las variables cuantitativas, se plantea lo siguiente:

quanti.var <- get_famd_var(res.famd, "quanti.var")
quanti.var 
## FAMD results for quantitative variables 
##  ===================================================
##   Name       Description                      
## 1 "$coord"   "Coordinates"                    
## 2 "$cos2"    "Cos2, quality of representation"
## 3 "$contrib" "Contributions"
fviz_famd_var(res.famd, "quanti.var", repel = TRUE,
              col.var = "black")

Las variables cuantitativas más contribuyentes se pueden resaltar en el diagrama de dispersión usando el argumento col.var = “contrib”. Esto produce un degradado de colores, que se puede personalizar utilizando el argumento gradient.cols.

fviz_famd_var(res.famd, "quanti.var", col.var = "contrib", 
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE)

Del mismo modo, puede resaltar variables cuantitativas utilizando sus valores cos2 que representan la calidad de la representación en el mapa factorial. Si una variable está bien representada por dos dimensiones, la suma del cos2 se cierra a uno. Para algunos de los elementos, es posible que se requieran más de 2 dimensiones para representar perfectamente los datos.

# Color by cos2 values: quality on the factor map
fviz_famd_var(res.famd, "quanti.var", col.var = "cos2",
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), 
             repel = TRUE)

Al igual que las variables cuantitativas, los resultados de las variables cualitativas se pueden extraer de la siguiente manera:

quali.var <- get_famd_var(res.famd, "quali.var")
quali.var 
## FAMD results for qualitative variable categories 
##  ===================================================
##   Name       Description                      
## 1 "$coord"   "Coordinates"                    
## 2 "$cos2"    "Cos2, quality of representation"
## 3 "$contrib" "Contributions"

Esto se grafica a continuación.

fviz_famd_var(res.famd, "quali.var", col.var = "contrib", 
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07")
             )

Si se desean hacer gráficos individuales se realiza lo siguiente.

ind <- get_famd_ind(res.famd)
ind
## FAMD results for individuals 
##  ===================================================
##   Name       Description                      
## 1 "$coord"   "Coordinates"                    
## 2 "$cos2"    "Cos2, quality of representation"
## 3 "$contrib" "Contributions"

Para trazar individuos, use la función fviz_mfa_ind() [in factoextra]. De forma predeterminada, los individuos están coloreados en azul. Sin embargo, al igual que las variables, también es posible colorear a los individuos por sus valores de cos2 y contribución:

fviz_famd_ind(res.famd, col.ind = "cos2", 
             gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
             repel = TRUE)

Es posible colorear a los individuos utilizando cualquiera de las variables cualitativas en la tabla de datos inicial. Para ello, se utiliza el argumento habillage en la función fviz_famd_ind().

fviz_mfa_ind(res.famd, 
             habillage = "Label", # color by groups 
             palette = c("#00AFBB", "#E7B800", "#FC4E07"),
             addEllipses = TRUE, ellipse.type = "confidence", 
             repel = TRUE # Avoid text overlapping
             ) 

fviz_ellipses(res.famd, c("Label", "Soil"), repel = TRUE)
## 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.

Una forma alternativa sería la siguiente.

fviz_ellipses(res.famd, 1:2, geom = "point")

Capítulo 7: análisis de factores múltiples

El análisis factorial múltiple (MFA) es un método de análisis de datos multivariante para resumir y visualizar una tabla de datos compleja en la que los individuos se describen mediante varios conjuntos de variables (cuantitativas y/o cualitativas) estructuradas en grupos. Tiene en cuenta la contribución de todos los grupos activos de variables para definir la distancia entre individuos.

Se instalan los paquetes y las liberías.

#install.packages(c("FactoMineR", "factoextra"))

library("FactoMineR")
library("factoextra")
library("FactoMineR")
data(wine)
colnames(wine)
##  [1] "Label"                         "Soil"                         
##  [3] "Odor.Intensity.before.shaking" "Aroma.quality.before.shaking" 
##  [5] "Fruity.before.shaking"         "Flower.before.shaking"        
##  [7] "Spice.before.shaking"          "Visual.intensity"             
##  [9] "Nuance"                        "Surface.feeling"              
## [11] "Odor.Intensity"                "Quality.of.odour"             
## [13] "Fruity"                        "Flower"                       
## [15] "Spice"                         "Plante"                       
## [17] "Phenolic"                      "Aroma.intensity"              
## [19] "Aroma.persistency"             "Aroma.quality"                
## [21] "Attack.intensity"              "Acidity"                      
## [23] "Astringency"                   "Alcohol"                      
## [25] "Balance"                       "Smooth"                       
## [27] "Bitterness"                    "Intensity"                    
## [29] "Harmony"                       "Overall.quality"              
## [31] "Typical"

El siguiente código R realiza el MFA en los datos de los vinos utilizando los grupos: olor, visual, olor después de agitar y sabor. Estos grupos se denominan grupos activos. El grupo restante de variables - origen (el primer grupo) y juicio general (el sexto grupo) - se denominan grupos complementarios; num.grupo.sup = c(1, 6):

library(FactoMineR)
data(wine)
res.mfa <- MFA(wine,
              group = c(2, 5, 3, 10, 9, 2),
              type = c("n", "s", "s", "s", "s", "s"),
              name.group = c("origin","odor","visual", "odor.after.shaking", "taste", "overall"),
              num.group.sup = c(1, 6),
              graph = FALSE)

print(res.mfa)
## **Results of the Multiple Factor Analysis (MFA)**
## The analysis was performed on 21 individuals, described by 31 variables
## *Results are available in the following objects :
## 
##    name                 description                                           
## 1  "$eig"               "eigenvalues"                                         
## 2  "$separate.analyses" "separate analyses for each group of variables"       
## 3  "$group"             "results for all the groups"                          
## 4  "$partial.axes"      "results for the partial axes"                        
## 5  "$inertia.ratio"     "inertia ratio"                                       
## 6  "$ind"               "results for the individuals"                         
## 7  "$quanti.var"        "results for the quantitative variables"              
## 8  "$quanti.var.sup"    "results for the quantitative supplementary variables"
## 9  "$quali.var.sup"     "results for the categorical supplementary variables" 
## 10 "$summary.quanti"    "summary for the quantitative variables"              
## 11 "$summary.quali"     "summary for the categorical variables"               
## 12 "$global.pca"        "results for the global PCA"

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.mfa)
head(eig.val)
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  3.4619504        49.378382                    49.37838
## Dim.2  1.3667683        19.494446                    68.87283
## Dim.3  0.6154291         8.777969                    77.65080
## Dim.4  0.3721997         5.308747                    82.95954
## Dim.5  0.2703825         3.856511                    86.81605
## Dim.6  0.2024033         2.886912                    89.70297

La función fviz_eig() o fviz_screeplot() [paquete factoextra] se puede utilizar para dibujar el gráfico de pantalla:

fviz_screeplot(res.mfa)

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

group <- get_mfa_var(res.mfa, "group")
group
## Multiple Factor Analysis results for variable groups 
##  ===================================================
##   Name           Description                                          
## 1 "$coord"       "Coordinates"                                        
## 2 "$cos2"        "Cos2, quality of representation"                    
## 3 "$contrib"     "Contributions"                                      
## 4 "$correlation" "Correlation between groups and principal dimensions"

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

# Coordinates of groups
head(group$coord)
##                        Dim.1      Dim.2      Dim.3      Dim.4      Dim.5
## odor               0.7820738 0.61977283 0.37353451 0.17260092 0.08553276
## visual             0.8546846 0.04014481 0.01438360 0.04550736 0.02966750
## odor.after.shaking 0.9247734 0.46892047 0.18009116 0.10139051 0.11589439
## taste              0.9004187 0.23793016 0.04741982 0.05270088 0.03928784
# Cos2: quality of representation on the factore map
head(group$cos2)
##                        Dim.1       Dim.2        Dim.3       Dim.4        Dim.5
## odor               0.3799491 0.238613517 0.0866745169 0.018506155 0.0045445922
## visual             0.7284016 0.001607007 0.0002062976 0.002065011 0.0008776492
## odor.after.shaking 0.6245535 0.160582210 0.0236855692 0.007507471 0.0098089810
## taste              0.7222292 0.050429542 0.0020031144 0.002474125 0.0013749986
# Contributions to the dimensions
head(group$contrib)
##                       Dim.1     Dim.2     Dim.3    Dim.4    Dim.5
## odor               22.59055 45.345861 60.694972 46.37321 31.63399
## visual             24.68795  2.937207  2.337166 12.22660 10.97242
## odor.after.shaking 26.71250 34.308703 29.262699 27.24089 42.86313
## taste              26.00900 17.408230  7.705163 14.15930 14.53047

Para trazar los grupos se realiza lo siguiente.

fviz_mfa_var(res.mfa, "group")

Para dibujar un gráfico de barras de la contribución de los grupos a las dimensiones, se usa la función fviz_contrib():

# Contribution to the first dimension
fviz_contrib(res.mfa, "group", axes = 1)

# Contribution to the second dimension
fviz_contrib(res.mfa, "group", axes = 2)

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

quanti.var <- get_mfa_var(res.mfa, "quanti.var")
quanti.var
## Multiple Factor Analysis results for quantitative variables 
##  ===================================================
##   Name       Description                      
## 1 "$coord"   "Coordinates"                    
## 2 "$cos2"    "Cos2, quality of representation"
## 3 "$contrib" "Contributions"

Se pueden acceder a los diferentes componentes de la siguiente manera.

# Coordinates
head(quanti.var$coord)
##                                   Dim.1       Dim.2       Dim.3      Dim.4
## Odor.Intensity.before.shaking 0.5908036  0.66723783 -0.02326175  0.3287015
## Aroma.quality.before.shaking  0.8352510 -0.07539908 -0.35417877  0.1414425
## Fruity.before.shaking         0.7160259 -0.15069626 -0.53748761  0.2517063
## Flower.before.shaking         0.4387181 -0.40937751  0.63731284  0.4029075
## Spice.before.shaking          0.0380525  0.86501993  0.12795122 -0.1822298
## Visual.intensity              0.8811873  0.23833245  0.14099033 -0.2128871
##                                     Dim.5
## Odor.Intensity.before.shaking  0.05786231
## Aroma.quality.before.shaking   0.04992114
## Fruity.before.shaking          0.18981578
## Flower.before.shaking          0.12200773
## Spice.before.shaking           0.36741971
## Visual.intensity              -0.17676282
# Cos2: quality on the factore map
head(quanti.var$cos2)
##                                     Dim.1       Dim.2       Dim.3      Dim.4
## Odor.Intensity.before.shaking 0.349048863 0.445206325 0.000541109 0.10804466
## Aroma.quality.before.shaking  0.697644264 0.005685021 0.125442602 0.02000597
## Fruity.before.shaking         0.512693037 0.022709361 0.288892928 0.06335608
## Flower.before.shaking         0.192473567 0.167589944 0.406167661 0.16233443
## Spice.before.shaking          0.001447992 0.748259477 0.016371514 0.03320769
## Visual.intensity              0.776491025 0.056802358 0.019878273 0.04532093
##                                     Dim.5
## Odor.Intensity.before.shaking 0.003348047
## Aroma.quality.before.shaking  0.002492121
## Fruity.before.shaking         0.036030029
## Flower.before.shaking         0.014885886
## Spice.before.shaking          0.134997242
## Visual.intensity              0.031245096
# Contributions to the dimensions
head(quanti.var$contrib)
##                                    Dim.1      Dim.2       Dim.3     Dim.4
## Odor.Intensity.before.shaking 4.49733206 14.5296787  0.03921898 12.948424
## Aroma.quality.before.shaking  8.98882147  0.1855354  9.09194110  2.397581
## Fruity.before.shaking         6.60581103  0.7411389 20.93864000  7.592798
## Flower.before.shaking         2.47993227  5.4694372 29.43858302 19.454686
## Spice.before.shaking          0.01865671 24.4200703  1.18658923  3.979718
## Visual.intensity              7.91221841  1.4660681  1.13941864  4.295418
##                                    Dim.5
## Odor.Intensity.before.shaking  0.5523351
## Aroma.quality.before.shaking   0.4111309
## Fruity.before.shaking          5.9439566
## Flower.before.shaking          2.4557588
## Spice.before.shaking          22.2708049
## Visual.intensity               4.0764862

Correlación entre variables cuantitativas y dimensiones.

El siguiente código R traza variables cuantitativas coloreadas por grupos. La paleta de argumentos se usa para cambiar los colores del grupo . Las variables cuantitativas complementarias están en flecha discontinua y color violeta. Se usa la función repel = TRUE, para evitar la superposición de texto.

fviz_mfa_var(res.mfa, "quanti.var", palette = "jco",
col.var.sup = "violet", repel = TRUE)

Para que la trama sea más legible, podemos usar geom = c(“punto”, “texto”) en lugar de geom = c(“flecha”, “texto”). Cambiaremos también la posición de la leyenda de “derecha” a “abajo”, usando el argumento leyenda = “abajo”:

fviz_mfa_var(res.mfa, "quanti.var", palette = "jco",
col.var.sup = "violet", repel = TRUE,
geom = c("point", "text"), legend = "bottom")

El siguiente código R muestra las 20 principales categorías de variables que contribuyen a las dimensiones:

# Contributions to dimension 1
fviz_contrib(res.mfa, choice = "quanti.var", axes = 1, top = 20,
palette = "jco")

# Contributions to dimension 2
fviz_contrib(res.mfa, choice = "quanti.var", axes = 2, top = 20,
palette = "jco")

Las variables cuantitativas que más contribuyen se pueden resaltar en el diagrama de dispersión usando el argumento col.var = “contrib”. Esto produce colores degradados, que se pueden personalizar usando el argumento gradiente.cols

fviz_mfa_var(res.mfa, "quanti.var", col.var = "contrib",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
col.var.sup = "violet", repel = TRUE,
geom = c("point", "text"))

# Color by cos2 values: quality on the factor map
fviz_mfa_var(res.mfa, col.var = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
col.var.sup = "violet", repel = TRUE)

Para crear un gráfico de barras de variables cos2, se escribe lo siguiente.

fviz_cos2(res.mfa, choice = "quanti.var", axes = 1)

Para obtener los resultados de los individuos se escribe lo siguiente:

ind <- get_mfa_ind(res.mfa)
ind
## Multiple Factor Analysis results for individuals 
##  ===================================================
##   Name                      Description                      
## 1 "$coord"                  "Coordinates"                    
## 2 "$cos2"                   "Cos2, quality of representation"
## 3 "$contrib"                "Contributions"                  
## 4 "$coord.partiel"          "Partial coordinates"            
## 5 "$within.inertia"         "Within inertia"                 
## 6 "$within.partial.inertia" "Within partial inertia"
fviz_mfa_ind(res.mfa, col.ind = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE)

fviz_mfa_ind(res.mfa,
habillage = "Label", # color by groups
palette = c("#00AFBB", "#E7B800", "#FC4E07"),
addEllipses = TRUE, ellipse.type = "confidence",
repel = TRUE # Avoid text overlapping
)

Si se busca colorear individuos usando múltiples variables categóricas al mismo tiempo, use la función fviz_ellipses() [de hecho extra] de la siguiente manera:

fviz_ellipses(res.mfa, c("Label", "Soil"), repel = TRUE)

Para trazar los puntos parciales de todos los individuos, se realiza lo siguiente:

fviz_mfa_ind(res.mfa, partial = "all")

fviz_mfa_ind(res.mfa, partial = c("1DAM", "1VAU", "2ING"))

El gráfico de ejes parciales muestra la relación entre los ejes principales del MFA y los que se obtienen al analizar cada grupo mediante un PCA (para grupos de variables continuas) o un MCA (para variables cualitativas).

fviz_mfa_axes(res.mfa)