Mais do que executar um código: fazendo uma análise de correlação com Python

Nesta análise, testes são realizados para se decidir entre o método de Pearson, Spearman ou Kendall

Hernandes Matias Junior
Jogando os Dados
6 min readAug 25, 2021

--

Illustração por Jonas Mosesson.

Parte de uma boa análise exploratória de dados, a descoberta do coeficiente de correlação entre variáveis pode ser feita utilizando uma linha de código no Python. No entanto, pode-se chegar ao coeficiente de correlação utilizando alguns métodos, sendo os mais comuns os de ‘Pearson’, ‘Spearman’ e ‘Kendall’. Mas como saber qual método escolher? É nesse momento em que uma boa base teórica faz a diferença para quem está fazendo a análise.

A principal premissa antes de se definir o método a ser utilizado é a distribuição normal da variável a ser analisada. Isso porque ‘Pearson’ é uma medida de correlação paramétrica, enquanto ‘Spearman’ e ‘Kendall’, são medidas de correlação não-paramétricas, sendo esse último recomendado para amostras menores, ou quando a variável possui muitos dados que se repetem.

Dispondo de uma base de dados de qualidade do ar, a missão desse post é verificar a normalidade dos dados da variável ‘Carbono’, usando o Boxplot, Histograma, Quantil-Quantil Plot, testes de Shapiro-Wilk, Kolmogorov Smirnov(Lilliefors) e Anderson-Darling, e, após a constatação, escolher entre os três métodos já mencionados anteriormente, para definirmos o coeficiente de correlação entre essa variável e as outras que também estão presentes no dataset.

Em todo o decorrer do post vou assumir que você já conhece um pouco de Estatística. Isso porque para explicar tudo detalhadamente eu precisaria de mais do que uma publicação aqui no Medium.

1. Características da Distribuição Normal

Fonte: Departamento de Informática e Estatística da UFSC.

Talvez a mais utilizada distribuição estatística, a Distribuição Normal é uma curva simétrica em torno do seu ponto médio, onde as frequências de seus valores apresentam um formato de sino. Algumas características dessa distribuição:

  • Formato de sino;
  • Simétrica ou próxima a um formato simétrico;
  • Unimodal;
  • Apresenta valores iguais ou próximos para a Média e a Mediana;
  • Os valores da distribuição tendem a zero ao se afastarem da Média.

2. Analisando a distribuição com Boxplot

Começamos importando as bibliotecas, que utilizaremos durante toda a análise, e o nosso dataset do carbono.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.stats as stats
from statsmodels.stats.diagnostic import lilliefors as lilliesns.set()df = pd.read_excel('carbono.xlsx')

Visualizando as observações da amostra, vemos que se trata de um dataframe de 887 observações e 6 variáveis.

Recapitulando, vamos testar a normalidade do ‘carbono’ e depois verificar a correlação entre ele e as outras variáveis ‘hidrocarboneto1’, ‘benzeno’, ‘hidrocarboneto2’, ‘oxidação’ e ‘ozonio’.

# gráfico de boxplotplt.figure(figsize=(15,8))
plt.title('BOXPLOT DOS VALORES DE CARBONO', fontsize=14, fontweight='bold')
sns.boxplot(x='CARBONO', data=df, color='purple')

O Boxplot nada mais é do que um Histograma visto de cima. Uma distribuição normal quando representada em um boxplot teria sua caixa muito próxima do centro da linha horizontal. Vendo o gráfico acima, a distribuição do carbono parece assimétrica com a sua calda à direita. É também do lado direito onde se encontram os outliers. Dessa forma, à primeira impressão é de que a distribuição não é normal.

3. Plotando os dados em um Histograma

# gráfico de histogramaplt.figure(figsize=(15,8))
plt.title('DISTRIBUIÇÃO DOS VALORES', fontsize=14, fontweight='bold')
sns.histplot(x='CARBONO', data=df, kde=True, color='purple')
plt.ylabel('FREQUÊNCIA')

Como dito anteriormente, perceba como o Histograma tem uma relação com o Boxplot. No gráfico, o formato da distribuição está longe de parecer um sino. A assimetria está de fato à direita e repare como a grande massa dos valores está entre 1150 e 1500 e como existem outliers que ultrapassam os 2250. Essa assimetria à direita desloca a média em sua direção, se comparada à mediana. Vamos verificar?

df['CARBONO'].median(), df['CARBONO'].mean()

Viu? Nossa análise foi correta e a média foi deslocada à direita da mediana. Todo esse conjunto citado reforça o pensamento de que a distribuição não é normal.

4. O famigerado QQ Plot

O quantil-quantil plot, ou QQ Plot, é outra ferramenta gráfica que auxilia na verificação se a distribuição é normal. É mais eficiente do que o Boxplot e o Histograma, e aqui é feita uma comparação entre os quantis teóricos de uma Normal e os quantis dos dados da nossa amostra.

plt.figure(figsize=(15,8))stats.probplot(df['CARBONO'], dist='norm', plot=plt)
plt.title('NORMAL QQ PLOT', fontsize=14, fontweight='bold')

