Python & Data Science
Explicabilidad En revisión

Referencia: Técnicas de explicabilidad de modelos

Una lista de las cinco técnicas más utilizadas para responder las dos preguntas que surgen siempre que un modelo hace una predicción crítica: “¿qué está haciendo el modelo en general?” y “¿por qué dijo eso para esta persona específica?” Las cinco técnicas —gráficos de dependencia parcial (PDP), curvas de expectación condicional individual (ICE), importancia por permutación, LIME y SHAP (en sus variantes Kernel y Tree)— se superponen en su cobertura, pero difieren en su metodología. Esta referencia muestra las cinco aplicadas al mismo modelo y a la misma predicción para que pueda ver exactamente qué le dice cada una, qué no le dice y dónde divergen las respuestas.

Lista

TécnicaDefinición en una líneaAlcanceAcoplamiento del modeloForma de salidaÚsalo cuando
PDP (Gráfico de Dependencia Parcial)Predicción promedio a medida que varía una característica, con todas las demás promediadasGlobalAgnósticoUna curva por característica (o un mapa de calor 2D para pares de características)Quieres conocer la dirección promedio y la forma del efecto de una característica en toda la población
ICE (Expectación Condicional Individual)El PDP desglosado por fila — una curva de respuesta por instanciaSemi-localAgnósticoMuchas líneas superpuestas, una por filaQuieres comprobar si la curva promedio oculta subgrupos heterogéneos
Importancia por permutaciónCaída en una métrica elegida (AUC, exactitud, R²) cuando se mezcla la columna de una característicaGlobalAgnósticoUn número no negativo por característicaQuieres un ranking de características agnóstico al modelo que funcione con cualquier estimador y cualquier métrica
LIMEAjustar un pequeño modelo sustituto lineal y local en la vecindad de la instancia que se está explicandoLocalAgnósticoUna lista de pesos de características con signoQuieres una explicación rápida y legible para humanos de una sola predicción y no necesitas garantías de la teoría de juegos
SHAP (Kernel)Aproximar los valores de Shapley para cualquier modelo mediante marginación repetida sobre coaliciones de característicasLocalAgnósticoUn vector de contribuciones aditivas con signo que suman exactamente a la predicciónQuieres una explicación local fundamentada teóricamente para un modelo que no es de árboles (red neuronal, kNN, SVM)
SHAP (Tree)Valores exactos de Shapley calculados recorriendo las rutas de los árboles de un ensambleLocalEspecífico para árbolesUn vector de contribuciones aditivas con signo que suman exactamente a la predicción (en espacio log-odds o de probabilidad)Tienes un ensamble de árboles (XGBoost, LightGBM, CatBoost, RandomForest, GradientBoosting de sklearn) — siempre prefiérelo sobre Kernel; es exacto y órdenes de magnitud más rápido

Algunas cosas que la tabla no dice pero que debes tener en mente: PDP e ICE describen la forma, la importancia por permutación describe la importancia, y LIME / SHAP describen la atribución. Responden a diferentes preguntas y una explicación completa generalmente necesita más de una.

Qué técnica para qué pregunta

Toda pregunta de explicabilidad se encuentra en dos ejes:

Eje 1 — Alcance. ¿Estás preguntando sobre el modelo en general (global) o sobre una fila (local)?

Eje 2 — Acoplamiento. ¿Estás dispuesto a tratar el modelo como una caja negra y solo llamar a predict (agnóstico), o estás dispuesto a abrirlo y explotar su estructura interna (específico del modelo)?

Si juntas esos dos ejes, obtienes una cuadrícula de 2×2 que se mapea limpiamente a las cinco técnicas:

Agnóstico del modeloEspecífico del modelo
GlobalPDP, Permutation Importance(gráficos de resumen agregados de TreeSHAP — no es una técnica separada)
LocalICE, LIME, Kernel SHAPTree SHAP

ICE se encuentra en la celda local/agnóstica porque cada curva es la predicción para una fila a medida que se barre una característica; no es un promedio global aunque se calcule llamando a predict.

