Profesor:Dr. José Manuel MAGALLANES REYES, Ph.D

  • Profesor Principal del Departamento de Ciencias Sociales, Sección de Ciencia Política y Gobierno.

  • Oficina 223 - Edificio CISEPA / ECONOMIA / CCSS

  • Telefono: (51) 1 - 6262000 anexo 4302

  • Correo Electrónico: jmagallanes@pucp.edu.pe


Análisis de Variables Latentes (I)

DOI

Muchas veces queremos saber si algun conjunto de variables representa algun concepto, al cual se le denomina técnicamente variable latente. Las técnicas son variadas, pero en esta unidad veremos análisis factorial exploratorio, y en la próxima el confirmatorio para tratar de reducir varias variables en otra u otras más simples.

En esta unidad trabajaremos con la data de:

Este ejemplo usa dos índices calculados cada uno a partir de un conjunto de indicadores. Nuestro interés no está en los índices, sino en utilizar los indicadores para producir los indices usando las técnicas que veremos.

1 Carga de datos

Los datos los hemos preparado previamente:

rm(list = ls()) # limpiar memoria
# carga
dataPreparada="https://github.com/Estadistica-AnalisisPolitico/Sesion6/raw/main/idhdemo.csv"
idhdemo=read.csv(dataPreparada)

2 Analisis Factorial Exploratorio (EFA)

El análisis factorial exploratorio (Watkins 2018), como su nombre indica, explora la data y nos entrega posibles factores que resumen cada uno un conjunto de variables. Seleccionemos la data que necesitamos:

names(idhdemo)
##  [1] "country"          "hdiRanking"       "hdi"              "hdiLife"         
##  [5] "hdiSchoolExpec"   "hdiMeanEduc"      "hdiGni"           "ideRanking"      
##  [9] "ideRegime"        "ide"              "ideElectoral"     "ideFunctioning"  
## [13] "ideParticipation" "ideCulture"       "ideLiberties"

Seleccionemos:

dontselect=c("country","hdiRanking","hdi",
             "ideRanking","ideRegime","ide")
select=setdiff(names(idhdemo),dontselect) 
theData=idhdemo[,select]

# usaremos:
library(magrittr)
head(theData,10)%>%
    rmarkdown::paged_table()

Calculemos las correlaciones entre todas las variables:

library(polycor)
corMatrix=polycor::hetcor(theData)$correlations

El objeto corMatrix guarda las correlaciones entre todas las variables:

round(corMatrix,2)
##                  hdiLife hdiSchoolExpec hdiMeanEduc hdiGni ideElectoral
## hdiLife             1.00           0.79        0.75   0.78         0.51
## hdiSchoolExpec      0.79           1.00        0.80   0.73         0.54
## hdiMeanEduc         0.75           0.80        1.00   0.71         0.50
## hdiGni              0.78           0.73        0.71   1.00         0.43
## ideElectoral        0.51           0.54        0.50   0.43         1.00
## ideFunctioning      0.65           0.66        0.60   0.62         0.85
## ideParticipation    0.51           0.57        0.53   0.45         0.80
## ideCulture          0.44           0.46        0.37   0.57         0.49
## ideLiberties        0.54           0.60        0.55   0.53         0.91
##                  ideFunctioning ideParticipation ideCulture ideLiberties
## hdiLife                    0.65             0.51       0.44         0.54
## hdiSchoolExpec             0.66             0.57       0.46         0.60
## hdiMeanEduc                0.60             0.53       0.37         0.55
## hdiGni                     0.62             0.45       0.57         0.53
## ideElectoral               0.85             0.80       0.49         0.91
## ideFunctioning             1.00             0.75       0.65         0.87
## ideParticipation           0.75             1.00       0.51         0.80
## ideCulture                 0.65             0.51       1.00         0.59
## ideLiberties               0.87             0.80       0.59         1.00

La Figura 2.1 grafica las correlaciones :

