- 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()