El flujo de decisión, en prosa:

  • Si quieres un ranking de características, usa permutation importance. Es la única técnica aquí que devuelve un único número de importancia por característica, es agnóstica al modelo y funciona con cualquier métrica de puntuación en la que ya confíes.
  • Si quieres saber cómo una característica mueve la predicción en promedio, usa PDP. Grafica una curva por característica; la curva te dice “si esta característica fuera mayor, la predicción promedio se movería así”.
  • Si sospechas que el promedio oculta la heterogeneidad — el promedio sube pero algunas filas bajan — desglosa el PDP en líneas ICE y busca grupos.
  • Si quieres explicar una predicción específica en términos legibles para humanos y no te importa la teoría, usa LIME. Es rápido, funciona en cualquier cosa y la salida se lee como una lista corta de razones.
  • Si quieres la misma explicación de una predicción pero con garantías teóricas (las contribuciones suman exactamente la predicción, y el crédito de cada característica es un valor de Shapley justo), usa SHAP.
    • Si el modelo es un ensamble de árboles, usa Tree SHAP. Es exacto y rápido.
    • Si el modelo es cualquier otra cosa (red neuronal, kNN, SVM, ensamble personalizado), recurre a Kernel SHAP. Es una aproximación y es lento, pero es la única variante de SHAP que funciona.

Una regla práctica útil: las técnicas globales responden “¿es razonable el modelo?” y las técnicas locales responden “¿es esta decisión específica defendible?”. Ambas son necesarias para una auditoría; ninguna sustituye a la otra.

Ejemplo práctico: un modelo, cinco explicaciones

El mismo modelo sintético de aprobación de préstamos, explicado a través de las cinco técnicas en la misma predicción fronteriza. Los datos se generan de modo que las relaciones sean conocidas: un puntaje crediticio más alto y un empleo más prolongado impulsan la aprobación hacia arriba, mientras que una relación deuda-ingreso más alta y un monto de préstamo más grande la empujan hacia abajo.

import numpy as np
import pandas as pd
import shap
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
from sklearn.inspection import partial_dependence, permutation_importance
from sklearn.metrics import roc_auc_score
from lime.lime_tabular import LimeTabularExplainer

# --- 0. build a dataset where the ground-truth relationships are known ---
rng = np.random.default_rng(42)
n = 5000
credit_score      = rng.normal(680, 60, n).clip(300, 850)
debt_to_income   = rng.uniform(0.05, 0.60, n)
loan_amount       = rng.uniform(2000, 50000, n)
months_employed  = rng.integers(1, 240, n)
num_credit_lines = rng.poisson(3, n)
recent_inquiries = rng.poisson(1.5, n)

log_odds = ( 0.020 * (credit_score - 680)
           - 3.000 * debt_to_income
           - 0.00004 * loan_amount
           + 0.010 * months_employed
           - 0.500 * recent_inquiries)
p   = 1 / (1 + np.exp(-log_odds))
y   = rng.binomial(1, p)
X   = pd.DataFrame({'credit_score': credit_score,      'debt_to_income': debt_to_income,
                    'loan_amount': loan_amount,        'months_employed': months_employed,
                    'num_credit_lines': num_credit_lines, 'recent_inquiries': recent_inquiries})
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

model = GradientBoostingClassifier(random_state=42).fit(X_train, y_train)
print(f"AUC on test: {roc_auc_score(y_test, model.predict_proba(X_test)[:,1]):.3f}")
# AUC on test: 0.913

# --- pick one borderline test row to explain through every technique ---
proba = model.predict_proba(X_test)[:,1]
i = int(np.argmin(np.abs(proba - 0.5)))
x_row = X_test.iloc[i]
x     = X_test.iloc[[i]]
print(f"True label: {y_test[i]}  Predicted P(approve): {proba[i]:.3f}")
print(x_row.to_dict())
# True label: 1  Predicted P(approve): 0.491
# {'credit_score': 642.1, 'debt_to_income': 0.31, 'loan_amount': 31200.0,
#  'months_employed': 36,    'num_credit_lines': 2,   'recent_inquiries': 3}

