SHAP

Visão geral

SHAP (SHapley Additive exPlanations) é uma estrutura amplamente utilizada para explicar previsões de aprendizado de máquina (machine learning), atribuindo a saída de um modelo aos seus atributos de entrada. O SHAP é agnóstico ao modelo (model-agnostic) em princípio (pode explicar qualquer modelo preditivo) e fornece explicações locais (local explanations) (por previsão individual) que podem ser agregadas em visões globais (importância de atributos (feature importance) e padrões de efeito ao longo de um conjunto de dados).

A ideia central do SHAP é usar valores de Shapley (Shapley values) da teoria dos jogos cooperativos (cooperative game theory) para distribuir o “crédito” de uma previsão entre os atributos de uma forma que satisfaça propriedades desejáveis semelhantes à equidade (axiomas). Na prática, o SHAP vem com múltiplos algoritmos — com destaque para KernelSHAP (geral, porém mais lento) e TreeSHAP (rápido e exato para ensembles de árvores (tree ensembles)) — e um conjunto de ferramentas de visualização que tornam as explicações acessíveis a praticantes.

O SHAP é frequentemente discutido junto de outros métodos de explicação pós-hoc (post-hoc), como LIME (Explicações Locais Interpretáveis e Agnósticas ao Modelo), e é central para entender as trocas (trade-offs) descritas em Explicações Globais vs. Locais.

A base teórica: valores de Shapley

Valores de Shapley na teoria dos jogos cooperativos

Na teoria dos jogos cooperativos, um conjunto de jogadores contribui para um pagamento total. O valor de Shapley atribui a cada jogador uma parcela do pagamento com base em suas contribuições marginais ao longo de todas as coalizões possíveis.

Para mapear isso para explicações em ML:

  • Jogadores → atributos de entrada
  • Pagamento → a previsão do modelo (ou uma versão transformada dela)
  • Coalizão → um subconjunto de atributos “presentes/conhecidos”

Seja:

  • $M$ o conjunto de todos os atributos, com $|M| = d$
  • $S \subseteq M$ um subconjunto de atributos que não contém o atributo $i$
  • $v(S)$ o valor da coalizão $S$ (como o modelo se comporta quando apenas os atributos em $S$ estão disponíveis)

O valor de Shapley para o atributo $i$ é:

[ \phi_i = \sum_{S \subseteq M \setminus {i}} \frac{|S|!(d-|S|-1)!}{d!} \left( v(S \cup {i}) - v(S) \right) ]

Isso é uma média ponderada da contribuição marginal do atributo ao longo de todos os subconjuntos.

Por que os valores de Shapley são atraentes: propriedades-chave (axiomas)

O SHAP herda garantias importantes dos valores de Shapley. De forma informal:

  • Eficiência (Aditividade / “conservação da saída”): as atribuições somam a diferença da previsão em relação a uma linha de base (baseline).
  • Simetria: se dois atributos contribuem de forma idêntica, recebem a mesma atribuição.
  • Dummy (jogador nulo; Null player): um atributo que nunca altera a previsão recebe atribuição zero.
  • Linearidade: explicações para somas de modelos equivalem a somas de explicações.

Essas propriedades tornam as explicações do SHAP mais fundamentadas do que muitos métodos heurísticos de atribuição, especialmente quando você quer consistência e comparabilidade.

SHAP como um modelo aditivo de atribuição de atributos

As explicações do SHAP geralmente são apresentadas como uma decomposição aditiva de uma única previsão:

[ f(x) = \phi_0 + \sum_{i=1}^{d} \phi_i ]

Onde:

  • $f(x)$ é a saída do modelo para a instância de entrada $x$
  • $\phi_0$ é o valor base (frequentemente a saída esperada do modelo em um conjunto de dados de fundo (background dataset))
  • $\phi_i$ é a atribuição do atributo $i$ para esta instância específica

Por isso, diz-se que o SHAP produz explicações locais: cada previsão recebe seu próprio conjunto de valores $\phi_i$.

O que é o “valor base”?

O valor base $\phi_0$ é tipicamente:

[ \phi_0 = \mathbb{E}[f(X)] ]

estimado sobre um conjunto de dados de fundo (também chamado de conjunto de referência). Intuitivamente, os valores $\phi_i$ explicam como passamos da “saída típica” para a saída deste exemplo específico.

Importante: o valor base depende de quais dados você escolhe como “fundo”, o que pode alterar materialmente sua explicação (ver armadilhas abaixo).

O que é a “função de valor” \( v(S) \) em ML?