library(ggcorrplot)

ggcorrplot(corMatrix)
Matriz de Correlaciones

Figure 2.1: Matriz de Correlaciones

Si puedes ver bloques de colores en la Figura 2.1 significa que esas variables representen algunos factores.

Veamos los pasos que el EFA requiere:

  1. Verificar si los datos permiten factorizar:
library(psych)
psych::KMO(corMatrix) 
## Kaiser-Meyer-Olkin factor adequacy
## Call: psych::KMO(r = corMatrix)
## Overall MSA =  0.9
## MSA for each item = 
##          hdiLife   hdiSchoolExpec      hdiMeanEduc           hdiGni 
##             0.90             0.92             0.91             0.88 
##     ideElectoral   ideFunctioning ideParticipation       ideCulture 
##             0.84             0.93             0.96             0.87 
##     ideLiberties 
##             0.88
  1. Verificar si la matriz de correlaciones es adecuada

Aquí hay dos pruebas:

cortest.bartlett(corMatrix,n=nrow(theData))$p.value>0.05
## [1] FALSE
library(matrixcalc)

is.singular.matrix(corMatrix)
## [1] FALSE
  1. Determinar en cuantos factores o variables latentes podríamos redimensionar la data: En este caso, la función fa.parallel nos dará la sugerencia:
fa.parallel(theData, fa = 'fa',correct = T,plot = F)
## Parallel analysis suggests that the number of factors =  2  and the number of components =  NA

Se sugieren 2, lo esperado en teoría, sigamos.

  1. Redimensionar a número menor de factores
  • Resultado inicial:
library(GPArotation)
resfa <- fa(theData,
            nfactors = 2,
            cor = 'mixed',
            rotate = "varimax", #oblimin?
            fm="minres")
print(resfa$loadings)
## 
## Loadings:
##                  MR1   MR2  
## hdiLife          0.307 0.836
## hdiSchoolExpec   0.368 0.811
## hdiMeanEduc      0.316 0.782
## hdiGni           0.283 0.813
## ideElectoral     0.906 0.249
## ideFunctioning   0.801 0.470
## ideParticipation 0.768 0.331
## ideCulture       0.498 0.382
## ideLiberties     0.901 0.334
## 
##                  MR1   MR2
## SS loadings    3.522 3.280
## Proportion Var 0.391 0.364
## Cumulative Var 0.391 0.756
  • Resultado mejorado (solo apropiado si hay más de un factor):
print(resfa$loadings,cutoff = 0.5)
## 
## Loadings:
##                  MR1   MR2  
## hdiLife                0.836
## hdiSchoolExpec         0.811
## hdiMeanEduc            0.782
## hdiGni                 0.813
## ideElectoral     0.906      
## ideFunctioning   0.801      
## ideParticipation 0.768      
## ideCulture                  
## ideLiberties     0.901      
## 
##                  MR1   MR2
## SS loadings    3.522 3.280
## Proportion Var 0.391 0.364
## Cumulative Var 0.391 0.756

Cuando logramos que cada variable se vaya a un factor, tenemos una estructura simple.

  • Resultado visual: El resultado lo podemos ver de manera gráfica en la Figura 2.2.
fa.diagram(resfa,main = "Resultados del EFA")
Variables organizadas en Factores

Figure 2.2: Variables organizadas en Factores

  1. Evaluando Resultado obtenido:
  • ¿Qué variables aportaron más a los factores?
sort(resfa$communality)
##       ideCulture ideParticipation      hdiMeanEduc           hdiGni 
##        0.3941682        0.6993302        0.7119301        0.7405067 
##          hdiLife   hdiSchoolExpec   ideFunctioning     ideElectoral 
##        0.7933223        0.7936103        0.8629055        0.8835971 
##     ideLiberties 
##        0.9226321
  • ¿Qué variables contribuyen a la construcción de más de un factor?