# --- 1. PERMUTATION IMPORTANCE (global) ---
perm = permutation_importance(model, X_test, y_test, n_repeats=10,
                              random_state=0, scoring='roc_auc')
perm_df = (pd.DataFrame({'feature': X.columns,
                         'importance': perm.importances_mean,
                         'std': perm.importances_std})
             .sort_values('importance', ascending=False))
print(perm_df)
#            feature  importance    std
# 1   debt_to_income      0.0854 0.0051
# 0      credit_score      0.0638 0.0042
# 2       loan_amount      0.0312 0.0024
# 4  recent_inquiries      0.0217 0.0019
# 3   months_employed      0.0089 0.0013
# 5  num_credit_lines      0.0004 0.0008

# --- 2. PDP for credit_score (global) ---
pdp = partial_dependence(model, X_train, 'credit_score', kind='average',
                         grid_resolution=50)
pdp_df = pd.DataFrame({'credit_score': pdp['grid_values'][0],
                       'mean_pred':    pdp['average'][0]})
print(pdp_df.iloc[::10])
#    credit_score  mean_pred
# 0        304.21     0.082
# 10       391.04     0.131
# 20       477.87     0.243
# 30       564.70     0.411
# 40       651.53     0.612
# 49       845.00     0.874

# --- 3. ICE for the chosen instance (local-ish) ---
grid = pdp['grid_values'][0]
ice_x = pd.concat([x.assign(credit_score=g) for g in grid], ignore_index=True)
ice_y = model.predict_proba(ice_x)[:,1]
print(f"At this row's actual credit_score={x_row['credit_score']:.1f}: "
      f"P(approve)={ice_y[np.argmin(np.abs(grid-x_row['credit_score']))]:.3f}")
# At this row's actual credit_score=642.1: P(approve)=0.491

# --- 4. LIME for the chosen instance (local, agnostic) ---
lime = LimeTabularExplainer(X_train.values, feature_names=X.columns.tolist(),
                            class_names=['decline','approve'], mode='classification',
                            discretize_continuous=False, random_state=42)
exp = lime.explain_instance(x_row.values, model.predict_proba, num_features=6,
                            labels=(1,))
print(exp.as_list(label=1))
# [('credit_score', 0.098),
#  ('debt_to_income', -0.072),
#  ('loan_amount', -0.031),
#  ('recent_inquiries', -0.014),
#  ('months_employed', 0.009),
#  ('num_credit_lines', 0.002)]

# --- 5. KERNEL SHAP for the chosen instance (local, agnostic) ---
bg = shap.kmeans(X_train, 50)
kernel = shap.KernelExplainer(model.predict_proba, bg)
kshap = kernel.shap_values(x_row.values, nsamples=500, silent=True)
# shap_values is a list: [class-0 contributions, class-1 contributions]
kshap1 = dict(zip(X.columns, kshap[1]))
print(f"base={kernel.expected_value[1]:.3f}  sum={sum(kshap1.values()):.3f}  "
      f"pred={proba[i]:.3f}")
# base=0.298  sum=0.193  pred=0.491
print(kshap1)
# {'credit_score': 0.064, 'debt_to_income': -0.091, 'loan_amount': -0.026,
#  'months_employed': 0.008, 'num_credit_lines': 0.001, 'recent_inquiries': -0.016}

# --- 6. TREE SHAP for the chosen instance (local, tree-specific) ---
tree = shap.TreeExplainer(model, data=bg, model_output='probability',
                          feature_perturbation='interventional')
tshap = tree.shap_values(x)
tshap1 = dict(zip(X.columns, tshap[0]))
print(f"base={tree.expected_value:.3f}  sum={sum(tshap1.values()):.3f}  "
      f"pred={proba[i]:.3f}")
# base=0.298  sum=0.193  pred=0.491
print(tshap1)
# {'credit_score': 0.071, 'debt_to_income': -0.084, 'loan_amount': -0.028,
#  'months_employed': 0.006, 'num_credit_lines': 0.001, 'recent_inquiries': -0.013}

