Machine Learning com Python: Teste de hipótese, esfericidade de Bartlett e estatística KMO para verificar a adequabilidade dos dados a uma PCA

Charles Júnior
Data Hackers
Published in
8 min readSep 11, 2023
reprodução/solutionpharmacy

Contextualização

O teste de hipótese envolve a formulação de uma hipótese nula (H0) e uma hipótese alternativa (H1), a coleta de dados, o cálculo de uma estatística de teste e a comparação dessa estatística com um valor crítico “p-value” para tomar uma decisão estatística.

Antes de aplicar uma PCA, é crucial realizar verificações para garantir a adequação dos dados à análise. Iremos abordar e analisar os dados do INEP por meio de técnicas como o teste de esfericidade de Bartlett e a estatística KMO (Kaiser-Meyer-Olkin).

Dados

Os dados utilizados são os indicadores de desempenho escolar do INEP, os quais passaram por uma etapa de preparação de dados, conforme explicado aqui.
Ao final do processo de preparação de dados, foi gerado um arquivo em Excel com o nome “df_inep.” Esse é o arquivo que iremos utilizar.

Recursos

Foram utilizados o Python e o Jupyter Notebook.

Aplicação

Importante verificar se todas as bibliotecas necessárias estão instaladas. Caso não estejam, proceda com a instalação, por exemplo:

pip install factor_analyzer

Foram utilizadas as seguintes bibliotecas:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from factor_analyzer import FactorAnalyzer
from factor_analyzer.factor_analyzer import calculate_kmo
from scipy.stats import bartlett

Para obter os dados do arquivo:

# Obter os dados 
df_fundamental = pd.read_excel("df_inep.xlsx")
df_fundamental = df_fundamental.iloc[:, [7,9,11,13,15, 17]]

Iremos aplicar os testes a uma amostra aleatória com 300 observações. Para isso:

# Criar amostra aleatoria com 300 valores
tamanho_amostra = 300
df_fundamental_amostra = df_fundamental.sample(n=tamanho_amostra, replace=False)

Verificando as primeiras linhas do dataframe:

# Verificando o dataframe
df_fundamental_amostra.head()
Dados do dataframe

Analisando a correlação entre as variáveis

Para a nossa abordagem da Análise de Componentes Principais (PCA), baseada na matriz de correlação de Pearson, é importante investigar os dados a fim de avaliar as relações entre as variáveis. Para isso, vamos gerar um gráfico de correlações e um gráfico de calor.

Gerar gráfico de correlações usando o pairplot:

# Gerando um gráfico de correlações com pairplot
df = df_fundamental_amostra
# Calcular a matriz de correlação
corr_matrix = df.corr()
# Criar um Pair Plot com distribuições
sns.set(style="ticks")
g = sns.pairplot(df, diag_kind="kde", markers="o")
# Tamanho da fonte para as anotações
fontsize = 16
# Adicionar anotações de correlação nas células dos gráficos de dispersão de pares
for i, (ax_row, ax_col) in enumerate(zip(g.axes, g.axes.T)):
for j, ax in enumerate(ax_col):
if i != j:
corr_value = corr_matrix.iloc[i, j]
ax.annotate(f"corr = {corr_value:.2f}", xy=(0.5, 0.95), xycoords='axes fraction',
ha='center', fontsize=fontsize, color='black', backgroundcolor='white')

# Adicionar uma linha de regressão linear
sns.regplot(data=df, x=df.columns[i], y=df.columns[j], ax=ax, scatter=False, color='blue')

g.fig.suptitle("Pair Plot com Distribuições, Correlações e Linhas de Regressão", y=1.02)
plt.show()
Gráfico de correlações entre as variáveis

Gerar o gráfico de calor:

# Gerando o gráfico de calor para analisar a correlação entre as variáveis
df = df_fundamental_amostra
# Calcular a matriz de correlação
corr_matrix = df.corr()
# Configurar o estilo do gráfico
sns.set(style="white")
# Criar um gráfico de calor de correlação
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, fmt=".2f", cmap='coolwarm', linewidths=.5)
# Configurar título e rótulos
plt.title("Gráfico de Calor de Correlação")
plt.xlabel("")
plt.ylabel("")
plt.show()
Gráfico de calor das correlações entre as variáveis

