Correlação define importância? Alternativas para selecionar as variáveis mais importantes num modelo de Machine Learning.

Matheus Vasconcelos
16 min readSep 19, 2023

--

Um dos campos da matemática mais controversos e passíveis de manipulações é a estatística. Diversas vezes pessoas manipulam dados de acordo com suas diretrizes, e um dos conceitos desse universo mais utilizado para tal é a correlação.

Um cientista de dados precisa compreender bem a sutileza na dinâmica entre correlação estatística e realidade. Incontáveis números são apresentados para o público leigo de modo a corroborar com estratégias de partes interessadas.

O ponto principal que me levou a escrever sobre isso é um alerta que Darrell Huff, no seu clássico “Como mentir com Estatística”, expôs: todo leitor deve questionar estatísticas despejadas com ou sem algum intuito.

Ressalto esse “sem intuito” porque o autor relata que já foi repreendido pelo presidente de uma seção da Associação Americana de Estatística que lhe afirmou que “não se trata sempre de tentar enganar, mas também apenas de incompetência”.

Essa observação reflete a importância de abrir os olhos para dados exibidos a todo momento. No capítulo 8, Post Hoc está de volta, Huff é certeiro quanto ao cuidado que devemos ter com a correlação.

E o que é correlação?

Antes de tudo, correlação nada mais é do que a relação, linear ou não, entre uma variável e outra. Ou seja, se uma variável X aumenta e outra variável Y também aumenta de maneira similar, haverá uma correlação positiva. Caso uma diminua junto com a outra, teremos uma correlação negativa.

Em padrões lineares (e com distribuição normal dos dados), usamos bastante o coeficiente de correlação de Pearson para não apenas definir como duas variáveis se correlacionam, mas também para quantificar o grau e a direção da relação linear entre elas.

Mas ponto-chave é a palavra “linear”. É evidente que as interações mais complexas mundo afora não são lineares. Uma estruturação linear pode descrever bem um problema simples como a relação entre altura e peso de uma pessoa, por exemplo, ou pode explicar parcialmente um problema complexo. Tendências não lineares, ainda que sejam altas, podem criar correlações que não refletem a força da relação.

Como foi dito por Spiegel, Schiller e Srinivasan no livro “Probabilidade e Estatística” da coleção Schaum, se supormos que se aplique o coeficiente linear de correlação a dados não-lineares e se obtenha um valor numericamente bem menor que 1, não significa que a correlação é pequena. Significa na verdade que a correlação linear é pequena.

Pode, inclusive, haver uma correlação não-linear considerável. Para tais situações, o coeficiente de correlação de Spearman pode ser melhor usado, ou um ajuste polinomial pode ser mais interessante.

Para entendermos isso, devemos ter em mente que a correlação anda de mãos dadas com o ajuste de regressão. Mas a correlação talvez não seja o recurso mais fundamental quando se trata de regressões mais complexas.

Quando plotamos num gráfico de dispersão uma reta de regressão, por exemplo, conseguimos visualmente identificar a existência ou não de uma correlação. O coeficiente de Pearson irá quantificá-la.

Há ainda os resíduos originados do ajuste feito pela nossa reta de regressão. Pense assim: Dados = Ajuste + Resíduos. Ou seja, temos que levar em conta a diferença entre o valor previsto e o valor real.

Há casos, como eu mencionei, em que uma reta de regressão se torna inútil para descrever um comportamento que apresenta um padrão mais curvo do que o limite onde uma reta consegue explicar a relação.

De forma adiantada, já ressalto que o coeficiente de correlação pode não ser a métrica mais confiável para análise de relação entre variáveis, a despeito do que acreditam muitos iniciantes em ciência de dados.

No livro “Econometria Básica” de Damodar Gujarati, o autor explica que “no contexto da regressão, o coeficiente de determinação (coeficiente de correlação ao quadrado) é uma medida mais significativa do que o coeficiente de correlação”.

Para modelos de regressão múltipla (onde mais variáveis estão envolvidas), a correlação é duvidosa. O r² (coeficiente de determinação) é mais seguro, uma vez que mede a proporção ou a porcentagem da variação total em Y explicada pelo modelo de regressão.

