Как интерпретировать и объяснить любую модель машинного обучения с помощью SHAP

Ценность Шепли — это концепция, полученная из теории кооперативных игр в экономике, которая присваивает ценность каждому игроку в совместной игре на основе их вклада в игру. В области машинного обучения эта концепция была адаптирована в рамках SHAP (Shapley Additive ExPlanations), которая представляет собой эффективный метод интерпретации работы модели.

Если вам интересно узнать больше о ценностях Шепли, я настоятельно рекомендую ознакомиться с моей предыдущей статьей о математике и интуиции, лежащих в основе ценностей Шепли. Несмотря на то, что он был модифицирован для целей машинного обучения, понимание его основных принципов может быть полезным.



Инфраструктура SHAP похожа на Shapley Values ​​в том, что она рассчитывает индивидуальное влияние функций в игре (также известная как модель машинного обучения). Однако модели машинного обучения — это некооперативные игры, а это означает, что функции не обязательно взаимодействуют друг с другом, как в кооперативных играх. Вместо этого каждая функция независимо влияет на результат модели. Хотя можно использовать формулу значений Шепли, она может быть дорогостоящей в вычислительном отношении и неточной из-за большого количества вовлеченных игроков и коалиций. Чтобы решить эту проблему, исследователи разработали альтернативные методы, такие как метод Монте-Карло и методы на основе ядра. В этой статье мы углубимся в метод Монте-Карло.

Давайте установим это на примере. Скажем, у нас есть набор данных цен на 20 640 домов в Калифорнии.

from sklearn.datasets import fetch_california_housing
import pandas as pd

# load dataset
housing = fetch_california_housing()
X, y = housing.data, housing.target
X = pd.DataFrame(X, columns=housing.feature_names)
# feature dataset
X = X.drop(['Population', 'AveBedrms', 'AveOccup'], axis=1)

Мы будем использовать функции MedInc, HouseAge, AveRooms, Latitude, и Longitude (X)…

…чтобы предсказать цену дома (y). Примечание. Цены на жилье указаны в 100 000 долларов США.

Давайте построим модель. Это может быть любая модель, но мы будем использовать XGBoost (прочитайте мою предыдущую статью, чтобы изучить математику XGBoost). Следуя стандартным шагам — разделите данные на обучающие и тестовые наборы и обучите модель на обучающем наборе.

# split data into train and test
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# train an XGBoost model
from xgboost import XGBRegressor
model = xgb.XGBRegressor(objective='reg:squarederror', random_state=4)
model.fit(X_train, y_train)

Затем используйте эту модель, чтобы делать прогнозы на тестовом наборе.

y_pred = model.predict(X_test)

Давайте разберем это дальше. Нам нужна прогнозируемая цена дома для первого образца (или дома) в нашем тестовом наборе. Итак, для первого образца с этими значениями признаков…

X_test.iloc[0,]
MedInc         4.151800
HouseAge      22.000000
AveRooms       5.663073
Latitude      32.580000
Longitude   -117.050000

…прогнозируемая цена дома:

y_pred[0]
> 1.596

Прогноз, сделанный XGBoost, кажется загадочным, поскольку это модель черного ящика, поэтому мы не видим, что происходит внутри ящика. Чтобы лучше понять, как было предсказано значение, нам нужно понять две вещи:

  • Влияют ли характеристики на прогнозируемую цену дома положительно или отрицательно? (Например, приводит ли более высокое значение MedInc к увеличению прогнозируемой цены на жилье?)
  • Какова степень этих влияний? (Например, оказывает ли MedInc большее влияние на прогнозируемую цену дома, чем AveRooms?)

Чтобы ответить на эти вопросы и определить вклад каждой функции в прогноз цены дома 1,596, мы можем полагаться на значения SHAP функций.

Давайте начнем с расчета значения SHAP MedInc для прогноза 1,596, выполнив следующие действия:

Шаг 0: Рассчитайте ожидаемую прогнозируемую цену дома

Ожидаемая прогнозируемая цена дома — это не что иное, как среднее значение всех сделанных прогнозов. Который:

y_pred.mean()
> 2.07