Ao examinar os gráficos, verifica-se que as correlações entre as variáveis existem, mas são mais notáveis para correlação negativa, enquanto a correlação positiva é mínima.

Estatística KMO

A estatística Kaiser-Meyer-Olkin (KMO) é utilizada na Análise de Componentes Principais (PCA) para avaliar a adequação dos dados ao modelo. O valor do KMO varia de 0 a 1, e quanto mais próximo de 1 e acima de 0.5, mais forte é a correlação entre as variáveis. Por outro lado, valores abaixo de 0.5 indicam correlações mais fracas, o que pode sugerir que a PCA não seja apropriada para esses dados e que outras técnicas de análise podem ser mais adequadas.

Fórmula para calcular o KMO:

No Python, para aplicar a estatística KMO, procedemos da seguinte maneira:

# Aplicando a estatística KMO
df = df_fundamental_amostra
# Calcular a matriz de correlação
rho = df.corr()
max_length = 10
# Realize o teste KMO
kmo_per_variable, kmo_total = calculate_kmo(rho)
# Imprima os resultados
for i, kmo in enumerate(kmo_per_variable):
variable_name = rho.columns[i]
# Formate o nome da variável com espaços em branco adicionados para atingir o comprimento máximo
formatted_variable_name = f"{variable_name:{max_length}}"
print(f"KMO {formatted_variable_name}: {kmo:.2f}")
# Imprima o KMO total
print(f"KMO Total: {kmo_total:.2f}")

Onde obtivemos o seguinte resultado:

Resultado da análise KMO

É observado que todas as variáveis envolvidas tiveram um KMO acima de 0.5, e o KMO total foi de 0.64, o que sugere, segundo a estatística KMO, uma adequação dos dados.

Existem alguns pontos importantes sobre a estatística KMO a serem observados:

  1. O valor total será sempre 0.5 se houverem apenas duas variáveis.
  2. KMO é uma estatística e não um teste estatístico.
  3. Alguns autores são críticos em relação ao seu uso, pois consideram que sua análise envolve uma ponderação arbitrária ao fazer uso de uma tabela de adequação, por exemplo:
Exemplo de tabela de adequação

No contexto deste artigo, o KMO foi abordado apenas para apresentação da técnica, visto que se trata de uma estatística e não de um teste estatístico. Portanto, para aplicar o teste de hipótese, consideraremos o teste de esfericidade de Bartlett para verificar a adequabilidade dos dados à uma Análise de Componentes Principais (PCA).

Teste de esfericidade de Bartlett

O teste de esfericidade de Bartlett é usado para avaliar a homogeneidade das matrizes de covariância entre as variáveis. Se as variáveis tiverem uma matriz de covariância homogênea, isso é uma indicação de que a PCA pode ser uma técnica apropriada.

Para realizar o teste de Bartlett, você formula a hipótese nula (H0) de que as matrizes de covariância das variáveis são iguais. A hipótese alternativa (H1) é que pelo menos uma das matrizes de covariância é diferente das outras. O teste compara a estatística de Bartlett com uma distribuição qui-quadrado.

Se o valor-p associado ao teste de Bartlett for significativamente menor que um nível de significância escolhido (por exemplo, 0.05), você pode rejeitar a hipótese nula. Isso sugere que as matrizes de covariância das variáveis são heterogêneas, o que pode indicar que a PCA não é apropriada.

Fórmula para aplicar o teste de bartlett:

Onde: p = número de variáveis, n = número de observações, lRl = determinante da matriz de correlação ρ

A distribuição do teste de esfericidade de Bartlett segue uma distribuição qui-quadrado, e os graus de liberdade são calculados pela fórmula:

Onde p = número de variáveis

Existem duas hipóteses que são verificadas através da matriz de correlação (ρ), conforme abaixo. Se a matriz for uma matriz identidade, ou seja, com todos os seus elementos da diagonal principal iguais a 1 e os demais iguais a 0, então a hipótese nula (H0) não será rejeitada. Caso contrário, se a matriz não for uma matriz identidade, (H0) é rejeitado e então teremos a hipótese alternativa (H1).