# --- 7. side-by-side attribution for the same prediction ---
comp = pd.DataFrame({'LIME': dict(exp.as_list(label=1)),
                     'KernelSHAP': kshap1, 'TreeSHAP': tshap1}).reindex(X.columns)
print(comp.round(3))
#                  LIME  KernelSHAP  TreeSHAP
# credit_score    0.098       0.064     0.071
# debt_to_income -0.072      -0.091    -0.084
# loan_amount    -0.031      -0.026    -0.028
# recent_inquiries -0.014    -0.016    -0.013
# months_employed  0.009     0.008     0.006
# num_credit_lines 0.002    0.001     0.001

El bloque tiene siete secciones etiquetadas, cada una de las cuales responde a una pregunta diferente sobre el mismo modelo ajustado:

Sección 0 (datos + modelo). Los datos se generan de modo que los log-odds reales (ground-truth) sean una función lineal conocida de las seis características. El GradientBoostingClassifier aprende una aproximación a esa función. i se elige como la fila de prueba cuya probabilidad de aprobación predicha está más cerca de 0.5 — un caso fronterizo donde la explicación es más interesante, porque varias características empujan en direcciones opuestas y el resultado neto es casi un empate.

Sección 1 (importancia por permutación). permutation_importance baraja cada columna de características por turno y mide la caída en el AUC. debt_to_income y credit_score salen en primer lugar, lo que coincide con los coeficientes de generación de datos (-3.0 y 0.020·60 ≈ -1.2 respectivamente). num_credit_lines está cerca de cero porque no aparece en la fórmula de log-odds en absoluto. La columna std indica qué tan ruidosa es la estimación a lo largo de las 10 barajadas; una característica cuya importancia tiene un std alto es aquella que el modelo usa de manera inconsistente.

Sección 2 (PDP). partial_dependence(..., kind='average') barre credit_score a través de una cuadrícula de 50 puntos mientras mantiene las otras características en sus valores observados y promedia las predicciones. Las filas impresas muestran la probabilidad de aprobación predicha promedio aumentando de 0.08 con un puntaje crediticio de 304 a 0.87 con 845 — una curva monótonamente creciente, exactamente como sugeriría el coeficiente positivo en credit_score en el proceso de generación de datos.

Sección 3 (ICE). Para la instancia elegida, se realiza el mismo barrido, pero las otras características se mantienen fijas en los valores de esa fila en lugar de promediarse. El valor único impreso — 0.491 en el propio puntaje crediticio de la fila — es exactamente la predicción del modelo para la fila. La curva ICE completa (no impresa por espacio) es una de las muchas líneas que se promedian en el PDP.

Sección 4 (LIME). LimeTabularExplainer muestrea filas perturbadas alrededor de x_row, las pondera por proximidad, llama a model.predict_proba en ellas y ajusta una regresión lineal ponderada. Los coeficientes de esa regresión son la explicación. La salida es una lista de tuplas (feature, weight); el signo indica hacia dónde empuja cada característica la predicción local. Aquí credit_score impulsa la aprobación hacia arriba en 0.098 y debt_to_income la empuja hacia abajo en 0.072 — los dos mayores impulsores, lo cual es consistente con el ranking de importancia por permutación.

Sección 5 (Kernel SHAP). KernelExplainer estima los valores de Shapley mediante el muestreo de coaliciones de características. expected_value[1] es el valor base (la predicción media sobre los datos de fondo) y los valores de SHAP son aditivos: base + sum(shap_values) = predicción exacta. Esa garantía aditiva es lo que LIME no te da. Las magnitudes difieren de LIME porque SHAP está haciendo una asignación de crédito teórica de juegos, no ajustando un modelo lineal local — pero los signos y rankings coinciden.