Por isso, antes de sairmos espalhando tudo que vemos nos jornais ou artigos sobre correlações, devemos nos perguntar se o tipo de correlação usada foi adequada ao problema, ou modificada para beneficiar partes interessadas.

Tanto o coeficiente de Pearson como o de Spearman oferecem uma estimativa da correlação entre duas variáveis que sempre ficam na mesma escala (0 e 1). Ou seja, normalizamos a medida para facilitar o entendimento, não só da máquina, como mencionei em artigos anteriores, mas de qualquer visualizador.

E mesmo que a relação entre as variáveis seja linear (e usemos o coeficiente de Pearson) e a correlação seja significativa, isso não implica numa relação de causalidade, ou seja, não podemos afirmar que isso acontecerá para todos os casos.

Dadas as diferentes nuances que um simples conceito como a correlação possui (linear e não-linear; positiva e negativa, etc), o conselho de Darrel Huff para darmos mais atenção aos números nesse sentido se mantém e sempre se manterá relevante.

O que mais ignoramos quanto à correlação?

O problema principal está no vício de muitos cientistas de dados e programadores com o conceito da correlação. Para alguns, essa medida é preponderante para determinar um modelo de predição. Um pouco mais adiante mostrarei uma alternativa concreta aos cientistas de dados para esse objetivo.

Na maioria desses casos onde a situação nos dá várias justificativas razoáveis através dos dados, a pessoa responsável por expor a informação escolhe uma das explicações favoritas dela. Isso porque o problema possui uma gama de possibilidades, como mostrarei a seguir.

Uma das armadilhas está no fato de que correlações, mesmo que sejam reais quantitativamente, podem ser usadas para sustentar uma relação de causa e efeito não comprovada. E essa confusão se dá de diversas maneiras:

  1. A velha falácia do Post-Hoc, ou seja se A aconteceu depois de B, então B causou A: Imagine que se eu, com uma dor de cabeça terrível, ao tomar um copo d’água, começo a me sentir melhor. A partir de então, meu cérebro (que odeia incertezas e ama padrões) começa a entender que o ato de tomar água me curou. É mais ou menos assim que funciona. Por diversas vezes ignoramos variáveis “ocultas” que interferem nas variáveis que achamos que são únicas e mais importantes. Há ainda mais fatores que deixamos de lado. Continuando…
  2. Troca de posição entre as variáveis: uma variável pode ser a causadora ou a consequência, mas também pode ser as duas a depender do contexto. Não é sempre fácil determinar, por exemplo, se uma pessoa é rica porque tem ações do mercado financeiro, ou se tem ações porque é rica.
  3. Dedução de que a correlação real vai manter uma relação forte para além dos dados com os quais foi demonstrada: é a velha história do “tudo em excesso faz mal”. Não podemos afirmar, como muitos em um processo de rigidez e vício numérico fazem, que sempre ao aumentarmos os dados, a correlação tende a se manter forte. Faz-se necessário um Domain Knowledge (Conhecimento de domínio) para aliar as estatísticas à realidade contextual. Uma planta não sobrevive sem água, mas experimente despejar torrentes de água nela por um tempo e veja se ela não morre!

Correlação não existe apenas entre duas variáveis

No mundo real, incontáveis variáveis influenciam sistemas e problemas diversos. Um exemplo interessante de correlação parcial mostra como tendemos a focar apenas em duas variáveis, e ignorar outras.

Temos um vício incessante de atribuir padrões, principalmente lineares, comparando duas variáveis, as quais são mais concebíveis para nós do que um problema com três ou mais variáveis.

Correlação parcial nada mais é do que o cálculo do coeficiente de correlação entre duas variáveis após remover o efeito de outras variáveis. Isso ajuda a identificar associações diretas entre variáveis sem a interferência de outras variáveis.

Um exemplo que peguei do livro “Econometria Básica” ilustra bem o ponto: Imagine que você é uma agricultor e quer prever o rendimento da colheita. Se calcularmos o coeficiente de correlação entre Y (rendimento da colheita) e X1 (chuva), suponha que o resultado é 0. Ou seja, não há correlação entre o rendimento e a chuva.