Таким образом, 2,07 служит ожидаемой прогнозируемой ценой дома. Сейчас мы пытаемся выяснить, почему прогнозируемое значение 1,596 отличается от ожидаемого прогноза 2,07. Откуда расхождение в 0,476 (2,07–1,596)?

Значение SHAP функции измеряет, насколько эта функция способствовала смещению прогноза модели в сторону / к ожидаемому прогнозируемому значению.

Шаг 1: Получите случайную перестановку функций

Мы начали с этой перестановки функций…

…и после случайной перетасовки получаем вот что:

Здесь нас интересует MedInc, поэтому давайте выделим MedInc и любую функцию справа от него.

Шаг 2. Выберите случайную выборку из набора данных.

Возвращаемся к нашему тестовому набору данных и выбираем из него случайную выборку:

Шаг 3: Сформируйте два новых образца

Эти сэмплы будут частично сформированы из исходного семпла…

…и новый образец, который мы только что вытащили на шаге 2:

Первый созданный нами образец, названный x1, будет содержать все те же значения, что и исходный образец, за исключением функций справа от MedInc. Для функций справа от MedInc мы получаем из нового образца.

Второй образец, который мы создадим, с именем x2, будет содержать все значения из исходного образца, кроме функций справа от MedInc и MedInc.

Из этого мы можем видеть, что это точные примеры образцов, за исключением одного ключевого момента — они различаются по значению MedInc, функции, которая нас интересует.

Шаг 4. Используйте новые выборки, чтобы делать прогнозы и находить разницу в прогнозах.

Теперь мы прогоняем эти выборки через нашу модель и получаем для них прогнозы.

И находим разницу между этими значениями:

Поскольку единственная разница между x1 и x2 заключается в значении MedInc, эта разница представляет собой изменение прогноза при изменении значения MedInc.

Шаг 5. Повторите шаги 1–4 несколько раз, а затем рассчитайте среднее значение различий.

Все, что мы делаем сейчас, это повторяем описанный выше процесс и вычисляем среднее значение всех значений разницы, найденных на шаге 4.

Предположим, что мы повторяем этот процесс 1000 раз (это число может варьироваться в зависимости от сложности модели и набора данных). После усреднения результатов мы получили значение 0,22.

Это 0,22 представляет собой значение SHAP для MedInc в первой выборке, что означает, что MedInc вносит +0,22 в корректировку ожидаемого прогноза 2,07 к нашему прогнозу 1,596.

Мы можем применить тот же процесс к другим функциям — HouseAge, AveRooms, Latitude и Longitude, чтобы найти их значения SHAP.

Теперь, когда мы понимаем основные расчеты SHAP, мы можем применить их к нашим прогнозам, визуализируя их. Чтобы визуализировать их, мы будем использовать Explainer из библиотеки Python shap и введем нашу модель.

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

Это даст нам значения SHAP для всех функций (MedInc, HouseAge, AveRooms, Latitudeи Longitude) для каждого образца в тесте. набор. Используя эти значения SHAP, давайте построим график.

1. Сюжет с водопадом

Этот график помогает нам визуализировать значения SHAP для каждого образца в наших данных по отдельности. Давайте визуализируем значения SHAP для первого образца.

# visualize the SHAP values of the first sample
shap.plots.waterfall(shap_values[0])

Обратите внимание, что ожидаемое прогнозируемое значение E[f(X)] = 2,07, которое является значением, рассчитанным на шаге 0, и прогнозируемая цена дома для первого дома, f(X) = 1,596, является нашим прогнозом для первой выборки.

Обратите внимание, что значение SHAP для MedInc равно +0,22 (которое мы видим на шаге 5), значение SHAP для Longitude равно -2,35 и т. д. Если мы сложим и вычтем все приведенных выше значений SHAP до 2,07 и обратно, соответственно, мы получаем прогнозируемое значение 1,596 для первого дома.

Не обращая внимания на знаки, величина значения SHAP для долготы, 2,35, больше, чем у других функций. Это означает, что долгота оказывает наибольшее влияние на этот конкретный прогноз.

Точно так же, как мы визуализировали значения SHAP для первого образца, мы можем визуализировать значения SHAP и для второго образца.