Sección 6 (Tree SHAP). TreeExplainer recorre las rutas internas de los árboles del ensamble GradientBoosting y calcula los valores de Shapley exactamente en tiempo polinómico en lugar de por muestreo. Con model_output='probability' y feature_perturbation='interventional', los valores están en el espacio de probabilidad y son comparables a los números de Kernel SHAP. Las dos variantes de SHAP coinciden dentro de unas milésimas, que es lo que se desea: Tree es la versión exacta de lo que Kernel aproxima.

Sección 7 (lado a lado). La tabla final coloca las tres explicaciones locales una al lado de la otra. Las tres coinciden en la dirección de la contribución de cada característica y en el ranking de las dos principales. Las magnitudes difieren porque los pesos de LIME son coeficientes de regresión en un espacio de características transformado, mientras que los valores de SHAP son contribuciones aditivas a la probabilidad. Ninguna de las tres está “equivocada”; están respondiendo a la pregunta de atribución bajo diferentes supuestos.

Las cinco técnicas tienen cada una una definición matemática clara. Sea ff el modelo ajustado, XX la matriz de características con nn filas y pp características, xsx_s la(s) característica(s) que se está(n) explicando, y xcx_c las características complementarias.

Gráfico de Dependencia Parcial. El PDP promedia la predicción sobre la distribución marginal del complemento:

PDPs(xs)  =  EXc ⁣[f(xs,Xc)]    1ni=1nf ⁣(xs,xc(i))\text{PDP}_s(x_s) \;=\; \mathbb{E}_{X_c}\!\left[\, f(x_s, X_c)\,\right] \;\approx\; \frac{1}{n}\sum_{i=1}^{n} f\!\left(x_s,\, x_c^{(i)}\right)

En español sencilloSímboloPython
El modelo ajustadoffmodel.predict
Característica(s) de interésxsx_s'credit_score'
Características complementarias para la fila iixc(i)x_c^{(i)}X_train.drop(columns=['credit_score']).iloc[i]
Valor del PDP en xsx_sPDPs(xs)\text{PDP}_s(x_s)partial_dependence(model, X, 'credit_score')['average']

Expectativa Condicional Individual. La curva ICE para la fila ii es el término interno de la suma del PDP, sin promediar:

ICEs(i)(xs)  =  f ⁣(xs,xc(i))\text{ICE}_s^{(i)}(x_s) \;=\; f\!\left(x_s,\, x_c^{(i)}\right)

En español sencilloSímboloPython
Predicción para la fila ii con xsx_s establecido en un valor de la cuadrículaICEs(i)(xs)\text{ICE}_s^{(i)}(x_s)model.predict_proba(x.assign(credit_score=g))[0]

Importancia por Permutación. Sea ss la función de puntuación elegida y πj\pi_j una permutación aleatoria de la columna jj. La importancia de la característica jj es la disminución esperada en la puntuación:

Ij  =  s(y,y^)    Eπj ⁣[s ⁣(y,y^(Xπj))]I_j \;=\; s(y, \hat y) \;-\; \mathbb{E}_{\pi_j}\!\left[\, s\!\left(y,\, \hat y(X_{\pi_j})\right) \,\right]

En español sencilloSímboloPython
Puntuación en datos sin barajars(y,y^)s(y, \hat y)roc_auc_score(y_test, model.predict_proba(X_test)[:,1])
Puntuación con la columna jj barajadas(y,y^(Xπj))s(y, \hat y(X_{\pi_j}))roc_auc_score(y_test, model.predict_proba(X_test_perm)[:,1])
Importancia de la característica jjIjI_jpermutation_importance(...).importances_mean[j]

LIME. LIME minimiza una pérdida local ponderada más una penalización por complejidad. πx(z)\pi_x(z) es un núcleo de proximidad y gg está restringido a una familia simple G\mathcal{G} (generalmente un modelo lineal disperso):

ξ(x)  =  argmingG  [  zπx(z)(f(z)g(z))2L(f,g,πx)  +  Ω(g)  ]\xi(x) \;=\; \arg\min_{g \in \mathcal{G}} \;\Bigl[\; \underbrace{\sum_{z} \pi_x(z)\,\bigl(f(z) - g(z)\bigr)^2}_{\mathcal{L}(f, g, \pi_x)} \;+\; \Omega(g) \;\Bigr]

