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)
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.
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)
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)
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:
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
Aquí hay dos pruebas:
cortest.bartlett(corMatrix,n=nrow(theData))$p.value>0.05
## [1] FALSE
library(matrixcalc)
is.singular.matrix(corMatrix)
## [1] FALSE
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.
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
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.
fa.diagram(resfa,main = "Resultados del EFA")
Figure 2.2: Variables organizadas en 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
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
resfa$TLI
## [1] 0.9263416
resfa$rms
## [1] 0.0346878
¿RMSEA cerca a cero?
resfa$RMSEA
## RMSEA lower upper confidence
## 0.1319641 0.1014027 0.1651144 0.9000000
resfa$BIC
## [1] -23.30257
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")
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)")
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)")
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?