Agora suponha que temos uma outra variável X2 (temperatura). A correlação parcial entre Y (rendimento) e X2 (temperatura) é positiva; Já a correlação parcial entre X2 (temperatura) e X1 (chuva) é negativa.

Ok, lembra da correlação entre rendimento e chuva isoladamente? O resultado foi 0, certo. Mas calculando a correlação parcial entre rendimento e chuva, mantendo a temperatura constante, ela existirá e o coeficiente será positivo.

Parece confuso, mas não é. Já que a temperatura influencia tanto na colheita como na chuva de formas distintas, quando analisamos, sob essa perspectiva, a relação entre colheita e chuva, há sim uma correlação.

Viu só como é complexo considerar uma correlação real entre duas variáveis como uma dinâmica de causa e efeito comprovadas? Temos a impressão de que duas variáveis dialogam entre si de maneira isolada das demais, quando, na prática, isso se situa longe da realidade.

Por isso que o trabalho de um estatístico ou de um cientista de dados deve ser minucioso. Será que existe uma outra variável que influencia meu modelo?

Alternativas para selecionar as melhores variáveis de um modelo

Ao trabalharmos na construção de modelos de Machine Learning, uma decisão crucial se apresenta: quais variáveis incluir, e de quais variáveis abrir mão, para reduzir a dimensionalidade do modelo (como expliquei nesse artigo). Essa escolha desempenha um papel vital no desempenho e eficácia do modelo.

Vale ressaltar uma certa diferença de importâncias de variáveis também:

  1. Importância local: é o quanto uma variável se destaca para uma previsão de um dado específico. Para isso, devemos nos ater à algumas técnicas específicas de permutação, por exemplo.
  2. Importância global: é o quanto uma variável é valiosa de forma generalizada, ou seja, quando consideramos todos os dados e exemplos. Num modelo de regressão, a magnitude dos coeficientes atribuídos às variáveis (X1, X2,…, Xn) já fornece essa importância implicitamente. Em modelos de Random Forest, o atributo “feature_importances_”

Agora, iremos examinar algumas opções disponíveis para escolher as variáveis mais relevantes, além da famigerada correlação.

1. Métodos de filtro:

Métodos de filtro são usados para uma análise mais breve com testes estatísticos diversos e tem por objetivo de atribuir um score para cada feature. As features são classificadas pelo score para serem mantidas ou removidas do modelo.

A correlação é um dos métodos de filtro, e tem lá o seu papel, principalmente se soubermos usar de modo correto. Como disse anteriormente, precisamos saber quando usar o coeficiente de Pearson, e o de Spearman.

Mas lembre-se: para problemas que possuem uma dinâmica linear e/ou uma distribuição mais ou menos normal, o coeficiente de Pearson é a melhor alternativa. Em outras ocorrências, ou usamos Spearman ou algum outro método.

# Calcula a correlação de Pearson
correlation_pearson = df.corr()

# Calcula a correlação de Spearman
ccorrelation_spearman = df.corr(method='spearman')

A saída será uma matriz de correlação que exibe o coeficiente de correlação entre duas variáveis, uma na linha e outra na coluna. Ainda há alternativas para aperfeiçoar a visualização, usando gráficos como o mapa de calor no seaborn.

Outro método de filtro é o teste estatístico F. Para problemas de regressão, podemos usar o f_regression; para classificação, o f_classifier. Esse método, usado em conjunto com o SelectKBest seleciona as melhores k features com base nos teste estatísticos para regressão ou classificação.

No meu exemplo, das turbinas eólicas, selecionei apenas uma variável para mostrar qual a mais importante, mas você poderia criar uma nova base de dados com as k melhores features, definindo k no SelectKBest.

Depois, podemos apenas descobrir o score de cada feature usando o o método scores_

from sklearn.feature_selection import SelectKBest, f_regression

selector = SelectKBest(score_func=f_regression, k=1) #K = 1: Selecionar a melhor característica.

# Obtendo os scores das features
feature_scores = selector.scores_

# Agora você pode examinar os scores para determinar a importância das features
for i, score in enumerate(feature_scores):
print(f"A Feature {i} tem um score de {score:.2f}")
>>> A Feature 0 tem um score de 107657.37 
>>> A Feature 1 tem um score de 327723.36
>>> A Feature 2 tem um score de 657.25