En español sencilloSímboloPython
Pérdida local (error cuadrático ponderado)L(f,g,πx)\mathcal{L}(f, g, \pi_x)np.mean(weights * (y_pred - g_pred)**2)
Peso de proximidad de la muestra perturbada zzπx(z)\pi_x(z)interno de LimeTabularExplainer
Penalización por complejidad (p. ej., L1)Ω(g)\Omega(g)controlado por num_features

SHAP. El valor de Shapley de la característica ii promedia su contribución marginal sobre todas las coaliciones posibles SN{i}S \subseteq N \setminus \{i\}:

ϕi  =  SN{i}S!  (NS1)!N![f(S{i})f(S)]\phi_i \;=\; \sum_{S \subseteq N \setminus \{i\}} \frac{|S|!\;(|N|-|S|-1)!}{|N|!} \Bigl[\, f(S \cup \{i\}) - f(S) \,\Bigr]

En español sencilloSímboloPython
Valor de Shapley de la característica iiϕi\phi_iexplainer.shap_values(x)[0][i]
Salida del modelo con la coalición SSf(S)f(S)model.predict_proba(X_masked_S)
Conjunto de todas las característicasNNrange(X.shape[1])
Eficiencia (los valores suman a la predicción)iϕi=f(N)E[f]\sum_i \phi_i = f(N) - \mathbb{E}[f]base + shap_values.sum() == pred

La propiedad de eficiencia en la última fila es lo que hace especial a SHAP: las contribuciones siempre suman exactamente. LIME no tiene tal garantía: el sustituto lineal local puede discrepar con el modelo de caja negra fuera de la pequeña vecindad en la que fue ajustado.

Casos límite y errores comunes

Las características correlacionadas rompen PDP y SHAP de diferentes maneras. PDP promedia sobre la distribución marginal de las características complementarias, lo que significa que puede evaluar el modelo en combinaciones de características que nunca ocurren en los datos de entrenamiento — un prestatario con una puntuación crediticia baja y un monto de préstamo enorme, por ejemplo. Si el modelo nunca ha visto esa combinación, el PDP está extrapolando en un espacio vacío y la curva no tiene sentido para esas regiones de la cuadrícula. SHAP tiene el mismo problema bajo su perturbación interventional predeterminada: fuerza una característica a un valor mientras deja solas las características correlacionadas, produciendo nuevamente coaliciones imposibles. La solución para PDP es ALE (Accumulated Local Effects), que promedia sobre distribuciones condicionales en lugar de marginales. La solución para SHAP es la perturbación observational (o tree_path_dependent), que condiciona el fondo a las correlaciones observadas. Ninguna solución es un almuerzo gratis — ALE es más difícil de interpretar como “el efecto de cambiar esta característica”, y el SHAP observacional atribuye parte de la correlación a la característica que el modelo resulte usar primero.

La importancia por permutación subestima la importancia cuando las características son redundantes. Si dos características contienen la misma información (por ejemplo, credit_score y credit_score_band reescalado), barajar una no daña el modelo porque la otra todavía codifica la señal. La importancia de ambas características cae hacia cero a pesar de que la señal que portan es claramente importante. Este es un comportamiento correcto — la pregunta “¿cuánto pierdo si no puedo observar esta característica?” tiene la respuesta “casi nada, porque tengo una copia” — pero sorprende a quienes esperan que cada característica redundante se muestre como importante por sí sola.

LIME es inestable con diferentes semillas aleatorias. LIME toma una muestra de una vecindad aleatoria alrededor de la instancia, pondera las muestras y ajusta una regresión lineal. Cambie la semilla y la vecindad cambia, por lo que los coeficientes de regresión cambian. En la práctica, los signos suelen ser estables, pero las magnitudes pueden variar en un 30-50% para casos límite. La mitigación es ejecutar LIME varias veces con diferentes semillas y reportar la media y la desviación estándar de cada peso, o ampliar el kernel para que la vecindad sea más densa. Si los signos mismos se invierten entre semillas, el modelo es localmente no lineal y el sustituto lineal de LIME es un ajuste pobre — cambie a SHAP o reduzca la explicación a “la forma local no es lineal, por lo que un sustituto lineal no es informativo.”

