Rows: 768 Columns: 9
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
dbl (9): Pregnancies, Glucose, BloodPressure, SkinThickness, Insulin, BMI, D...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
En este caso como observamos no existen valores perdidos por lo que nuestra base de datos es adecuada para seguir con nuestro análisis.
# Renombrar columnas ya que en l base original están en inglescolnames(diabetes) <-c("Embarazos", "Glucosa", "Presión arterial", "Grosor de la piel", "Insulina", "IMC", "Función de pedigrí de diabetes", "Edad", "Resultado")
Embarazos Glucosa Presión arterial
Embarazos 1.00000000 0.12945867 0.14128198
Glucosa 0.12945867 1.00000000 0.15258959
Presión arterial 0.14128198 0.15258959 1.00000000
Grosor de la piel -0.08167177 0.05732789 0.20737054
Insulina -0.07353461 0.33135711 0.08893338
IMC 0.01768309 0.22107107 0.28180529
Función de pedigrí de diabetes -0.03352267 0.13733730 0.04126495
Edad 0.54434123 0.26351432 0.23952795
Grosor de la piel Insulina IMC
Embarazos -0.08167177 -0.07353461 0.01768309
Glucosa 0.05732789 0.33135711 0.22107107
Presión arterial 0.20737054 0.08893338 0.28180529
Grosor de la piel 1.00000000 0.43678257 0.39257320
Insulina 0.43678257 1.00000000 0.19785906
IMC 0.39257320 0.19785906 1.00000000
Función de pedigrí de diabetes 0.18392757 0.18507093 0.14064695
Edad -0.11397026 -0.04216295 0.03624187
Función de pedigrí de diabetes Edad
Embarazos -0.03352267 0.54434123
Glucosa 0.13733730 0.26351432
Presión arterial 0.04126495 0.23952795
Grosor de la piel 0.18392757 -0.11397026
Insulina 0.18507093 -0.04216295
IMC 0.14064695 0.03624187
Función de pedigrí de diabetes 1.00000000 0.03356131
Edad 0.03356131 1.00000000
En la matriz de correlación vemos que la mayoría de variables no tienen correlación entes ellas la única correlación que se puede considerar “correlación positiva moderada” es Edad con Embarazos ya que su correlación es de 0.54 lo que nos dice que si una variable aumenta la otra también aumenta por lo que se dice que a mayor edad mayor es la probabilidad de haber tenido más de un embarazo.
Las demás variables poseen correlaciones débiles tanto como positivo como negativo.
library(corrplot)
Warning: package 'corrplot' was built under R version 4.5.0
corrplot 0.95 loaded
rosa_palette <-colorRampPalette(c("#7B1FA2", "#E91E63", "#F8BBD0"))(200)# Graficar la matriz de correlación con tonos rosascorrplot(cor_matrix_diab,method ="color",col = rosa_palette,tl.cex =0.7,addCoef.col ="black")
Al observar este mapa o gráfico de correlación, lo que se dijo anteriormente es lo mismo solo que de una manera más entendible. Edad con Embarazo posee una correlación moderada (r=0.54), IMC con Grosor de la piel posee una correlación débil (r=0.39) ya que está por debajo del 0.5 lo que significa que a mayor índice de masa corporal tiende a poseer más grosor de la piel, Glucosa con Edad poseen una correlación baja (r=0.26) esto significa que a mayor edad tiene a aumentar la glucosa, La Insulina con Grosor de la piel tiene una correlación baja (r=0.44) esto se puede asociar que con acumulación de grasa y la Presión arterial con Edad poseen una correlación baja (0.24) esto se puede asociar con la vejez y que eso aumenta la presión arterial.
Prueba de adecuación KMO
library(psych)
Warning: package 'psych' was built under R version 4.3.2
KMO(cor_matrix_diab)
Kaiser-Meyer-Olkin factor adequacy
Call: KMO(r = cor_matrix_diab)
Overall MSA = 0.59
MSA for each item =
Embarazos Glucosa
0.56 0.56
Presión arterial Grosor de la piel
0.69 0.57
Insulina IMC
0.57 0.65
Función de pedigrí de diabetes Edad
0.77 0.55
Según las directrices de Kaiser (1974), un punto de corte sugerido para determinar la factorabilidad de los datos de muestro es KMO ≥ 60. El KMO total en este caso es de 0.59, lo que indica que, con base en esta prueba, podamos realizar un análisis factorial ya que aproximándolo nos da 0.60 por lo que si podemos hacer un AFE ya que es aceptable.
Prueba de Bartlett
cortest.bartlett(cor_matrix_diab, n =nrow(diabetes_escalado))
Si él es menor a 0.05 (p<0.05) nuestro AFE es adecuado en este caso nuestro p_value fue de 1.25755e-181 lo que quiere decir que nuestro p_value es adecuado y podemos seguir con nuestro Análisis Factorial Exploratorio.
Aplicar nuestro Análisis Factorial
num_factores_sin_rotar <-fa(diabetes_escalado, nfactors =2, rotate ="none", fm ="ml")print(num_factores_sin_rotar)
Factor Analysis using method = ml
Call: fa(r = diabetes_escalado, nfactors = 2, rotate = "none", fm = "ml")
Standardized loadings (pattern matrix) based upon correlation matrix
ML2 ML1 h2 u2 com
Embarazos -0.04 0.58 0.34 0.66 1.0
Glucosa 0.31 0.28 0.18 0.82 2.0
Presión arterial 0.32 0.26 0.17 0.83 1.9
Grosor de la piel 0.70 -0.13 0.50 0.50 1.1
Insulina 0.58 -0.05 0.34 0.66 1.0
IMC 0.53 0.05 0.28 0.72 1.0
Función de pedigrí de diabetes 0.28 0.03 0.08 0.92 1.0
Edad 0.00 0.93 0.87 0.13 1.0
ML2 ML1
SS loadings 1.38 1.38
Proportion Var 0.17 0.17
Cumulative Var 0.17 0.34
Proportion Explained 0.50 0.50
Cumulative Proportion 0.50 1.00
Mean item complexity = 1.3
Test of the hypothesis that 2 factors are sufficient.
df null model = 28 with the objective function = 1.24 with Chi Square = 948.23
df of the model are 13 and the objective function was 0.18
The root mean square of the residuals (RMSR) is 0.05
The df corrected root mean square of the residuals is 0.08
The harmonic n.obs is 768 with the empirical chi square 128.47 with prob < 4.2e-21
The total n.obs was 768 with Likelihood Chi Square = 134.88 with prob < 2.2e-22
Tucker Lewis Index of factoring reliability = 0.714
RMSEA index = 0.11 and the 90 % confidence intervals are 0.094 0.128
BIC = 48.51
Fit based upon off diagonal values = 0.94
Measures of factor score adequacy
ML2 ML1
Correlation of (regression) scores with factors 0.83 0.94
Multiple R square of scores with factors 0.69 0.88
Minimum correlation of possible factor scores 0.38 0.76
Para la variable Embarazo ML1 está asociado moderadamente y explica un 34% de su varianza.
Para la variable Glucosa débil la carga en ambos factores ya que solo un 17.8% de su varianza es explicada.
Para la variable Presión arterial la relación es muy débil.
Para la variable Grosor de la piel esta asociad fuertemente a ML2. Bien explicada.
Para la variable Insulina está asociada a ML2. Aceptable.
Para la variable IMC está asociada moderadamente a ML2.
Para la variable Función de pedigrí tiene baja carga y baja comunalidad por lo que se podría eliminar.
Para la variable Edad tiene fuerte asociación con ML1 eso significa que existe excelente comunalidad.
ML1 representa un factor que está relacionado con edad y embarazos.
ML2 representa un factor que está relacionado con grosor de piel, insulina e IMC.
Determinar número de factores
# Scree plot y eigenvaloresscree(cor(diabetes))
Para determinar el número de factores, observamos los puntos sin relleno y al comparar la línea que está en 1 que es la regla de Kaiser, tomamos los factores que están por encima de él, en este caso es 1 el que sobre pasa a 1 pero tomaremos 2 para mayor análisis por son los únicos factores con eigenvalores mayores a 1. Los puntos rellenados de negro nos ayudarían para un análisis de componentes principales.
fa.parallel(diabetes_escalado, fa ="fa", fm ="ml", n.iter =100)
Parallel analysis suggests that the number of factors = 3 and the number of components = NA
Para determinar el número de factores, los identificamos comparando la línea azul que son los datos reales con las líneas rojas que son los datos que son simulados. Al visualizar el gráfico se toman 2 factores ya que el tercero toca lo que es la línea imaginaria de 1 que observamos en el grafico anterior.
Matriz de cargas factoriales
mfac <-fa(diabetes_escalado, nfactors =2, rotate ="none", fm ="ml")print(mfac$loadings)
Loadings:
ML2 ML1
Embarazos 0.582
Glucosa 0.315 0.282
Presión arterial 0.319 0.257
Grosor de la piel 0.698 -0.125
Insulina 0.578
IMC 0.529
Función de pedigrí de diabetes 0.280
Edad 0.933
ML2 ML1
SS loadings 1.382 1.376
Proportion Var 0.173 0.172
Cumulative Var 0.173 0.345
Las cargas factoriales nos indican cuanto existe la correlación cada variable con cada uno de los factores.
Para ML1: Para este factor las variables más dominantes son Edad con un valor de 0.933, Embarazos con un valor de 0.582, la variable Glucosa con un valor de 0.282 y la variable Presión arterial con un valor de 0.257
Para ML2: Para este factor las variables que dominan son Grosor de la piel (0.698), Insulina (0.578), IMC (0.529) y la Glucosa (0.315)
Cada factor explica un 17.3% de lo que es la varianza.
Estos ambos explican un 34.5% de la varianza total de los datos.
Varimax
# Rotación Varimaxmod_rot <-fa(diabetes_escalado, nfactors =2, rotate ="varimax", fm ="ml")print(mod_rot$loadings)
Loadings:
ML2 ML1
Embarazos 0.581
Glucosa 0.310 0.288
Presión arterial 0.315 0.263
Grosor de la piel 0.700 -0.113
Insulina 0.579
IMC 0.528
Función de pedigrí de diabetes 0.280
Edad 0.933
ML2 ML1
SS loadings 1.380 1.378
Proportion Var 0.172 0.172
Cumulative Var 0.172 0.345
Para factor 1: La variable Edad tiene un valor de 0.933 y es muy fuerte, la variable Embarazos con un valor fuerte de 0.581, la variable Glucosa con un valor ligero de 0.288 y la variable Presión arterial con un valor ligero de 0.263
El factor 2 con variables con mayores cargas son: Grosor de la piel con 0.700 (fuerte), Insulina con 0.579 (fuerte), IMC con 0.528 (fuerte), Presión arterial y Glucosa son moderadas con 0.31 y Función de pedigrí de diabetes con un valor ligero de 0.28.
Cada factor explica aproximadamente un 17.2% de lo que es la varianza total, ambos factores juntos explican el 34.4%.
print(mod_rot)
Factor Analysis using method = ml
Call: fa(r = diabetes_escalado, nfactors = 2, rotate = "varimax", fm = "ml")
Standardized loadings (pattern matrix) based upon correlation matrix
ML2 ML1 h2 u2 com
Embarazos -0.05 0.58 0.34 0.66 1.0
Glucosa 0.31 0.29 0.18 0.82 2.0
Presión arterial 0.31 0.26 0.17 0.83 1.9
Grosor de la piel 0.70 -0.11 0.50 0.50 1.1
Insulina 0.58 -0.04 0.34 0.66 1.0
IMC 0.53 0.06 0.28 0.72 1.0
Función de pedigrí de diabetes 0.28 0.04 0.08 0.92 1.0
Edad -0.02 0.93 0.87 0.13 1.0
ML2 ML1
SS loadings 1.38 1.38
Proportion Var 0.17 0.17
Cumulative Var 0.17 0.34
Proportion Explained 0.50 0.50
Cumulative Proportion 0.50 1.00
Mean item complexity = 1.3
Test of the hypothesis that 2 factors are sufficient.
df null model = 28 with the objective function = 1.24 with Chi Square = 948.23
df of the model are 13 and the objective function was 0.18
The root mean square of the residuals (RMSR) is 0.05
The df corrected root mean square of the residuals is 0.08
The harmonic n.obs is 768 with the empirical chi square 128.47 with prob < 4.2e-21
The total n.obs was 768 with Likelihood Chi Square = 134.88 with prob < 2.2e-22
Tucker Lewis Index of factoring reliability = 0.714
RMSEA index = 0.11 and the 90 % confidence intervals are 0.094 0.128
BIC = 48.51
Fit based upon off diagonal values = 0.94
Measures of factor score adequacy
ML2 ML1
Correlation of (regression) scores with factors 0.83 0.94
Multiple R square of scores with factors 0.69 0.88
Minimum correlation of possible factor scores 0.38 0.76
El factor ML1: Las variables que más se asocian es la Edad con un valor de 0.93 y Embarazos con un valor de 0.58
El factor ML2: Las variables más asociadas son el Grosor de piel con un valor de 0.70, la variable Insulina con un valor de 0.58 y IMC con un valor de 0.53
Factores con rotación
library(psych)fa.diagram(mod_rot)
Las variables asociadas fuertemente para el factor 1 (ML1) son: Edad con una carga de 0.9 y Embarazos con una carga de 0.6
Las variables asociadas fuertemente para el factor 2 (ML2) son: Grosor de la piel con una carga de 0.7, Insulina con una carga de 0.6, IMC con una carga de 0.5, Presión arterial con una carga de 0.3 y Glucosa con una carga de 0.3.
Análisis Factorial Exploratorio en Python
Cargar los datos
import pandas as pddiabetes = pd.read_csv("C:/Users/MINEDUCYT/Desktop/CICLOI_2025/SeminarioI/diabetes.csv")print(diabetes.head(10))
# Asignar nuevos nombres a las columnas de la base de datosdiabetes.columns = ["Embarazos", "Glucosa", "Presión arterial", "Grosor de la piel", "Insulina", "IMC", "Función de pedigrí de diabetes", "Edad", "Resultado"]print(diabetes.head())
# Seleccionamos las primeras 8 columnas ya que la ultima no nos será útidiabetes_seleccionada = diabetes.iloc[:, 0:8]print(diabetes_seleccionada.head(10))
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
import numpy as npimport pandas as pdfrom factor_analyzer import FactorAnalyzerfrom sklearn.preprocessing import StandardScaler# Obtener las cargas factoriales después de la rotaciónloadings_rot = fa.loadings_# Imprimir las cargas factoriales después de la rotaciónprint(loadings_rot)
import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport networkx as nxfrom factor_analyzer import FactorAnalyzerfrom sklearn.preprocessing import StandardScaler# Obtener nombres reales de las variablesvar_names = diabetes.columns.tolist()[:loadings_rot.shape[0]]# Crear un gráfico de diagrama usando NetworkXG = nx.Graph()# Agregar nodos para los factoresfor i inrange(loadings_rot.shape[1]): G.add_node(f"Factor {i+1}", pos=(i, 1))# Agregar nodos para las variables con sus nombres realesfor i, var inenumerate(var_names): G.add_node(var, pos=(i, 0))# Agregar las aristas entre variables y factores basadas en las cargas factorialesthreshold =0.3# Umbral para mostrar relaciones significativasfor i, var inenumerate(var_names):for j inrange(loadings_rot.shape[1]):ifabs(loadings_rot[i, j]) > threshold: G.add_edge(var, f"Factor {j+1}", weight=loadings_rot[i, j])# Obtener posiciones de los nodospos = nx.get_node_attributes(G, 'pos')# Dibujar el gráficoplt.figure(figsize=(12, 6))pos = nx.spring_layout(G, seed=42) # Layout automático reproduciblenx.draw(G, pos, with_labels=True, node_size=2000, node_color='lightgreen', font_size=10, font_weight='bold', edge_color='gray')# Mostrar el gráficoplt.title("Diagrama de Cargas Factoriales (Varimax)")plt.show()