No nosso caso, a feature com o maior score, seria a “Potência Teórica”, seguida da feature “Velocidade do vento”.

Poderíamos ter determinado isso de forma mais direta fazendo:

features = x_new.transform(x)
print(features)
#Mas quais características são essas?
#Podemos descobrir usando

cols = x_new.get_support(indices=True)
x.iloc[:,cols]

Entenda que o ‘x_new’ será um novo conjunto de dados contendo apenas as features selecionadas pelo método SelectKBest, no caso apenas uma.

2. Feature Importances para modelos de Árvore

Como mencionado há algumas linhas atrás, a importância global quantifica a feature em termos gerais. E os métodos incorporados ajudam nesse sentido.

Os modelos de árvore, frequentemente usados para problemas de classificação, possuem o atributo “feature_importances_” que mensura globalmente a importância de cada variável para o modelo. Usando como referência os dados da competição do Kaggle a respeito dos passageiros do Titanic, temos:

#Considerando que já criamos o modelo de Árvore Aleatória "modelo" para 
#prever quem sobreviveria no Titanic com base em informações do passageiro

import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
import numpy as np
import pandas as pd

#...

importances = modelo.feature_importances_
indices = np.argsort(importances)
features = x.columns
plt.figure(figsize=(10,5))
plt.title('Features +importante')
plt.barh(range(len(indices)), importances[indices], color='g', align='center',linestyle="solid",alpha=0.8)
plt.yticks(range(len(indices)), [features[i] for i in indices])
plt.xlabel('Importância')
Perceba que a variável ‘Sex’, que corresponde ao gênero é a mais importante, seguida da tarifa a ser paga por cada passageiro

3. SHAP (SHapley Additive exPlanations):

Essa talvez seja a técnica mais fundamental na hora de definir a importância local das variáveis. É mais custosa computacionalmente porque analisa localmente as importâncias das variáveis e permuta todas as variáveis em inúmeras situações.

É diferente, por exemplo, a ordem de criação das variáveis. Um exemplo interessante foi dado nesse blog escrito pelo Big Data Brasil. Eles consideraram um time de futebol como exemplo.

Um jogador que entra em um time e é o primeiro atleta a jogar pela equipe (ou seja: antes dele não havia nenhum outro), vai ter uma importância muito superior ao jogador que entra por último, mesmo que este seja o melhor do mundo.

Essas permutações ajudam a mensurar bem quem é o mais importante, de modo a “recompensar” financeiramente o jogador que mais contribui, uma vez que, naturalmente, o primeiro a entrar, independente se é bom ou não, tende a ganhar uma boa grana apenas por ser o primeiro.

Uma equipe de ciência de dados num projeto pode funcionar da mesma forma. É muito difícil mensurar subjetivamente a contribuição de cada pessoa da equipe. Se perguntarmos a cada um qual o nível de auxílio, em porcentagem, que ele acha que teve, e somarmos todos, obteremos (bem) mais que 100%.

Por isso, é fundamental uma análise imparcial do problema, e o SHAP ajuda nisso. Além disso, ainda há a permutação que é influenciada pela contribuição da pessoa quando ela está no time.

Em uma frase, o Big Data Brasil afirmou que “a contribuição de cada jogador é a média de sua contribuição em relação a todas as permutações de times que não o incluem.”

Na prática, podemos calcular o SHAP de diferentes tipos de modelo. Vou priorizar alguns como:

a) TreeExplainer: Especializado em modelos baseados em árvores, como Random Forest, XGBoost, LightGBM, etc.

b) LinearExplainer: Ideal para modelos lineares.

c) KernelExplainer: Faz uma regressão linear ponderada nas variáveis preditivas e descobre como o nosso modelo chegou àquela decisão. Ele pode ser usado para uma gama de modelos, não se limitando à um tipo ou outro, como o TreeExplainer e o LinearExplainer. Precisamos passar como argumento o modelo não como objeto, mas sim como função. Por essas e outras que ele é computacionalmente mais pesado.