# visualize the SHAP values of the second sample
shap.plots.waterfall(shap_values[0])

Сравнивая значения SHAP для первого и второго домов в наших тестовых данных, мы наблюдаем существенные различия. В первом доме Долгота оказала наибольшее влияние на прогнозируемую цену, а во втором доме MedInc — самое заметное влияние.

ПРИМЕЧАНИЕ. Эти различия в значениях SHAP подчеркивают уникальный вклад каждой функции в выходные данные модели для каждого образца. Важно понимать эти вклады, чтобы укрепить доверие к процессу принятия решений модели и убедиться, что он не является предвзятым или дискриминационным.

2. Принудительный сюжет

Другой способ визуализировать вышеизложенное — это силовой график.

shap.plots.force(shap_values[0])

3. Средний график SHAP

Чтобы определить, какие функции обычно наиболее важны для прогнозов нашей модели, мы можем использовать гистограмму средних значений SHAP по всем наблюдениям. Взятие среднего значения абсолютных значений гарантирует, что положительные и отрицательные значения не компенсируют друг друга.

shap.plots.bar(shap_values)

Каждая функция имеет соответствующую полосу, высота которой соответствует среднему значению SHAP. Например, на нашем графике функция с наибольшим средним значением SHAP — это Широта, что указывает на то, что она оказывает наиболее существенное влияние на прогнозы нашей модели. Эта информация может помочь нам понять, какие функции имеют решающее значение для процесса принятия решений модели.

4. Пчелиный заговор

График пчелиного тепла — это полезная визуализация для изучения всех значений SHAP для каждой функции. На оси Y значения SHAP сгруппированы по функциям, при этом цвет точек указывает на соответствующее значение функции. Как правило, более красные точки представляют более высокие значения характеристик.

Теплый график может помочь определить важные взаимосвязи между функциями и прогнозами модели. На этом графике функции упорядочены по их средним значениям SHAP.

shap.plots.beeswarm(shap_values)

Изучая значения SHAP на графике пчелиного тепла, мы можем начать понимать природу взаимосвязей между функциями и прогнозируемой ценой дома. Например, для MedInc мы наблюдаем, что значения SHAP увеличиваются по мере увеличения значения признака. Это говорит о том, что более высокие значения MedInc способствуют более высоким прогнозируемым ценам на жилье.

Напротив, для широты и долготы наблюдается противоположная тенденция: более высокие значения характеристик приводят к более низким значениям SHAP. Это наблюдение означает, что более высокие значения широты и долготы связаны с более низкими прогнозируемыми ценами на жилье.

5. Графики зависимости

Чтобы получить более глубокое понимание взаимосвязей между отдельными функциями и соответствующими им значениями SHAP, мы можем создать графики зависимостей. График зависимости — это точечная диаграмма, показывающая взаимосвязь между значением SHAP и значением признака для одного признака.

shap.plots.scatter(shap_values[:,"MedInc"])

shap.plots.scatter(shap_values[:,"Latitude"])

Анализируя графики зависимости, мы можем подтвердить наблюдения, сделанные на графике пчелиного тепла. Например, когда мы создаем график зависимости для MedInc, мы наблюдаем положительную связь между значениями MedInc и значениями SHAP. Другими словами, более высокие значения MedInc приводят к более высоким прогнозируемым ценам на жилье.

В целом графики зависимости обеспечивают более детальное понимание сложных взаимосвязей между отдельными характеристиками и прогнозируемыми ценами на жилье.

В заключение, значения SHAP дают нам представление о том, как каждая функция влияет на выходные данные модели. Эти идеи могут быть дополнительно расширены за счет использования визуализаций. Мы можем использовать SHAP для принятия более обоснованных решений о выборе функций, улучшении модели и, в конечном итоге, для повышения производительности наших приложений машинного обучения.

Как всегда, спасибо, что включили меня в свое путешествие по машинному обучению. Отправьте мне электронное письмо по адресу [email protected] или свяжитесь со мной в LinkedIn, чтобы получить комментарии, вопросы и предложения!

Если вы хотите поддержать мою работу, рассмотрите возможность использования моей ссылки для подписки на Medium! (5 долларов в месяц, отменить в любое время).