sort(resfa$complexity)
##     ideElectoral           hdiGni          hdiLife     ideLiberties 
##         1.150198         1.238563         1.265339         1.270410 
##      hdiMeanEduc ideParticipation   hdiSchoolExpec   ideFunctioning 
##         1.317113         1.358907         1.395523         1.614353 
##       ideCulture 
##         1.874466
  • ¿Tucker Lewis > 0.9?
resfa$TLI
## [1] 0.9263416
  • ¿RMS cerca a cero?
resfa$rms
## [1] 0.0346878

¿RMSEA cerca a cero?

resfa$RMSEA
##      RMSEA      lower      upper confidence 
##  0.1319641  0.1014027  0.1651144  0.9000000
  • ¿BIC?
resfa$BIC
## [1] -23.30257

3 Obtención de índices

Podemos calcular dos indices que resuman los dos factores encontrados.

as.data.frame(resfa$scores)%>%head()
##          MR1         MR2
## 1 -1.6803401 -0.83207114
## 2  0.4219025  0.17017645
## 3 -0.8499736  0.38447261
## 4 -0.3312612 -0.83527332
## 5  0.6137348  0.55689007
## 6  0.1404683  0.08167183

Les daremos por nombre ‘ide_efa’ y ‘idh_efa’ a esas dos columnas. Dado que tenemos el indice de democracia en la data original, comparémoslo con el recién calculado, via el scatterplot de la Figura 3.1.

idhdemo$ide_efa=resfa$scores[,1]
idhdemo$idh_efa=resfa$scores[,2]

ggplot(data=idhdemo,aes(x=ide,y=ide_efa)) + geom_point() + theme_minimal() + labs(x="Indice de Democracia (original)", y="Indice de Democracia EFA")
Comparando Indice de Democracia con el Score obtenido en EFA

Figure 3.1: Comparando Indice de Democracia con el Score obtenido en EFA

Nota que los rangos de los valores en la Figura 3.1 no son los mismos. Podemos cambiar tales rangos:

# normalizando
library(BBmisc)
efa_scores_norm=normalize(resfa$scores, 
                       method = "range", 
                       margin=2, # by column
                       range = c(0, 10))

# nuevas variables
idhdemo$ide_efa_norm=efa_scores_norm[,1]
idhdemo$idh_efa_norm=efa_scores_norm[,2]

La Figura 3.2 muestra las nuevas variables para IDE.

# graficando

ggplot(data=idhdemo,aes(x=ide,y=ide_efa_norm)) + geom_point() + theme_minimal() + labs(x="Indice de Democracia (original)", y="Indice de Democracia EFA (cambiado)")
Comparación Indice de Democracia con Score EFA con rangos coincidentes

Figure 3.2: Comparación Indice de Democracia con Score EFA con rangos coincidentes

La Figura 3.3 muestra las nuevas variables para IDH.

ggplot(data=idhdemo,aes(x=hdi,y=idh_efa_norm)) + geom_point() + theme_minimal() + labs(x="Indice de Desarrollo Humano (original)", y="Indice de Desarrollo Humano EFA (cambiado)")
Comparación Indice de Desarrollo Humano con Score EFA con rangos coincidentes

Figure 3.3: Comparación Indice de Desarrollo Humano con Score EFA con rangos coincidentes

Queda a esta altura preguntarse:

  • ¿Qué ventaja hay entre calcular un índice como un resultado aritmético simple a partir de los indicadores versus usar análisis factorial con el mismo propósito?

  • Finalmente, nota este resultado:

cor(idhdemo$ide_efa_norm,idhdemo$idh_efa_norm)
## [1] 0.0632508

¿Qué crees que esto significa? ¿Qué relación tiene el Análisis factorial con la regresión? ¿Puede servir de algo en particular?

Referencias

Watkins, Marley W. 2018. “Exploratory Factor Analysis: A Guide to Best Practice.” Journal of Black Psychology 44 (3): 219–46. https://doi.org/10.1177/0095798418771807.