Vamos usar como exemplo uma base de dados de turbinas éolicas, onde queremos prever a potência real do equipamento tendo como features a potência teórica e a direção do vento.

Imagine que desenvolvemos um modelo de Regressão Linear para tal, e posteriormente um Random Forest Regressor. Aplicando o shap para verificar visualmente a importância de cada variável em cada um dos modelos:

#Shap para o modelo de Regressão Linear
explainer = shap.LinearExplainer(lr, x_tr)
shap_values = explainer.shap_values(x_te)
shap.summary_plot(shap_values, x_te, feature_names=x.columns)

#Shap para o modelo de Random Forest Regressor
explainer = shap.TreeExplainer(reg, x_tr)
shap_values = explainer.shap_values(x_te)
shap.summary_plot(shap_values, x_te, feature_names=x.columns)
SHAP para o modelo de Regressão Linear
SHAP para o modelo de Random Forest Regressor

A visualização parece complexa, mas não é. Entenda da seguinte forma:

No eixo horizontal, há os valores de SHAP que quantificam a importância da variável. No eixo vertical temos os nomes das features.

Nesse caso, criamos o explicador linear e de árvore. Para exibir, usamos o summary plot para resumir o impacto das variáveis. Mas podemos também usar o force_plot para entender o impacto em dados específicos, em vez de ter uma visão mais geral.

  1. Quanto mais a direita, maior é o impacto positivo daquela variável para a variável de interesse.
  2. Quanto mais a esquerda, maior impacto negativo para a variável de interesse

Ah, mas e as cores?

  1. Quanto mais a direita, com a cor vermelha: altos valores daquela variável impactam positivamente no modelo
  2. Quanto mais a direita com a cor azul, baixos valores daquela variável impactam positivamente no modelo
  3. Quanto mais a esquerda com a cor vermelha: altos valores daquela variável impactam negativamente no modelo
  4. Quanto mais a esquerda com a cor azul: baixos valores daquela variável impactam negativamente no modelo

Para o nosso exemplo, veja que há uma simetria em relação às cores e às direções que elas tomam, mas nem sempre é assim. Altos valores de potência teórica influenciam positivamente, como era de se esperar, na potência real. O mesmo acontece com a velocidade do vento.

Nos dois modelos, a variável “direção do vento” não parece ter tanta relevância assim.

Note que o comportamento entre o SHAP da regressão linear e da árvore aleatória se torna parecido, mas é óbvio que um é mais “confiável” que o outro, embora haja uma descrição similar.

Usando testes de R2 (coeficiente de explicação) e MSE (Mean Squared Error, ou erro quadrático médio), descobrimos que o modelo de Random Forest Regressor descreve melhor o comportamento das variáveis, portanto, é de se supor que seu SHAP Values é mais adequado.

O Shap ainda possui outros métodos e atributos interessantes para mensurar o quão valiosa é uma variável. O shap.force_plot, como mencionei mais acima, calcula a importância individual das variáveis para cada dado analisado. Vejamos um exemplo de uma observação específica do dataset das turbinas eólicas:

Cada observação tem um force_plot individual onde as variáveis que estão com a cor azul puxam a predição pra valores baixos, e as que são coloridas em vermelho puxam a predição pra valores altos. O tamanho de cada barra colorida diz respeito à magnitude dessa característica que influencia no modelo.

O Output Value (no caso 3,253.62) é como um ponto de equilíbrio em um cabo de guerra entre as variáveis azuis (que tendem a puxar a predição para baixo) e as variáveis vermelhas (que tendem a puxar a predição para cima).

Note que há também o Base Value (no caso 1,563), que representa o ponto de partida para as predições do modelo, isto é, o ponto onde para um exemplo em particular, quando nenhuma feature é considerada, o modelo prevê um valor médio. Essa predição média é chamada de “Base Value”.

No nosso caso, para uma observação escolhida aleatoriamente (uma turbina), a velocidade do vento e a potência teórica contribuem significativamente para o aumento na predição, enquando a direção do vento nem aparece no gráfico.

Se você subtrair o comprimento das barras azuis do comprimento das barras vermelhas, isso equivale à distância do valor de referência para a saída.

