SHAP и интерпретируемость моделей для Data Scientist

Готовься к собесу аналитика как в Duolingo
10 минут в день — SQL, Python, A/B, метрики. 1700+ вопросов в Telegram
Открыть Карьерник в Telegram

Карьерник — Duolingo для аналитиков: 10 минут в день тренируй SQL, Python, A/B, статистику, метрики и ещё 3 темы собеса. 1500+ вопросов в Telegram-боте. Бесплатно.

Зачем интерпретируемость

Бизнес: «модель отказала клиенту в кредите — почему?». Регулятор: «объясните алгоритм». DS: «как улучшить модель?».

Главная боль без интерпретируемости — модель работает в black-box, бизнес не доверяет, регулятор требует объяснений. На собесе DS обязательно: «как объяснить решение модели?», «чем SHAP отличается от feature importance?»

В РФ для финтеха/медицины интерпретируемость — обязательная часть стека. На собесе junior — общие концепции, middle — практическое применение SHAP/LIME.

Feature importance в деревьях

tree.feature_importances_ в sklearn — статистика по splits:

  • Gini importance: среднее уменьшение нечистоты от каждого split на признаке, нормализовано
  • Split count: сколько раз признак использован

Минусы:

  • Смещена в сторону high-cardinality признаков (continuous и categorical с many levels)
  • Биас в пользу correlated features
  • Не показывает направление эффекта (положительный/отрицательный)

Когда уместно: quick sanity check. Для серьёзной интерпретации — permutation importance или SHAP.

Permutation importance

Идея: случайно перемешать значения признака, измерить падение метрики. Большое падение → важный признак.

from sklearn.inspection import permutation_importance
result = permutation_importance(model, X_test, y_test, n_repeats=10)
print(result.importances_mean)

Плюсы:

  • Model-agnostic (работает на любой модели)
  • Не смещена high-cardinality
  • Учитывает только то, что модель реально использует

Минусы:

  • Дорого (N × n_features перепрогонов)
  • На correlated features — недооценивает важность

SHAP

SHapley Additive exPlanations — game-theoretic подход.

Идея Shapley values: каждый признак — «игрок», предсказание — «выигрыш». Каждому признаку приписывается часть вклада в предсказание.

Formal:

φ_i = Σ_{S ⊆ N \ {i}} |S|! (n-|S|-1)! / n! × [v(S ∪ {i}) - v(S)]

Среднее marginal contribution по всем подмножествам признаков. Гарантирует:

  • Эффективность: сумма вкладов = полное предсказание
  • Симметрия: равные признаки получают равные вклады
  • Согласованность: если модель меняется так, что признак важнее → его SHAP не уменьшится

TreeSHAP — оптимизация для tree-based моделей. Точно вычисляет за полиномиальное время.

import shap
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_test)

shap.summary_plot(shap_values, X_test)         # global importance
shap.force_plot(explainer.expected_value, shap_values[0], X_test.iloc[0])  # one row

Плюсы:

  • Local explanations (per row) И global
  • Направление эффекта (signed)
  • Совместимость с любой моделью (KernelSHAP), быстро для деревьев (TreeSHAP)

Минусы:

  • Дорого для не-деревьев (KernelSHAP)
  • Сложно интерпретировать на correlated features
  • Объяснение приписывает вклад, не говорит «почему именно так»

В индустрии — стандарт для interpretability в табличных моделях.

Готовься к собесу аналитика как в Duolingo
10 минут в день — SQL, Python, A/B, метрики. 1700+ вопросов в Telegram
Открыть Карьерник в Telegram

LIME

Local Interpretable Model-agnostic Explanations.

Идея: возле точки x генерим возмущения, обучаем простую модель (linear) на них, объясняем через linear coefficients.

from lime.lime_tabular import LimeTabularExplainer
explainer = LimeTabularExplainer(X_train, feature_names=...)
exp = explainer.explain_instance(X_test[0], model.predict_proba)
exp.show_in_notebook()

Плюсы: быстрее SHAP на нелинейных моделях, простота интерпретации.

Минусы:

  • Случайность (разные runs → разные объяснения)
  • Стабильность хуже SHAP
  • Не гарантирует consistency

В современных проектах SHAP вытесняет LIME.

Partial dependence plots

PDP: показывает зависимость predicted output от одной feature, маржинализуя остальные.

from sklearn.inspection import PartialDependenceDisplay
PartialDependenceDisplay.from_estimator(model, X_train, features=['age', 'income'])

ICE plot (Individual Conditional Expectation): PDP per-row → видно гетерогенность эффекта.

Когда: понять «как меняется prediction при изменении возраста, при прочих равных». Не интерпретация конкретного row, а general behavior.

Грабля: PDP под ASSUMPTION независимости признаков. Если age и income сильно скоррелированы — PDP вне поддержки данных.

Частые ошибки

Использовать feature_importances_ для production-объяснений. Смещение в сторону high-cardinality. Permutation importance или SHAP.

SHAP на correlated features. Если age и income сильно correlated — SHAP «делит» вклад между ними произвольно. Использовать grouped SHAP или предварительно decorrelate.

KernelSHAP на больших данных. O(2^n_features) — невыполнимо. На trees — TreeSHAP. На NN — DeepSHAP, GradientSHAP.

Считать interpretability ≡ explainability. Interpretable model = читаемая по структуре (linear, дерево). Explainable = можно объяснить решения post-hoc (SHAP). Два разных подхода.

LIME для production. Нестабильность. Использовать SHAP.

Игнорировать sample size. Permutation importance с малым n_repeats нестабильна. Минимум 10-30 на feature.

Объяснять одним графиком. Global importance, local examples (SHAP force), PDP — каждый показывает свой угол. Использовать комбинацию.

Связанные темы

FAQ

Что такое black-box и white-box модели?

White-box — структурно интерпретируемые (linear regression, decision tree, rules). Black-box — сложные, требуют post-hoc объяснений (random forest, neural networks). SHAP — способ объяснить black-box.

TreeSHAP только для деревьев?

Да. Для не-древесных — KernelSHAP (medium-agnostic, медленный) или специфичные методы (DeepSHAP для NN, LinearSHAP для linear).

Как объяснить SHAP бизнесу?

«Каждое значение признака — это его вклад в финальное предсказание. Положительный — толкает в сторону класса 1, отрицательный — в сторону 0. Сумма всех вкладов + базовое значение = финальное предсказание». Force plot для одного клиента — самый понятный визуал.

Можно ли использовать SHAP для time series?

Можно, но осторожно — SHAP предполагает независимость features. Для time series с lag-features учесть, что они скоррелированы.

LIME быстрее SHAP?

На небольших данных LIME быстрее (KernelSHAP medium-agnostic дороже). На trees TreeSHAP — быстрее LIME.

Это официальная информация?

Нет. Статья основана на работах Lundberg & Lee (SHAP, 2017), Ribeiro et al. (LIME, 2016), документации shap, lime, sklearn.


Тренируйте Data Science — откройте тренажёр с 1500+ вопросами для собесов.