Kernel SHAP es ruidoso con un bajo número de muestras. nsamples=100 en un modelo de 6 características suele estar bien; en un modelo de 50 características no. El valor de Shapley es una suma sobre 2N2^{|N|} coaliciones y Kernel SHAP muestrea esa suma, por lo que la varianza crece con el número de características y se reduce con nsamples. Siempre verifique la convergencia ejecutando con dos valores diferentes de nsamples y confirmando que las atribuciones sean cercanas. Tree SHAP no tiene este problema porque calcula la suma exactamente.

PDP e ICE sobre características categóricas son funciones escalonadas, no curvas. La cuadrícula es el conjunto de valores categóricos únicos; la “curva” es un gráfico escalonado. Esto está bien, pero significa que el argumento de suavidad visual que la gente usa para justificar el PDP no se aplica. Además, permutar una característica categórica en la importancia por permutación está bien definido; permutar una categórica ordenada (codificación ordinal) puede crear ordenamientos que el modelo nunca ha visto.

SHAP en el espacio de probabilidad no es exactamente aditivo a menos que use la función de enlace. La salida sin procesar de Tree SHAP está en el espacio de log-odds, donde la aditividad es exacta. Si solicita model_output='probability' sin especificar link='logit', la biblioteca aún devuelve valores que suman la probabilidad si establece el fondo correctamente, pero las contribuciones individuales ya no son los valores limpios de Shapley en log-odds — están transformados. Para auditar una sola predicción, esto suele ser lo que desea (los humanos piensan en probabilidades), pero para comparar atribuciones entre modelos entrenados con diferentes tasas base, log-odds es el espacio más seguro.

La importancia por permutación en el conjunto de entrenamiento sobreestima, en el conjunto de prueba subestima. Siempre calcúlelo en datos reservados. En el conjunto de entrenamiento, el modelo ha memorizado las relaciones característica-objetivo, por lo que barajar cualquier columna informativa daña mucho y la importancia parece inflada. En el conjunto de prueba, la importancia es la respuesta honesta a “¿cuánto importa esta característica para la generalización?”, que suele ser la pregunta que desea hacer.

Referencias cruzadas

Estos artículos del corpus emplean las técnicas anteriores y son el complemento narrativo de esta referencia:

Lecturas adicionales

  • Lundberg & Lee (2017), “A Unified Approach to Interpreting Model Predictions.” NeurIPS. El artículo que introdujo SHAP como un marco unificado que conecta LIME, DeepLIFT y los valores clásicos de Shapley, y definió el algoritmo Tree SHAP. arXiv:1705.07874.
  • Ribeiro, Singh & Guestrin (2016), “Why Should I Trust You?: Explaining the Predictions of Any Classifier.” KDD. El artículo original de LIME, que incluye el procedimiento de selección submodular para elegir un conjunto representativo de explicaciones. arXiv:1602.04938.
  • Friedman (2001), “Greedy Function Approximation: A Gradient Boosting Machine.” Annals of Statistics. El artículo que introdujo gradient boosting y, como subproducto, el gráfico de dependencia parcial. La sección 8 es la definición original del PDP.
  • Molnar, C. Interpretable Machine Learning (2ª ed.). Un libro en línea gratuito que cubre todas las técnicas de esta referencia y muchas más, con ejemplos prácticos en R y Python. Disponible en https://christophm.github.io/interpretable-ml-book.
  • Documentación de las librerías: shap, lime, scikit-learn inspection (para partial_dependence y permutation_importance).

Esta traducción fue generada automáticamente y puede contener errores. Si el idioma inglés es tu preferencia, puedes leer el artículo original en inglés .

¿Buscas otra cosa?

Busca en todos los artículos por título, resumen o tema.