Em outras palavras, a diferença entre o comprimento das barras azuis e das barras vermelhas no gráfico do Force Plot equivale à diferença entre o Output Value (a predição específica para uma observação) e o Base Value (a predição média do modelo sem levar em conta nenhuma característica específica).

Essa diferença representa o impacto das características da observação na predição final do modelo.

Isso reflete o valor previsto para a variável alvo com base nas características específicas daquela observação.

Podemos também visualizar facilmente o o gráfico de barras do SHAP Values para modelos de classificação. Tome como exemplo o dataset do Titanic novamente:

import shap
explainer = shap.KernelExplainer(modelo.predict_proba,x[:100])
shap_values = explainer.shap_values(x[:100])
shap.summary_plot(shap_values, x[:100])

Note que usamos o predict_proba para prever a probabilidade de uma observação pertencer à determinada classe (0 ou 1). Nesse caso, conseguimos mensurar a partir do eixo horizontal (que representa o SHAP Value, ou seja a magnitude da importância daquela variável para a predição geral do modelo) como cada feature interfere no modelo.

4. Permutação

A permutação segue um princípio parecido com o SHAP, mas é menos robusto e e mais econômico computacionalmente. Se quisermos trabalhar com a famosa biblioteca Scikit Learn, o nome real do módulo é “permutation_importance” , presente nos algoritmos de inspeção.

Esse comando embaralha os valores de uma variável e observa como isso afeta o desempenho do modelo. Como resultado, podemos obter um Data Frame quantificando cada valor de importância da variável para o modelo.

Tomando como exemplo o mesmo algoritmo que procura determinar potência real de uma turbina eólica com base em dados como: Velocidade do vento, direção do vento e potência teórica, obtemos o seguinte:

#Permutação:
from sklearn.inspection import permutation_importance

# Supondo que 'modelo' seja o modelo de Random Forest Regressor
results = permutation_importance(modelo, x_te, y_te, n_repeats=30, random_state=46)

# Importâncias das features
perm_importance = results.importances_mean

# Nomes das features
feature_names = x_te.columns # Supondo que 'x_test' seja um DataFrame do Pandas

# Criando um DataFrame para visualizar os resultados
importance_df = pd.DataFrame({'Feature': feature_names, 'Importance': perm_importance})

# Exibindo as importâncias
display(importance_df)
A velocidade do vento e a potência teórica tem a maior importância para o conjunto, de acordo com o teste de permutação. a variável direção do vento não apresentou influências consideráveis.

5. Métodos de regularização

Em uma regressão linear tradicional, o objetivo é minimizar a soma dos quadrados dos resíduos (RSS) entre as previsões do modelo e os valores reais.

Por outro lado, há outros tipos de regressão que aplicam penalidades às features menos importantes. O objetivo é minimizar a soma dos quadrados dos resíduos mais o termo de regularização, o que resulta em coeficientes menores e mais estáveis.

As principais ferramentas para tal são a regressão Ridge (Penalidade L2) e a regressão Lasso (Penalidade L1). É importante acrescentar que esse tipo de abordagem é um método incorporado, isto é, técnicas próprias de um modelo específico, já integradas no algoritmo utilizado.

Se você acredita que nem todas as variáveis disponíveis são relevantes para a previsão em voga, a Lasso pode ser a alternativa escolhida.

Isso porque ela tende a reduzir os coeficientes de algumas variáveis a zero, realizando automaticamente a seleção de variáveis e resultando em um modelo mais enxuto.

Por outro lado, a grosso modo, a Ridge faz algo similar mas não reduz os coeficientes das features à zero, apenas os diminui.

6. Redução de dimensionalidade

Usar algoritmos como o LDA e PCA podem ajudar não a selecionar exatamente as features importantes, mas a reduzir a dimensionalidade do modelo, ou seja, eliminar o peso de variáveis não importantes para o problema em questão.

Não é um método muito cristalino para o cientista de dados quanto à mensuração da importância das features, mas resolve por baixo dos panos o problema da dimensionalidade, dando atenção às variáveis “certas”.

--

--

Matheus Vasconcelos

A Telecommunications Engineering student, passionate about science, programming, and data analysis.