Curso
A análise fatorial (FA) é um método exploratório de análise de dados usado para identificar fatores subjacentes influentes ou variáveis latentes a partir de um conjunto de variáveis observadas. Ela facilita a interpretação dos dados ao reduzir o número de variáveis. O método extrai a variância comum máxima de todas as variáveis e a concentra em um escore comum.
A análise fatorial é amplamente utilizada em pesquisa de mercado, publicidade, psicologia, finanças e pesquisa operacional. Pesquisadores de mercado usam a análise fatorial para identificar clientes sensíveis a preço, descobrir atributos de marca que influenciam a escolha do consumidor e entender critérios de seleção de canais para distribuição.
Análise fatorial
A análise fatorial é um modelo estatístico linear. Ela é usada para explicar a variância entre as variáveis observadas e condensar um conjunto de variáveis observadas em variáveis não observadas chamadas fatores. As variáveis observadas são modeladas como uma combinação linear de fatores e termos de erro (Fonte). Um fator ou variável latente está associado a múltiplas variáveis observadas que compartilham padrões de resposta em comum. Cada fator explica uma determinada parcela da variância nas variáveis observadas. Ela ajuda na interpretação dos dados ao reduzir o número de variáveis.
A análise fatorial é um método para investigar se um conjunto de variáveis de interesse X1, X2, …, Xl está linearmente relacionado a um número menor de fatores não observáveis F1, F2, …, Fk.
Fonte: esta imagem foi recriada a partir de uma imagem que encontrei em anotações de análise fatorial. A imagem oferece uma visão completa da análise fatorial.
Pressupostos:
- Não há outliers nos dados.
- O tamanho da amostra deve ser maior que o número de fatores.
- Não deve haver multicolinearidade perfeita.
- Não deve haver homocedasticidade entre as variáveis.
Tipos de análise fatorial
- Análise fatorial exploratória (EFA): é a abordagem mais popular entre pesquisadores de ciências sociais e gestão. Seu pressuposto básico é que qualquer variável observada pode estar diretamente associada a qualquer fator.
- Análise fatorial confirmatória (CFA): parte do pressuposto de que cada fator está associado a um conjunto específico de variáveis observadas. A CFA confirma o que se espera teoricamente.
Como a análise fatorial funciona?
O objetivo principal da análise fatorial é reduzir o número de variáveis observadas e encontrar variáveis não observáveis. Essas variáveis não observadas ajudam o pesquisador de mercado a concluir um estudo. Essa conversão de variáveis observadas em variáveis não observadas ocorre em duas etapas:
- Extração de fatores: nesta etapa, define-se o número de fatores e o método de extração usando técnicas de particionamento da variância, como análise de componentes principais e análise de fatores comuns.
- Rotação de fatores: nesta etapa, a rotação tenta transformar os fatores em fatores não correlacionados — o objetivo é melhorar a interpretabilidade geral. Existem vários métodos de rotação, como: Varimax, Quartimax e Promax.
Terminologia
O que é um fator?
Fator é uma variável latente que descreve a associação entre várias variáveis observadas. O número máximo de fatores é igual ao número de variáveis observadas. Cada fator explica uma certa variância nas variáveis observadas. Os fatores com menor variância são descartados. Fatores também são chamados de variáveis latentes, ocultas, não observadas ou variáveis hipotéticas.
O que são cargas fatoriais?
A carga fatorial é uma matriz que mostra a relação de cada variável com o fator subjacente. Ela apresenta o coeficiente de correlação entre a variável observada e o fator, indicando a variância explicada pelas variáveis observadas.
O que são autovalores (eigenvalues)?
Autovalores representam a variância explicada por cada fator em relação à variância total. Também são conhecidos como raízes características.
O que são comunalidades?
Comunalidades são a soma dos quadrados das cargas para cada variável. Elas representam a variância comum. Variam de 0 a 1, e valores próximos de 1 indicam maior variância comum.
O que é rotação fatorial?
A rotação é uma ferramenta para melhorar a interpretação na análise fatorial. A rotação pode ser ortogonal ou oblíqua. Ela redistribui as comunalidades, produzindo um padrão mais claro de cargas.
Escolhendo o número de fatores
O critério de Kaiser é uma abordagem analítica baseada na ideia de selecionar os fatores que explicam uma parcela mais significativa da variância. O autovalor é um bom critério para determinar o número de fatores. Em geral, autovalores maiores que 1 são considerados como critério de seleção.
A abordagem gráfica se baseia na representação visual dos autovalores dos fatores, o chamado scree plot. Esse gráfico ajuda a determinar o número de fatores no ponto em que a curva forma um "cotovelo".
Análise fatorial vs. análise de componentes principais
- Componentes da PCA explicam a maior quantidade de variância, enquanto a análise fatorial explica a covariância nos dados.
- Componentes da PCA são totalmente ortogonais entre si, enquanto a análise fatorial não exige ortogonalidade entre fatores.
- Um componente da PCA é uma combinação linear das variáveis observadas, enquanto, em FA, as variáveis observadas são combinações lineares da variável não observada (fator).
- Componentes da PCA são, em geral, pouco interpretáveis. Em FA, os fatores subjacentes podem ser nomeados e interpretados.
- A PCA é um método de redução de dimensionalidade, enquanto a análise fatorial é um método de variáveis latentes.
- A PCA é um tipo de análise fatorial no sentido amplo. A PCA é observacional, enquanto a FA é uma técnica de modelagem.
Análise fatorial em Python com o pacote factor_analyzer
Importar bibliotecas necessárias
# Import required libraries
import pandas as pd
from sklearn.datasets import load_iris
from factor_analyzer import FactorAnalyzer
import matplotlib.pyplot as plt
Carregar os dados
Vamos realizar análise fatorial no BFI (conjunto de dados de um projeto de avaliação de personalidade), coletado com uma escala de resposta de 6 pontos: 1 Muito impreciso, 2 Moderadamente impreciso, 3 Ligeiramente impreciso, 4 Ligeiramente preciso, 5 Moderadamente preciso e 6 Muito preciso. Você também pode baixar este dataset no link: https://vincentarelbundock.github.io/Rdatasets/datasets.html
df= pd.read_csv("bfi.csv")
Pré-processar os dados
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 linhas × 25 colunas
Teste de adequação
Antes de realizar a análise fatorial, é preciso avaliar a "fatorabilidade" do conjunto de dados. Fatorabilidade significa: "é possível encontrar fatores neste dataset?". Há dois métodos para verificar a fatorabilidade ou a adequação da amostra:
- Teste de esfericidade de Bartlett
- Teste Kaiser-Meyer-Olkin
O teste de Bartlett de esfericidade verifica se as variáveis observadas se correlacionam entre si, comparando a matriz de correlação observada com a matriz identidade. Se o teste não for estatisticamente significativo, você não deve aplicar análise fatorial.
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)
Neste teste de Bartlett, o p-valor é 0. O teste foi estatisticamente significativo, indicando que a matriz de correlação observada não é uma matriz identidade.
O teste Kaiser-Meyer-Olkin (KMO) mede a adequação dos dados para a análise fatorial. Ele determina a adequação para cada variável observada e para o modelo completo. O KMO estima a proporção de variância entre todas as variáveis observadas. Proporções mais altas indicam maior adequação à análise fatorial. Os valores de KMO variam entre 0 e 1. Valor inferior a 0,6 é considerado inadequado.
from factor_analyzer.factor_analyzer import calculate_kmo
kmo_all,kmo_model=calculate_kmo(df)
kmo_model
0.8486452309468382
O KMO geral dos nossos dados é 0,84, excelente. Esse valor indica que você pode seguir com a análise fatorial planejada.
Escolhendo o número de fatores
Para escolher o número de fatores, você pode usar o critério de Kaiser e o scree plot. Ambos se baseiam em autovalores.
# 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 |
Aqui, você vê que apenas para 6 fatores os autovalores são maiores que 1. Isso significa que devemos escolher apenas 6 fatores (ou variáveis não observadas).
# 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()
O scree plot traça uma linha para cada fator e seu autovalor. A quantidade de autovalores maiores que 1 é considerada como o número de fatores.
Aqui, você vê que apenas para 6 fatores os autovalores são maiores que 1. Isso significa que devemos escolher apenas 6 fatores (ou variáveis não observadas).
Executando a análise fatorial
# 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 |
- O fator 1 tem altas cargas em E1, E2, E3, E4 e E5 (extroversão)
- O fator 2 tem altas cargas em N1, N2, N3, N4 e N5 (neuroticismo)
- O fator 3 tem altas cargas em C1, C2, C3, C4 e C5 (conscienciosidade)
- O fator 4 tem altas cargas em O1, O2, O3, O4 e O5 (abertura)
- O fator 5 tem altas cargas em A1, A2, A3, A4 e A5 (amabilidade)
- O fator 6 não apresenta cargas altas em nenhuma variável e não é facilmente interpretável. É melhor trabalharmos com apenas cinco fatores.
Vamos executar a análise fatorial com 5 fatores.
# 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 |
No total, 42% da variância cumulativa é explicada pelos 5 fatores.
Prós e contras da análise fatorial
A análise fatorial explora grandes conjuntos de dados e encontra associações interligadas. Ela reduz as variáveis observadas a algumas variáveis não observadas ou identifica grupos de variáveis inter-relacionadas, o que ajuda pesquisadores de mercado a resumir cenários e descobrir relações ocultas entre preferências, gostos e influências culturais dos consumidores. Além disso, auxilia na melhoria de questionários para pesquisas futuras. Os fatores tornam a interpretação dos dados mais natural.
Os resultados da análise fatorial podem ser controversos. As interpretações são debatíveis, pois um mesmo conjunto de fatores pode permitir mais de uma leitura. Após a identificação e a nomeação dos fatores, é necessário conhecimento de domínio.
Conclusão
Parabéns, você chegou ao fim deste tutorial!
Neste tutorial, você aprendeu o que é análise fatorial, os diferentes tipos, como ela funciona, a terminologia básica, como escolher o número de fatores, a comparação entre análise de componentes principais e análise fatorial, a implementação em Python usando o pacote FactorAnalyzer e os prós e contras da técnica.
Vou adorar receber seu feedback ou dúvidas. Deixe um comentário com sua pergunta e farei o possível para responder.
Se você quiser se aprofundar em fatores no Python, faça o curso Unsupervised Learning in Python da DataCamp.
