Pular para o conteúdo principal

Introdução à análise fatorial em Python

Neste tutorial, você vai aprender os fundamentos da análise fatorial e como implementá-la em Python.
· 10 min leer

Explore com IA

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:

  1. Não há outliers nos dados.
  2. O tamanho da amostra deve ser maior que o número de fatores.
  3. Não deve haver multicolinearidade perfeita.
  4. 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".

Fonte

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.

Fonte

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()
 A1A2A3A4A5C1C2C3C4C5...N1N2N3N4N5O1O2O3O4O5
02.04.03.04.04.02.03.03.04.04.0...3.04.02.02.03.03.063.04.03.0
12.04.05.02.05.05.04.04.03.04.0...3.03.03.05.05.04.024.03.03.0
25.04.05.04.04.04.05.04.02.05.0...4.05.04.02.03.04.025.05.02.0
34.04.06.05.05.04.04.03.05.05.0...2.05.02.04.01.03.034.03.05.0
42.03.03.04.05.04.04.05.03.02.0...2.03.04.04.03.03.034.03.03.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
05.134311
12.751887
22.142702
31.852328
41.548163
51.073582
60.839539
70.799206
80.718989
90.688089
100.676373
110.651800
120.623253
130.596563
140.563091
150.543305
160.514518
170.494503
180.482640
190.448921
200.423366
210.400671
220.387804
230.381857
240.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
 Factor1Factor2Factor3Factor4Factor5Factor6
A10.0407830.0952200.048734-0.113057-0.5309870.161216
A20.2355380.0331310.1337140.0637340.661141-0.006244
A30.343008-0.0096210.1213530.0339900.6059330.160106
A40.219717-0.0815180.235140-0.1253380.4045940.086356
A50.414458-0.1496160.1063820.0309770.4696980.236519
C10.077248-0.0043580.5545820.1901240.0075110.095035
C20.0383700.0683300.6745450.0875930.0570550.152775
C30.031867-0.0399940.551164-0.0113380.1012820.008996
C4-0.0662410.216283-0.638475-0.143846-0.1026170.318359
C5-0.1808120.284187-0.5448380.025837-0.0599550.132423
E1-0.5904510.0222800.053915-0.071205-0.1308510.156583
E2-0.6845780.233624-0.088497-0.045561-0.1167160.115065
E30.556774-0.0008950.1033900.2411800.1793960.267291
E40.658395-0.1367880.113798-0.1078080.2411430.158513
E50.5075350.0344900.3098130.2008210.0788040.008747
N10.0680110.805806-0.051264-0.074977-0.174849-0.096266
N20.0229580.789832-0.0374770.006726-0.141134-0.139823
N3-0.0656870.725081-0.059039-0.010664-0.0191840.062495
N4-0.3450720.578319-0.1621740.0629160.0004030.147551
N5-0.1616750.523097-0.025305-0.1618920.0901250.120049
O10.225339-0.0200040.1332010.4794770.0051780.218690
O2-0.0019820.156230-0.086047-0.4966400.0439890.134693
O30.3259540.0118510.0938800.5661280.0766420.210777
O4-0.1777460.207281-0.0056710.3492270.1336560.178068
O5-0.0142210.063234-0.047059-0.576743-0.0575610.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
 Factor1Factor2Factor3Factor4Factor5
A10.0404650.1111260.022798-0.077931-0.428166
A20.2137160.0295880.1390370.0621390.626946
A30.3178480.0093570.1093310.0561960.650743
A40.204566-0.0664760.230584-0.1127000.435624
A50.393034-0.1221130.0878690.0667080.537087
C10.0701840.0104160.5458240.2095840.038878
C20.0332700.0895740.6487310.1154340.102782
C30.023907-0.0308550.557036-0.0051830.111578
C4-0.0649840.240410-0.633806-0.107535-0.037498
C5-0.1763950.290318-0.5624670.036822-0.047525
E1-0.5748350.0428190.033144-0.058795-0.104813
E2-0.6787310.244743-0.102483-0.042010-0.112517
E30.5368160.0241800.0830100.2808770.257906
E40.646833-0.1156140.102023-0.0734220.306101
E50.5040690.0361450.3128990.2137390.090354
N10.0789230.786807-0.045997-0.084704-0.216363
N20.0273010.754109-0.030568-0.010304-0.193744
N3-0.0614300.731721-0.067084-0.004217-0.027712
N4-0.3453880.590602-0.1789020.0752250.005886
N5-0.1612910.537858-0.037309-0.1497690.100931
O10.213005-0.0022240.1150800.5049070.061550
O20.0045600.175788-0.099729-0.4689250.081809
O30.3109560.0267360.0768730.5960070.126889
O4-0.1911960.220582-0.0219060.3690120.155475
O5-0.0053470.085401-0.062730-0.533778-0.010384
# Get variance of each factors
fa.get_factor_variance()
 Factor1Factor2Factor3Factor4Factor5
SS Loadings2.4730902.7096332.0411061.5221531.844498
Proportion Var0.0989240.1083850.0816440.0608860.073780
Cumulative Var0.0989240.2073090.2889530.3498390.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.

Temas

Relacionado

Tutorial

Funções em Python: como chamar e escrever funções

Tutorial

Tutorial de strings em Python