Análise de Importância de Features com SHAP para Modelos de Regressão Logística

  • TreeExplainer: Otimizado para modelos baseados em árvores, como XGBoost, LightGBM e CatBoost.
  • DeepExplainer: Projetado para modelos de deep learning, com suporte para TensorFlow e Keras.
  • GradientExplainer: Outra opção para modelos de deep learning, baseada na metodologia Integrated Gradients. Suporta TensorFlow, Keras e PyTorch, mas pode ser mais lenta que o DeepExplainer.
  • KernelExplainer: Uma abordagem mais genérica que utiliza regressão linear ponderada para aproximar os valores SHAP de qualquer tipo de modelo.

Embora explaineres específicos do modelo sejam geralmente mais rápidos e eficientes, o KernelExplainer é versátil. Neste guia, demonstraremos como aplicar o SHAP a um modelo de regressão logística, utilizando gráficos de barras e gráficos de enxame (beeswarm) para visualizar a importância global das features.

Processo de Implementação

Preparação dos Dados

O primeiro passo envolve carregar e preparar o conjunto de dados. Em seguida, separamos as features e a variável alvo, e dividimos os dados em conjuntos de treino e teste.


import pandas as pd
from sklearn.model_selection import train_test_split

# Carregar os dados
dados = pd.read_csv('dataset.csv')
df = pd.DataFrame(dados)

# Definir a variável alvo e as features
variavel_alvo = 'target'
colunas_features = df.columns.drop(variavel_alvo)

# Dividir os dados em treino e teste
X_treino, X_teste, y_treino, y_test = train_test_split(
   df[colunas_features], df[variavel_alvo], test_size=0.2, random_state=0
)
 

Treinamento do Modelo

Um modelo de regressão logística é instanciado e treinado com os dados de treino.


from sklearn.linear_model import LogisticRegression

# Construir e treinar o modelo
modelo = LogisticRegression()
modelo.fit(X_treino, y_treino)
 

Criação do Explainer SHAP

Para modelos que não são baseados em árvores ou redes neurais profundas, o KernelExplainer é uma opção adequada. Ele calcula os valores SHAP para o conjunto de teste.


import shap
import numpy as np

# Instanciar o KernelExplainer com o modelo e os dados de background (X_teste como exemplo)
# É importante usar dados representativos como background. Para KernelExplainer,
# pode-se usar uma amostra dos dados de treino ou o próprio conjunto de teste.
# Aqui, usaremos X_teste para simplificar, mas em cenários reais, considere um background set.
explainer = shap.KernelExplainer(modelo.predict_proba, X_teste)

# Calcular os valores SHAP
# Para modelos de classificação binária, shap_values pode retornar uma lista de arrays
# se predizer probabilidades para ambas as classes. Aqui, pegamos os valores para a classe positiva.
shap_values_prob = explainer.shap_values(X_teste)

# Para regressão logística, shap_values retorna uma lista de arrays, um para cada classe.
# Vamos focar na segunda classe (probabilidade da classe 1)
shap_values_classe_1 = shap_values_prob[1]

# Criar o objeto Explanation para visualização
# O objeto shap_obj armazena os valores SHAP calculados.
shap_obj = explainer.expected_value

# Para visualização, o summary_plot espera os valores SHAP calculados.
# O KernelExplainer calcula uma aproximação. A saída de shap_values() é o que usamos.
# Vamos recalcular para ter o objeto Explanation correto para visualização.
# O objeto 'shap_obj' aqui é diferente do exemplo original, pois KernelExplainer
# precisa do modelo e do background_data. A forma de chamar shap_obj = explainer(...)
# é mais comum para outros explainers. Vamos seguir a documentação de summary_plot.

# O summary_plot espera os valores SHAP e os dados originais.
# Vamos usar os shap_values_classe_1 calculados anteriormente.
# Precisamos também de um array de background_data que o KernelExplainer usou.
# Para simplificar, vamos simular um objeto Explanation se necessário,
# mas summary_plot pode aceitar diretamente os valores SHAP e os dados.
# A forma mais direta com KernelExplainer é:
shap_values = explainer.shap_values(X_teste)
# KernelExplainer para classificação retorna uma lista. Pegamos a da classe positiva.
shap_values_for_plot = shap_values[1]
 

Gráfico de Baras Global

O gráfico de barras do SHAP sumariza a importância global de cada feature. Ele exibe a média dos valores absolutos de SHAP para cada feature em todo o conjunto de dados, fornecendo uma visão geral de quais features têm o maior impacto no modelo.


import matplotlib.pyplot as plt

# Plotar o gráfico de barras global
shap.summary_plot(shap_values_for_plot, X_teste, plot_type="bar", feature_names=list(colunas_features))
plt.show()
 

Gráfico de Enxame Global (Beeswarm Plot)

O gráfico de enxame (beeswarm plot) oferece uma visualização mais detalhada. Cada ponto no gráfico representa uma instância do conjunto de dados para uma feature específica. A posição horizontal do ponto indica o valor SHAP (impacto da feature na previsão), e a cor pode representar o valor original da feature (do manor para o maior). A densidade dos pontos em uma determinada região de valor SHAP mostra a frequência desse impacto.

O gráfico de barras é essencialmente uma representação agregada (média) do gráfico de enxame.


# Plotar o gráfico de enxame global
shap.summary_plot(shap_values_for_plot, X_teste, feature_names=list(colunas_features))
plt.show()
 

Tags: SHAP feature importance logistic regression explainable AI Python

Publicado em 8-26 07:36