Curso
El análisis factorial (FA) es un método de análisis exploratorio de datos que se utiliza para buscar factores subyacentes o variables latentes influyentes a partir de un conjunto de variables observadas. Ayuda a interpretar los datos al reducir el número de variables. Extrae la varianza común máxima de todas las variables y la condensa en una puntuación común.
El análisis factorial se usa ampliamente en investigación de mercados, publicidad, psicología, finanzas e investigación de operaciones. Quienes investigan el mercado lo emplean para identificar clientes sensibles al precio, detectar rasgos de marca que influyen en la elección del consumidor y comprender los criterios de selección de canales en la distribución.
Análisis factorial
El análisis factorial es un modelo estadístico lineal. Se utiliza para explicar la varianza entre las variables observadas y condensar un conjunto de variables observadas en variables no observadas llamadas factores. Las variables observadas se modelan como una combinación lineal de factores y términos de error (Fuente). Un factor o variable latente se asocia con múltiples variables observadas que comparten patrones de respuesta comunes. Cada factor explica una cantidad concreta de varianza en las variables observadas. Ayuda a interpretar los datos al reducir el número de variables.
El análisis factorial investiga si varias variables de interés X1, X2, …, Xl están linealmente relacionadas con un número menor de factores no observables F1, F2, …, Fk.
Fuente: esta imagen es una recreación de una imagen que encontré en unos apuntes de análisis factorial. Ofrece una visión completa del método.
Supuestos:
- No hay valores atípicos en los datos.
- El tamaño muestral debe ser mayor que el número de factores.
- No debe existir multicolinealidad perfecta.
- No debe haber homocedasticidad entre las variables.
Tipos de análisis factorial
- Análisis factorial exploratorio (EFA): es el enfoque más popular entre investigadores sociales y de gestión. Su supuesto básico es que cualquier variable observada puede estar directamente asociada con cualquier factor.
- Análisis factorial confirmatorio (CFA): su supuesto básico es que cada factor está asociado con un conjunto concreto de variables observadas. El CFA contrasta si los datos se ajustan a lo esperado teóricamente.
¿Cómo funciona el análisis factorial?
El objetivo principal del análisis factorial es reducir el número de variables observadas y encontrar variables no observadas. Estas variables latentes ayudan a quienes investigan el mercado a sacar conclusiones de una encuesta. Esta conversión de variables observadas a no observadas se logra en dos pasos:
- Extracción de factores: en este paso se seleccionan el número de factores y el método de extracción usando técnicas de partición de varianza como el análisis de componentes principales y el análisis de factores comunes.
- Rotación de factores: en este paso, la rotación intenta transformar los factores para que sean no correlacionados; el objetivo es mejorar la interpretabilidad. Existen varios métodos de rotación, como: Varimax, Quartimax y Promax.
Terminología
¿Qué es un factor?
Un factor es una variable latente que describe la asociación entre varias variables observadas. El número máximo de factores es igual al de variables observadas. Cada factor explica cierta varianza en las variables observadas. Los factores con menor varianza se descartan. A los factores también se les conoce como variables latentes, ocultas, no observadas o hipotéticas.
¿Qué son las cargas factoriales?
La matriz de cargas factoriales muestra la relación de cada variable con el factor subyacente. Indica el coeficiente de correlación entre la variable observada y el factor, y cuánta varianza explican las variables observadas.
¿Qué son los valores propios (eigenvalues)?
Los valores propios representan la varianza que explica cada factor respecto a la varianza total. También se les llama raíces características.
¿Qué son las comunalidades?
Las comunalidades son la suma de los cuadrados de las cargas de cada variable. Representan la varianza común. Oscilan entre 0 y 1; cuanto más cerca de 1, mayor varianza común.
¿Qué es la rotación de factores?
La rotación es una herramienta para mejorar la interpretación del análisis factorial. Puede ser ortogonal u oblicua. Redistribuye las comunalidades con un patrón de cargas más claro.
Elección del número de factores
El criterio de Kaiser es un enfoque analítico basado en seleccionar los factores que explican una mayor proporción de varianza. El valor propio es un buen criterio para determinar cuántos factores retener. Por lo general, se conservan los factores con valores propios mayores que 1.
El enfoque gráfico se basa en la representación visual de los valores propios de los factores, también llamada scree plot o gráfico de sedimentación. Este gráfico ayuda a determinar el número de factores donde la curva hace un “codo”.
Análisis factorial vs. análisis de componentes principales
- Los componentes del PCA explican la máxima varianza, mientras que el análisis factorial explica la covarianza en los datos.
- Los componentes del PCA son totalmente ortogonales entre sí, mientras que el análisis factorial no exige ortogonalidad entre factores.
- Un componente del PCA es una combinación lineal de variables observadas; en FA, las variables observadas son combinaciones lineales de variables no observadas (factores).
- Los componentes del PCA suelen ser poco interpretables. En FA, los factores subyacentes pueden etiquetarse e interpretarse.
- El PCA es un método de reducción de dimensionalidad, mientras que el análisis factorial es un enfoque basado en variables latentes.
- El PCA es un tipo de análisis factorial. El PCA es observacional, mientras que el FA es una técnica de modelado.
Análisis factorial en Python con el paquete factor_analyzer
Importar las librerías necesarias
# Import required libraries
import pandas as pd
from sklearn.datasets import load_iris
from factor_analyzer import FactorAnalyzer
import matplotlib.pyplot as plt
Cargar los datos
Vamos a realizar análisis factorial sobre BFI (conjunto de datos de un proyecto de evaluación de personalidad), recogido con una escala de respuesta de 6 puntos: 1 Muy inexacto, 2 Moderadamente inexacto, 3 Ligeramente inexacto, 4 Ligeramente exacto, 5 Moderadamente exacto y 6 Muy exacto. También puedes descargar este conjunto de datos desde el siguiente enlace: https://vincentarelbundock.github.io/Rdatasets/datasets.html
df= pd.read_csv("bfi.csv")
Preprocesar los datos
df.columns
Index(['A1', 'A2', 'A3', 'A4', 'A5', 'C1', 'C2', 'C3', 'C4', 'C5', 'E1', 'E2',
'E3', 'E4', 'E5', 'N1', 'N2', 'N3', 'N4', 'N5', 'O1', 'O2', 'O3', 'O4',
'O5', 'gender', 'education', 'age'],
dtype='object')
# Dropping unnecessary columns
df.drop(['gender', 'education', 'age'],axis=1,inplace=True)
# Dropping missing values rows
df.dropna(inplace=True)
df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2436 entries, 0 to 2799
Data columns (total 25 columns):
A1 2436 non-null float64
A2 2436 non-null float64
A3 2436 non-null float64
A4 2436 non-null float64
A5 2436 non-null float64
C1 2436 non-null float64
C2 2436 non-null float64
C3 2436 non-null float64
C4 2436 non-null float64
C5 2436 non-null float64
E1 2436 non-null float64
E2 2436 non-null float64
E3 2436 non-null float64
E4 2436 non-null float64
E5 2436 non-null float64
N1 2436 non-null float64
N2 2436 non-null float64
N3 2436 non-null float64
N4 2436 non-null float64
N5 2436 non-null float64
O1 2436 non-null float64
O2 2436 non-null int64
O3 2436 non-null float64
O4 2436 non-null float64
O5 2436 non-null float64
dtypes: float64(24), int64(1)
memory usage: 494.8 KB
df.head()
| A1 | A2 | A3 | A4 | A5 | C1 | C2 | C3 | C4 | C5 | ... | N1 | N2 | N3 | N4 | N5 | O1 | O2 | O3 | O4 | O5 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2.0 | 4.0 | 3.0 | 4.0 | 4.0 | 2.0 | 3.0 | 3.0 | 4.0 | 4.0 | ... | 3.0 | 4.0 | 2.0 | 2.0 | 3.0 | 3.0 | 6 | 3.0 | 4.0 | 3.0 |
| 1 | 2.0 | 4.0 | 5.0 | 2.0 | 5.0 | 5.0 | 4.0 | 4.0 | 3.0 | 4.0 | ... | 3.0 | 3.0 | 3.0 | 5.0 | 5.0 | 4.0 | 2 | 4.0 | 3.0 | 3.0 |
| 2 | 5.0 | 4.0 | 5.0 | 4.0 | 4.0 | 4.0 | 5.0 | 4.0 | 2.0 | 5.0 | ... | 4.0 | 5.0 | 4.0 | 2.0 | 3.0 | 4.0 | 2 | 5.0 | 5.0 | 2.0 |
| 3 | 4.0 | 4.0 | 6.0 | 5.0 | 5.0 | 4.0 | 4.0 | 3.0 | 5.0 | 5.0 | ... | 2.0 | 5.0 | 2.0 | 4.0 | 1.0 | 3.0 | 3 | 4.0 | 3.0 | 5.0 |
| 4 | 2.0 | 3.0 | 3.0 | 4.0 | 5.0 | 4.0 | 4.0 | 5.0 | 3.0 | 2.0 | ... | 2.0 | 3.0 | 4.0 | 4.0 | 3.0 | 3.0 | 3 | 4.0 | 3.0 | 3.0 |
5 filas × 25 columnas
Prueba de adecuación
Antes de realizar el análisis factorial, necesitas evaluar la «factorabilidad» de tu conjunto de datos. Factorabilidad significa: «¿podemos encontrar factores en el conjunto de datos?». Hay dos métodos para comprobar la factorabilidad o la adecuación muestral:
- Prueba de esfericidad de Bartlett
- Prueba de Kaiser-Meyer-Olkin
La prueba de Bartlett de esfericidad comprueba si las variables observadas están intercorrelacionadas comparando la matriz de correlaciones observada con la matriz identidad. Si la prueba no es estadísticamente significativa, no deberías aplicar análisis factorial.
from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity
chi_square_value,p_value=calculate_bartlett_sphericity(df)
chi_square_value, p_value
(18146.065577234807, 0.0)
En esta prueba de Bartlett, el p-valor es 0. La prueba resulta significativa, lo que indica que la matriz de correlaciones observada no es una matriz identidad.
La prueba de Kaiser-Meyer-Olkin (KMO) mide la idoneidad de los datos para el análisis factorial. Determina la adecuación para cada variable observada y para el modelo completo. KMO estima la proporción de varianza entre todas las variables observadas. Una proporción mayor es más adecuada para el análisis factorial. Los valores de KMO oscilan entre 0 y 1. Un KMO inferior a 0,6 se considera inadecuado.
from factor_analyzer.factor_analyzer import calculate_kmo
kmo_all,kmo_model=calculate_kmo(df)
kmo_model
0.8486452309468382
El KMO global de nuestros datos es 0,84, lo cual es excelente. Este valor indica que puedes continuar con el análisis factorial previsto.
Elección del número de factores
Para elegir cuántos factores retener, puedes usar el criterio de Kaiser y el scree plot. Ambos se basan en los valores propios.
# Create factor analysis object and perform factor analysis
fa = FactorAnalyzer()
fa.analyze(df, 25, rotation=None)
# Check Eigenvalues
ev, v = fa.get_eigenvalues()
ev
| Original_Eigenvalues | |
|---|---|
| 0 | 5.134311 |
| 1 | 2.751887 |
| 2 | 2.142702 |
| 3 | 1.852328 |
| 4 | 1.548163 |
| 5 | 1.073582 |
| 6 | 0.839539 |
| 7 | 0.799206 |
| 8 | 0.718989 |
| 9 | 0.688089 |
| 10 | 0.676373 |
| 11 | 0.651800 |
| 12 | 0.623253 |
| 13 | 0.596563 |
| 14 | 0.563091 |
| 15 | 0.543305 |
| 16 | 0.514518 |
| 17 | 0.494503 |
| 18 | 0.482640 |
| 19 | 0.448921 |
| 20 | 0.423366 |
| 21 | 0.400671 |
| 22 | 0.387804 |
| 23 | 0.381857 |
| 24 | 0.262539 |
Aquí se ve que solo para 6 factores los valores propios son mayores que 1. Esto significa que deberíamos elegir 6 factores (variables latentes).
# Create scree plot using matplotlib
plt.scatter(range(1,df.shape[1]+1),ev)
plt.plot(range(1,df.shape[1]+1),ev)
plt.title('Scree Plot')
plt.xlabel('Factors')
plt.ylabel('Eigenvalue')
plt.grid()
plt.show()
El scree plot dibuja un punto y una línea para cada factor y su valor propio. El número de valores propios mayores que 1 se toma como número de factores.
Aquí se ve que solo para 6 factores los valores propios son mayores que 1. Esto significa que deberíamos elegir 6 factores (variables latentes).
Realizar el análisis factorial
# Create factor analysis object and perform factor analysis
fa = FactorAnalyzer()
fa.analyze(df, 6, rotation="varimax")
fa.loadings
| Factor1 | Factor2 | Factor3 | Factor4 | Factor5 | Factor6 | |
|---|---|---|---|---|---|---|
| A1 | 0.040783 | 0.095220 | 0.048734 | -0.113057 | -0.530987 | 0.161216 |
| A2 | 0.235538 | 0.033131 | 0.133714 | 0.063734 | 0.661141 | -0.006244 |
| A3 | 0.343008 | -0.009621 | 0.121353 | 0.033990 | 0.605933 | 0.160106 |
| A4 | 0.219717 | -0.081518 | 0.235140 | -0.125338 | 0.404594 | 0.086356 |
| A5 | 0.414458 | -0.149616 | 0.106382 | 0.030977 | 0.469698 | 0.236519 |
| C1 | 0.077248 | -0.004358 | 0.554582 | 0.190124 | 0.007511 | 0.095035 |
| C2 | 0.038370 | 0.068330 | 0.674545 | 0.087593 | 0.057055 | 0.152775 |
| C3 | 0.031867 | -0.039994 | 0.551164 | -0.011338 | 0.101282 | 0.008996 |
| C4 | -0.066241 | 0.216283 | -0.638475 | -0.143846 | -0.102617 | 0.318359 |
| C5 | -0.180812 | 0.284187 | -0.544838 | 0.025837 | -0.059955 | 0.132423 |
| E1 | -0.590451 | 0.022280 | 0.053915 | -0.071205 | -0.130851 | 0.156583 |
| E2 | -0.684578 | 0.233624 | -0.088497 | -0.045561 | -0.116716 | 0.115065 |
| E3 | 0.556774 | -0.000895 | 0.103390 | 0.241180 | 0.179396 | 0.267291 |
| E4 | 0.658395 | -0.136788 | 0.113798 | -0.107808 | 0.241143 | 0.158513 |
| E5 | 0.507535 | 0.034490 | 0.309813 | 0.200821 | 0.078804 | 0.008747 |
| N1 | 0.068011 | 0.805806 | -0.051264 | -0.074977 | -0.174849 | -0.096266 |
| N2 | 0.022958 | 0.789832 | -0.037477 | 0.006726 | -0.141134 | -0.139823 |
| N3 | -0.065687 | 0.725081 | -0.059039 | -0.010664 | -0.019184 | 0.062495 |
| N4 | -0.345072 | 0.578319 | -0.162174 | 0.062916 | 0.000403 | 0.147551 |
| N5 | -0.161675 | 0.523097 | -0.025305 | -0.161892 | 0.090125 | 0.120049 |
| O1 | 0.225339 | -0.020004 | 0.133201 | 0.479477 | 0.005178 | 0.218690 |
| O2 | -0.001982 | 0.156230 | -0.086047 | -0.496640 | 0.043989 | 0.134693 |
| O3 | 0.325954 | 0.011851 | 0.093880 | 0.566128 | 0.076642 | 0.210777 |
| O4 | -0.177746 | 0.207281 | -0.005671 | 0.349227 | 0.133656 | 0.178068 |
| O5 | -0.014221 | 0.063234 | -0.047059 | -0.576743 | -0.057561 | 0.135936 |
- El factor 1 tiene cargas altas para E1, E2, E3, E4 y E5 (Extraversión).
- El factor 2 tiene cargas altas para N1, N2, N3, N4 y N5 (Neuroticismo).
- El factor 3 tiene cargas altas para C1, C2, C3, C4 y C5 (Responsabilidad/Escrupulosidad).
- El factor 4 tiene cargas altas para O1, O2, O3, O4 y O5 (Apertura).
- El factor 5 tiene cargas altas para A1, A2, A3, A4 y A5 (Amabilidad).
- El factor 6 no presenta cargas altas claras en ninguna variable y no es fácil de interpretar. Conviene quedarnos con cinco factores.
Vamos a realizar el análisis factorial con 5 factores.
# Create factor analysis object and perform factor analysis using 5 factors
fa = FactorAnalyzer()
fa.analyze(df, 5, rotation="varimax")
fa.loadings
| Factor1 | Factor2 | Factor3 | Factor4 | Factor5 | |
|---|---|---|---|---|---|
| A1 | 0.040465 | 0.111126 | 0.022798 | -0.077931 | -0.428166 |
| A2 | 0.213716 | 0.029588 | 0.139037 | 0.062139 | 0.626946 |
| A3 | 0.317848 | 0.009357 | 0.109331 | 0.056196 | 0.650743 |
| A4 | 0.204566 | -0.066476 | 0.230584 | -0.112700 | 0.435624 |
| A5 | 0.393034 | -0.122113 | 0.087869 | 0.066708 | 0.537087 |
| C1 | 0.070184 | 0.010416 | 0.545824 | 0.209584 | 0.038878 |
| C2 | 0.033270 | 0.089574 | 0.648731 | 0.115434 | 0.102782 |
| C3 | 0.023907 | -0.030855 | 0.557036 | -0.005183 | 0.111578 |
| C4 | -0.064984 | 0.240410 | -0.633806 | -0.107535 | -0.037498 |
| C5 | -0.176395 | 0.290318 | -0.562467 | 0.036822 | -0.047525 |
| E1 | -0.574835 | 0.042819 | 0.033144 | -0.058795 | -0.104813 |
| E2 | -0.678731 | 0.244743 | -0.102483 | -0.042010 | -0.112517 |
| E3 | 0.536816 | 0.024180 | 0.083010 | 0.280877 | 0.257906 |
| E4 | 0.646833 | -0.115614 | 0.102023 | -0.073422 | 0.306101 |
| E5 | 0.504069 | 0.036145 | 0.312899 | 0.213739 | 0.090354 |
| N1 | 0.078923 | 0.786807 | -0.045997 | -0.084704 | -0.216363 |
| N2 | 0.027301 | 0.754109 | -0.030568 | -0.010304 | -0.193744 |
| N3 | -0.061430 | 0.731721 | -0.067084 | -0.004217 | -0.027712 |
| N4 | -0.345388 | 0.590602 | -0.178902 | 0.075225 | 0.005886 |
| N5 | -0.161291 | 0.537858 | -0.037309 | -0.149769 | 0.100931 |
| O1 | 0.213005 | -0.002224 | 0.115080 | 0.504907 | 0.061550 |
| O2 | 0.004560 | 0.175788 | -0.099729 | -0.468925 | 0.081809 |
| O3 | 0.310956 | 0.026736 | 0.076873 | 0.596007 | 0.126889 |
| O4 | -0.191196 | 0.220582 | -0.021906 | 0.369012 | 0.155475 |
| O5 | -0.005347 | 0.085401 | -0.062730 | -0.533778 | -0.010384 |
# Get variance of each factors
fa.get_factor_variance()
| Factor1 | Factor2 | Factor3 | Factor4 | Factor5 | |
|---|---|---|---|---|---|
| SS Loadings | 2.473090 | 2.709633 | 2.041106 | 1.522153 | 1.844498 |
| Proportion Var | 0.098924 | 0.108385 | 0.081644 | 0.060886 | 0.073780 |
| Cumulative Var | 0.098924 | 0.207309 | 0.288953 | 0.349839 | 0.423619 |
En total, el 42% de la varianza acumulada es explicada por los 5 factores.
Ventajas e inconvenientes del análisis factorial
El análisis factorial explora conjuntos de datos grandes y encuentra asociaciones interrelacionadas. Reduce las variables observadas a unas pocas variables latentes o identifica grupos de variables relacionadas, lo que ayuda a quienes investigan el mercado a simplificar situaciones complejas y descubrir relaciones ocultas entre gustos, preferencias e influencias culturales de los consumidores. Además, ayuda a mejorar los cuestionarios para futuras encuestas. Los factores facilitan una interpretación más natural de los datos.
Los resultados del análisis factorial pueden ser controvertidos. Sus interpretaciones son debatibles porque se pueden proponer varias lecturas para los mismos factores. Tras identificar y nombrar los factores, se requiere conocimiento del dominio.
Conclusión
¡Enhorabuena, has llegado al final de este tutorial!
En este tutorial has aprendido qué es el análisis factorial; los diferentes tipos, cómo funciona, la terminología básica, cómo elegir el número de factores, la comparación entre el análisis de componentes principales y el análisis factorial, cómo implementarlo en Python con el paquete FactorAnalyzer y las ventajas e inconvenientes del método.
Estaré encantado de leer tus comentarios o preguntas. Puedes dejar tu duda en los comentarios e intentaré responderla lo mejor posible.
Si quieres profundizar en factores en Python, haz el curso Unsupervised Learning in Python de DataCamp.