A reta vermelha em 45º representa como deveria ser a distribuição dos dados, caso essa distribuição fosse normal. Os pontos em azul são os dados da nossa amostra. Ou seja, quanto mais próximos os pontos em azul estiverem da reta vermelha, maiores são as chances da nossa distribuição ser normal. No gráfico acima, é possível perceber que existe um distanciamento considerável, principalmente nas extremidades. É interpretativo, mas para mim é outra evidência de uma distribuição não normal. Aconselho muito o estudo e o aprofundamento do QQ Plot.

5. A vez dos testes estatísticos: Shapiro-Wilk, Kolmogorov Smirnov e Anderson-Darling

Assim como no QQ Plot, eu recomendo o aprofundamento nesses testes estatísticos para a verificação da normalidade, pois seria inviável explicar tudo aqui. Seguindo adiante, ao realizarmos os testes e ao encontrar o p-valor, vamos considerar as duas hipóteses:

Nível de significância de 0,05 ou 5%, ou a um nível de confiança de 0.95 ou 95%:

  • Ho = distribuição normal: p>0.05
  • Ha = distribuição não normal: p<=0.05
# shapiro-wilk
stats.shapiro(df['CARBONO'])

8.634053487357324e-14

# kolmogorov smirnov (lilliefors)
lillie(df['CARBONO'], dist='norm')

0.0009999999999998899

# anderson-darling
stats.anderson(df['CARBONO'], 'norm')

0.783

Ambos os testes de Shapiro-Wilk e Kolmogorov Smirnov apontaram uma distribuição não normal. Anderson-Darling, conhecido por ser um teste mais flexível, apontou normalidade.

6. O placar final

Após as verificações com os gráficos e testes, elencamos o que nós interpretamos e o que eles apontaram:

BOXPLOT: Não normal;

HISTOGRAMA: Não normal;

QQ PLOT: Não normal;

SHAPIRO-WILK: Não normal;

KOLMOGOROV SMIRNOV: Não normal;

ANDERSON-DARLING: Normal.

Não normal 5 x 1 Normal.

7. Finalmente ela: correlação!

Como assumimos que a distribuição não é normal, utilizaremos o método de Spearman para encontrarmos o coeficiente de correlação da variável ‘Carbono’, e plotaremos inicialmente em um heatmap. O método de Kendall, apesar de também ser para distribuição não normal, é adequado para dados ordinais, o que não é o caso aqui.

correlacao = df.corr(method='spearman')plt.figure(figsize=(15,8))
plt.title('HEATMAP DE CORRELAÇÃO', fontsize=14, fontweight='bold')
sns.heatmap(correlacao, annot=True)

O heatmap é uma boa forma de se verificar a correlação, mas como o nosso foco é apenas em uma variável, acredito que seja melhor utilizar uma visualização mais simples e ordenar as outras variáveis de acordo com a sua correlação frente ao ‘Carbono’.

correlacao = 
df.corr(method='spearman')['CARBONO'].sort_values(ascending=False)

Todas as outras variáveis possuem correlação interessante com ‘Carbono’.

‘Hidrocarboneto2’, ‘Benzeno’ e ‘Ozonio’ possuem correlação positiva muito forte com ‘Carbono’, enquanto ‘Hidrocarboneto1’ possui correlação positiva forte e ‘Oxidação’ possui correlação negativa forte.

Vamos visualizar essas do ‘Carbono’ e das outras variáveis em gráficos de dispersão?

colunas = ['HIDROCARBONETO1', 'BENZENO', 'HIDROCARBONETO2', 'OXIDAÇÃO', 'OZONIO']plt.figure(figsize=(25,25))for k in range(len(colunas)):

plt.subplot(4,3, k+1)
sns.scatterplot(x='CARBONO', y=colunas[k], data=df, color='#ff7252')
plt.ylabel(colunas[k],fontsize=12)
plt.xlabel('CARBONO',fontsize=12)

plt.show()

Quando ‘Carbono’ aumenta, ‘Hidrocarboneto1’, ‘Benzeno’, ‘Hidrocarboneto2’ e ‘Ozonio’ também tendem a aumentar, enquanto ‘Oxidação’ tende a diminuir.

Muito legal, né? Você pode encontrar todo o código e o dataset no repositório do meu Github.

Também pode me contactar pelo Linkedin.

Abraços!

Referências Bibliográficas

A distribuição Normal. UFPR. http://www.leg.ufpr.br/~silvia/CE701/node36.html

Distribuição Normal (Gaussiana). UFSC. https://www.inf.ufsc.br/~andre.zibetti/probabilidade/normal.html

Como testar a distribuição normal. SOS Estatística. https://sosestatistica.com.br/como-testar-se-uma-distribuicao-e-normal/

--

--

Hernandes Matias Junior
Jogando os Dados

Engenheiro, Administrador pela PUC Minas e pós-graduando em Data Science e Analytics pela USP.