Para rejeitar a hipótese nula a matriz de correlações não pode ser uma matriz identidade.

No contexto da adequabilidade dos dados para uma Análise de Componentes Principais (PCA), buscamos a hipótese alternativa (H1). Ou seja, estamos interessados em verificar se há evidência estatística de que as matrizes de covariância das variáveis não são iguais (ou seja, não são uma matriz identidade).

Normalmente, em um nível de confiança de 95% e um nível de significância de 5%, rejeitaríamos a hipótese nula (H0) se o valor-p associado ao teste de esfericidade de Bartlett fosse menor que 0.05, o que indicaria que as matrizes de covariância não são homogêneas e, portanto, a PCA não é apropriada para esses dados.

95% de confiança e 5% de significância, buscamos um p-value abaixo de 0.05

Ou seja, temos 95% de confiança de que o valor-p não estará em uma região que contenha o valor 0 e 5% de significância da probabilidade de cometer um erro, ou seja, rejeitar a hipótese nula quando ela é verdadeira.

E como aplicar o bartlett no Python?

Iremos usar a função bartlett da biblioteca scipy. A primeira coisa a fazer é instalá-la (caso não esteja instalada) e importar a biblioteca. Ao utilizar a função bartlett, não é necessário passar uma matriz de correlação como parâmetro. No entanto, esta função só aceita arrays de 1 dimensão como parâmetros.

# Para instalar
pip install scipy
# Para importar
from scipy.stats import bartlett

O próximo passo é chamar a execução da função bartlett, onde são passados como parâmetros os dados do dataframe. No caso, cada variável deve ser passada individualmente, por exemplo: bartlett(var1, var2, ..., var_k). No entanto, para facilitar, iremos utilizar um recurso do Python chamado de "desempacotamento de argumentos" (unpacking de argumentos).

# Calcular o teste de esfericidade de Bartlett
estistica, p_valor = bartlett(*[df[col] for col in df.columns])

Especificamente, o asterisco (*) é o operador de desempacotamento e é usado antes de uma sequência (como uma lista) em uma chamada de função para desempacotar os elementos dessa sequência e passá-los como argumentos separados para a função.

A função bartlett retorna duas saídas contendo a estatística calculada na distribuição qui-quadrado para os dados de entrada e o p-valor da função. Conforme mencionado, se o p-valor for menor do que o nível de significância escolhido, no nosso caso, 0.05, então podemos rejeitar a hipótese nula e realizar a PCA na base de dados. Iremos, então, aproveitar o p-valor retornado e usá-lo para imprimir uma mensagem que indique se a hipótese nula foi ou não rejeitada. Com isso, temos o código completo abaixo para realizar o teste de Bartlett no Python:

# Aplicando o teste de Bartlett
df = df_fundamental_amostra
# Calcular o teste de esfericidade de Bartlett
estatistica, p_valor = bartlett(*[df[col] for col in df.columns])
# Definir um nível de significância
nivel_significancia = 0.05
# Verificar a hipótese nula
resultado = ''
if p_valor < nivel_significancia:
resultado = 'Rejeitamos a hipótese nula. A matriz de correlação não é uma matriz de identidade.'
else:
resultado = 'Não rejeitamos a hipótese nula. A matriz de correlação é uma matriz de identidade.'

print(f'{resultado}\nEstatística X²: {estatistica}\np-value: {p_valor}')
Resultado do teste de Batlett

O teste de Bartlett resulta em um p-valor de 0, o que indica que os dados podem ser fatorados e a matriz de correlação observada não é igual a uma matriz identidade.

Download

Para obter o notebook com o código: https://github.com/charlesjuniorx/artigos_python_hipotese_pca

Referências

https://docs.ufpr.br/~soniaisoldi/ce090/TestesAnaliseFatorial.pdf

https://www.analyticsvidhya.com/blog/2020/10/dimensionality-reduction-using-factor-analysis-in-python/

https://towardsdatascience.com/hypothesis-testing-with-python-step-by-step-hands-on-tutorial-with-practical-examples-e805975ea96e

--

--