Em explicações de ML, $v(S)$ geralmente é definida via uma expectativa sobre atributos ausentes/não observados:

  • SHAP condicional (Conditional SHAP; sensível à dependência entre atributos):
    [ v(S) = \mathbb{E}[f(X)\mid X_S = x_S] ]
  • SHAP intervencional (Interventional SHAP; suposição de independência entre atributos):
    Substitui atributos ausentes por amostras obtidas independentemente a partir da distribuição de fundo.

Diferentes implementações de SHAP aproximam essas ideias de maneiras distintas, e essa escolha é central quando os atributos são correlacionados.

Variantes comuns de SHAP e quando usá-las

A estrutura do SHAP é geral; diferentes algoritmos calculam/aproximam valores de Shapley sob suposições diferentes.

KernelSHAP (agnóstico ao modelo)

O KernelSHAP aproxima valores de Shapley ajustando um modelo linear local ponderado (weighted local linear model) ao redor da instância que está sendo explicada. Ele trata o modelo como uma caixa-preta (black box) que pode ser consultada.

  • Prós
    • Funciona com qualquer modelo (redes neurais, SVMs, pipelines, APIs proprietárias)
    • Tem uma base clara fundamentada em Shapley
  • Contras
    • Pode ser lento (muitas avaliações do modelo)
    • Requer escolher um conjunto de dados de fundo
    • É sensível a atributos correlacionados e à seleção do conjunto de fundo

O KernelSHAP é conceitualmente próximo do LIME, mas com ponderação inspirada em Shapley e restrições aditivas.

TreeSHAP (rápido, exato para árvores)

O TreeSHAP explora a estrutura de árvores de decisão (decision trees) para calcular valores de Shapley de forma eficiente.

  • Prós
    • Muito rápido para ensembles de árvores (XGBoost, LightGBM, CatBoost, árvores do scikit-learn)
    • Frequentemente exato (ou muito próximo) para modelos de árvore comuns
    • Amplamente usado em ML tabular
  • Contras
    • Principalmente para modelos baseados em árvore
    • Ainda sujeito a armadilhas de interpretação (correlações, linha de base, espaço de saída)

O TreeSHAP é um dos motivos pelos quais o SHAP se popularizou: ele torna explicações locais de alta qualidade viáveis em escala.

Outras variantes que você pode encontrar

  • LinearSHAP: eficiente para modelos lineares (geralmente direto).
  • DeepSHAP / GradientSHAP: aproximações para redes profundas (menos “universalmente exatas” do que o TreeSHAP; frequentemente dependem de referências de fundo e suposições sobre gradientes).
  • Valores de interação SHAP (SHAP interaction values): estendem o SHAP para interações par-a-par, decompondo atribuições em efeitos principais e efeitos de interação.

Do local ao global: agregando valores SHAP

Embora o SHAP seja fundamentalmente local, você pode obter insights globais ao agregar em muitas instâncias.

Resumos globais comuns incluem:

  • Valor SHAP médio absoluto por atributo
    [ \text{importance}(i) = \frac{1}{n}\sum_{j=1}^{n} |\phi_i^{(j)}| ] Esta é uma medida popular de importância global de atributos.

  • Gráficos de enxame (beeswarm) / gráficos de resumo (summary plots)
    Mostram a distribuição de valores SHAP por atributo, frequentemente coloridos pelo valor do atributo. Isso revela:

    • quais atributos mais importam no geral
    • se valores mais altos do atributo tendem a aumentar ou diminuir previsões
    • heterogeneidade e outliers
  • Gráficos de dependência (dependence plots)
    Plotam valor do atributo vs. valor SHAP, opcionalmente coloridos por outro atributo para revelar interações. Isso frequentemente fornece uma visão mais fiel do que um raciocínio simples baseado em correlação, porque está ligado ao comportamento do modelo.

Cuidado: resumos globais de SHAP descrevem o comportamento do modelo, não necessariamente efeitos causais no mundo real.

Uso prático: exemplos em Python

Os exemplos abaixo usam a API moderna da biblioteca shap (shap.Explainer) sempre que possível.

Exemplo 1: TreeSHAP com uma árvore com gradient boosting (regressão tabular)

import shap
import xgboost as xgb
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split

