Implementação Prática de Análise de Explicabilidade com SHAP em Modelos de Aprendizado de Máquina Clássicos

Este guia demonstra um fluxo de trabalho completo para a análise de explicabilidade de um modelo de classificação usando a biblioteca SHAP, focando na previsão de inadimplência de crédito.

1. Pré-processamento de Dados

Os dados são carregados e transformados. Variáveis categóricas são codificadas usando mapeamento de rótulos e one-hot encoding, e valores ausentes em características contínuas são preenchidos com a moda.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")

# Configurar fonte para suporte a caracteres acentuados
plt.rcParams['font.sans-serif'] = ['DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

# Carregar o conjunto de dados
credit_data = pd.read_csv('credit_data.csv')

# Codificação de rótulos para características ordinais
posse_mapeamento = {'Própria Casa': 1, 'Aluguel': 2, 'Hipoteca': 3, 'Empréstimo Casa': 4}
credit_data['Posse Moradia'] = credit_data['Posse Moradia'].map(posse_mapeamento)

tempo_emprego_mapeamento = {
    'Menos de 1 ano': 1, '1 ano': 2, '2 anos': 3, '3 anos': 4,
    '4 anos': 5, '5 anos': 6, '6 anos': 7, '7 anos': 8,
    '8 anos': 9, '9 anos': 10, '10+ anos': 11
}
credit_data['Anos no Emprego'] = credit_data['Anos no Emprego'].map(tempo_emprego_mapeamento)

# One-Hot Encoding para a característica 'Finalidade'
credit_data_encoded = pd.get_dummies(credit_data, columns=['Finalidade'])

# Converter colunas booleanas do one-hot encoding para inteiro
colunas_originais = credit_data.columns.tolist()
novas_colunas_onehot = [col for col in credit_data_encoded.columns if col not in colunas_originais]
for col in novas_colunas_onehot:
    credit_data_encoded[col] = credit_data_encoded[col].astype(int)

# Mapeamento binário para 'Prazo'
prazo_mapeamento = {'Curto Prazo': 0, 'Longo Prazo': 1}
credit_data_encoded['Prazo'] = credit_data_encoded['Prazo'].map(prazo_mapeamento)
credit_data_encoded = credit_data_encoded.rename(columns={'Prazo': 'Longo Prazo'})

# Identificar e preencher características numéricas
colunas_numericas = credit_data_encoded.select_dtypes(include=['int64', 'float64']).columns.tolist()
for caracteristica in colunas_numericas:
    valor_mais_frequente = credit_data_encoded[caracteristica].mode()[0]
    credit_data_encoded[caracteristica].fillna(valor_mais_frequente, inplace=True)

2. Treinamento do Modelo

Os dados são divididos em conjuntos de treino e teste. Um modelo de floresta aleatória é treinado e avaliado usando métricas de classificação padrão.

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
import time

# Separar características (X) e rótulo (y)
X = credit_data_encoded.drop(['Inadimplencia'], axis=1)
y = credit_data_encoded['Inadimplencia']

# Dividir os dados (80% treino, 20% teste)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.20, random_state=2024
)

# Treinar e avaliar o modelo com parâmetros padrão
print("--- Avaliando Modelo de Floresta Aleatória Padrão ---")
inicio = time.time()
modelo_rf = RandomForestClassifier(random_state=2024)
modelo_rf.fit(X_train, y_train)
previsoes = modelo_rf.predict(X_test)
fim = time.time()

print(f"Tempo de treinamento e predição: {fim - inicio:.2f} segundos")
print("\nRelatório de Classificação no Conjunto de Teste:")
print(classification_report(y_test, previsoes))
print("Matriz de Confusão:")
print(confusion_matrix(y_test, previsoes))

3. Análise de Explicabilidade com SHAP

A biblioteca SHAP é usada para calcular os valores SHAP, que quantificam a contribuição de cada característica para as previsões do modelo.

import shap

# Inicializar o explicador SHAP para modelos baseados em árvores
explicador_shap = shap.TreeExplainer(modelo_rf)

# Calcular os valores SHAP para o conjunto de teste
# O resultado é uma lista de arrays, um para cada classe no problema de classificação
valores_shap = explicador_shap.shap_values(X_test)
print(f"Formato dos valores SHAP para a classe 0: {valores_shap[0].shape}")
print(f"Formato das características de teste: {X_test.shape}")

4. Visualização dos Resultados SHAP

Diferentes tipos de gráficos fornecem insights sobre a importância e o impacto das características.

# 1. Gráfico de Barras: Importância global das características
shap.summary_plot(valores_shap[0], X_test, plot_type="bar", show=False)
plt.title("Importância das Características (Gráfico de Barras SHAP)")
plt.tight_layout()
plt.show()

# 2. Gráfico de Violino (Beeswarm): Distribuição e impacto dos valores SHAP
shap.summary_plot(valores_shap[0], X_test, plot_type="violin", max_display=10, show=False)
plt.title("Distribuição do Impacto das Características (Gráfico Violino SHAP)")
plt.tight_layout()
plt.show()

# 3. Gráfico de Dependência: Relação entre uma característica e seu impacto SHAP
shap.dependence_plot('Anos no Emprego', valores_shap[0], X_test, show=False)
plt.title("Relação de Dependência para 'Anos no Emprego'")
plt.tight_layout()
plt.show()

Tags: SHAP explicabilidade machine learning classificação floresta aleatória

Publicado em 6-7 02:26 por Thomas