# Data
X, y = fetch_california_housing(return_X_y=True, as_frame=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# Model
model = xgb.XGBRegressor(
    n_estimators=400,
    max_depth=4,
    learning_rate=0.05,
    subsample=0.9,
    colsample_bytree=0.9,
    random_state=0
)
model.fit(X_train, y_train)

# SHAP: auto-selects TreeExplainer for tree models
explainer = shap.Explainer(model, X_train)  # background = X_train
shap_values = explainer(X_test)

# Global summary
shap.plots.beeswarm(shap_values)

# Local explanation for one instance
idx = 0
shap.plots.waterfall(shap_values[idx])

O que observar:

  • O valor base (previsão esperada no conjunto de fundo).
  • Quais atributos empurram a previsão para cima vs. para baixo em relação ao valor base.
  • Se a importância global se alinha às expectativas do domínio (e investigar quando não se alinha).

Exemplo 2: KernelSHAP para um classificador caixa-preta

Suponha que você tenha um modelo em que apenas predict_proba está disponível. O KernelSHAP pode funcionar, mas você deve gerenciar o custo e escolher um conjunto de fundo razoável.

import shap
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier

X, y = load_breast_cancer(return_X_y=True, as_frame=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

clf = RandomForestClassifier(n_estimators=300, random_state=0)
clf.fit(X_train, y_train)

# Pick a small background sample to reduce cost
background = shap.sample(X_train, 100, random_state=0)

# Wrap the model output you want to explain: probability of class 1
def f_proba(X):
    return clf.predict_proba(X)[:, 1]

explainer = shap.KernelExplainer(f_proba, background)
# nsamples controls approximation quality vs runtime
shap_values = explainer.shap_values(X_test.iloc[:10], nsamples=500)

# Visualize one prediction
shap.force_plot(explainer.expected_value, shap_values[0], X_test.iloc[0], matplotlib=True)

Notas práticas:

  • O KernelSHAP escala mal com a contagem de atributos; considere agrupamento de atributos, menos pontos de fundo ou menos amostras explicadas.
  • Seja explícito sobre qual saída você está explicando (probabilidade, log-odds, score).

Considerações práticas que importam em projetos reais

Escolhendo o conjunto de dados de fundo (escolha da linha de base)

Seu conjunto de fundo define o que “atributos ausentes” significam e o que o valor base representa.

Escolhas comuns:

  • Amostra dos dados de treino (quase padrão): explica em relação à distribuição típica de treino.
  • Um subgrupo específico (por exemplo, “candidatos aprovados”): explica em relação a uma população de referência (útil, mas pode ser politicamente/eticamente sensível).
  • Linha de base do domínio (por exemplo, faixas clinicamente normais): às vezes preferível para interpretabilidade, mas pode estar fora da distribuição do modelo.

Diretriz: escolha uma linha de base que corresponda à pergunta que você está respondendo (depuração, auditoria, explicação voltada ao usuário) e documente-a.

Lidando com pré-processamento e atributos codificados

O SHAP explica as entradas do modelo. Se seu pipeline usa:

  • codificação one-hot (one-hot encoding)
  • codificação por alvo (target encoding)
  • embeddings aprendidos (learned embeddings)
  • padronização (standardization)

então atribuições SHAP “brutas” podem estar em atributos transformados. Abordagens:

  • Explicar o pipeline completo (encapsular pré-processamento + modelo).
  • Agrupar atributos one-hot em um único atributo humano (por exemplo, somar valores SHAP para todos country_*).
  • Preferir codificações interpretáveis quando explicação é um requisito central.

Saídas em classificação: probabilidade vs log-odds

Para classificadores, você pode explicar diferentes espaços de saída:

  • Probabilidade é intuitiva, porém não linear; atribuições aditivas podem ser mais difíceis de interpretar perto de saturação em 0/1.
  • Logaritmo das chances (log-odds) frequentemente se comporta de forma mais linear para explicações aditivas.

Muitas ferramentas de SHAP para classificadores de árvore historicamente usaram logaritmo das chances por padrão. Sempre confirme o que você está plotando e comunicando.

Dicas de desempenho e escalabilidade

  • Para TreeSHAP: geralmente é viável explicar muitas linhas, mas ainda assim considere amostragem em conjuntos de dados grandes.
  • Para KernelSHAP:
    • reduza o tamanho do conjunto de fundo (por exemplo, 50–200)
    • explique um subconjunto de instâncias
    • reduza a dimensionalidade de atributos ou agrupe atributos
    • ajuste nsamples (mais amostras → melhor aproximação, maior custo)

Armadilhas de interpretação e limitações

Atributos correlacionados (dependentes)

Valores de Shapley assumem que você consegue raciocinar sobre adicionar/remover atributos. Porém, quando atributos são correlacionados (por exemplo, income e education), “remover” um atributo mantendo o outro fixo pode criar combinações irreais.

Consequências:

  • O SHAP pode dividir o crédito entre atributos correlacionados de maneiras pouco intuitivas.
  • As atribuições podem mudar significativamente dependendo de suposições condicionais ou intervencionais.
  • A importância global pode ser enganosa quando múltiplos atributos codificam o mesmo sinal.

Mitigações:

  • Agrupar atributos correlacionados (tratá-los como um único “jogador”).
  • Comparar abordagens intervencionais vs. condicionais quando disponíveis.
  • Usar conhecimento de domínio: não superinterprete a divisão de atribuição entre variáveis colineares.

A escolha da linha de base muda a narrativa

Como o SHAP explica desvios a partir de um valor base, diferentes conjuntos de fundo podem produzir narrativas diferentes:

  • Um modelo pode parecer que “penaliza” um atributo sob uma linha de base, mas não sob outra.
  • Explicações voltadas ao usuário podem ser manipuladas (intencionalmente ou não) ao selecionar um conjunto de referência conveniente.

Mitigação: trate a seleção da linha de base como uma decisão de modelagem que exige justificativa e revisão.

SHAP não é causal

O SHAP descreve como o modelo usa atributos, não o que aconteceria se você interviesse no mundo real.

  • Um alto valor SHAP para “zip code” não prova que o CEP causa um resultado.
  • Variáveis proxy (proxy variables) podem carregar informação sensível, o que o SHAP pode revelar (útil para auditoria, arriscado para explicações voltadas ao usuário).

Se você precisa de raciocínio “e se”, considere complementar o SHAP com Explicações Contrafactuais e tenha cuidado com alegações causais, a menos que você tenha uma estratégia de identificação causal.

Explicações podem ser instáveis sob aproximação ou mudanças nos dados

  • O KernelSHAP é estocástico e aproximado; os resultados podem variar com nsamples e com o conjunto de fundo.
  • A deriva do modelo (model drift) ou mudança de distribuição dos dados (dataset shift) pode alterar as distribuições de SHAP ao longo do tempo.
  • Se você re-treina com frequência, acompanhe mudanças em resumos globais de SHAP como parte do monitoramento.

Vazamento de atributo e atribuições “boas demais para ser verdade”

O SHAP pode evidenciar vazamento de atributo (feature leakage): um atributo pode dominar as explicações porque codifica o rótulo (direta ou indiretamente). Isso é valioso para depuração, mas também significa que explicações podem parecer “confiantes” enquanto o modelo é falho.

Como o SHAP é usado na prática

Usos comuns no mundo real incluem:

  • Depuração de modelos: encontrar direcionadores inesperados, identificar vazamento, entender casos de borda.
  • Engenharia de atributos: identificar atributos fracos ou redundantes; diagnosticar interações.
  • Risco e conformidade: criar evidências do comportamento do modelo para revisão interna (com ressalvas cuidadosas).
  • Auditoria de justiça (fairness): comparar distribuições de SHAP entre grupos para detectar proxies ou dependência desigual de certos atributos (frequentemente junto de métricas descritas em práticas mais amplas de IA Responsável).
  • Explicações voltadas ao usuário: fornecer justificativas locais, mas apenas após cuidadosa escolha de linha de base, agrupamento de atributos e comunicação de limitações.

Boas práticas para uso responsável de SHAP

  • Declare claramente o que está sendo explicado: score do modelo, probabilidade, logaritmo das chances, saída específica por classe.
  • Justifique a linha de base/conjunto de fundo e mantenha-o consistente para comparações.
  • Valide explicações qualitativamente com especialistas de domínio e quantitativamente com verificações de sensibilidade (alterar tamanho do conjunto de fundo, checar estabilidade).
  • Trate atributos correlacionados de forma deliberada (agrupamento, suposições alternativas de dependência).
  • Evite linguagem causal a menos que sustentada por metodologia causal.
  • Use múltiplas lentes: combine SHAP com análise de erros (error analysis), dependência parcial (partial dependence) e métodos discutidos em Explicações Globais vs. Locais. Compare com LIME (Explicações Locais Interpretáveis e Agnósticas ao Modelo) quando apropriado.

Resumo

O SHAP é uma abordagem fundamentada e prática para explicabilidade, construída sobre valores de Shapley. Ele fornece atribuições locais e aditivas de atributos com fortes propriedades teóricas e dá suporte a entendimento global ao agregar explicações locais. No trabalho cotidiano de ML, o TreeSHAP é a escolha padrão para ensembles de árvores, enquanto o KernelSHAP oferece um método mais lento, porém geral, para modelos caixa-preta.

O SHAP é poderoso, mas não é infalível: atributos correlacionados, escolha da linha de base, confusão sobre o espaço de saída e interpretação não causal são as armadilhas mais comuns. Usado com cuidado — com suposições documentadas e análises complementares — o SHAP é uma das ferramentas mais eficazes para entender e comunicar o comportamento de modelos.