Новый взгляд на ценности Шепли: введение в Шепли и SHAP

Краткое введение в значения Shapley и библиотеку Python SHAP

О чем этот пост?

Этот пост является первым из серии из двух (на данный момент) постов об объяснении статистических моделей с помощью значений Шепли. Я могу придумать две основные причины, по которым вы могли бы захотеть его прочитать (помимо, знаете ли, для развлечения):

  1. Чтобы узнать о значениях Шепли и библиотеке Python SHAP. В конце концов, это то, о чем этот пост. Приводимые в нем объяснения далеко не исчерпывающие и не содержат ничего, что нельзя было бы получить из других онлайн-источников, но он все же должен служить хорошим быстрым введением или дополнительным чтением по этому вопросу.
  2. В качестве введения или для краткого освежения информации перед прочтением следующего сообщения о наивных ценностях Шепли. Следующий пост - моя попытка внести новый вклад в тему ценностей Шепли в машинном обучении. Возможно, вы уже знакомы с SHAP и Шепли и просто просматриваете этот пост, чтобы убедиться, что у нас есть точки соприкосновения, или вы можете здесь, чтобы прояснить что-то непонятное из следующего поста.

Что такое ценности Шепли?

Существует множество онлайн-источников, объясняющих эту тему, поэтому мое объяснение здесь будет кратким. Я особенно рекомендую эту главу Интерпретируемого машинного обучения Кристофа Мольнара для более подробного объяснения. Я также обнаружил, что изучение математической формулы (ниже или в Википедии), пока я не получил ее, дало мне лучшее интуитивное понимание этой концепции.

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

Давайте рассмотрим пример: допустим, у нас есть команда, которой нужно выполнить задачу. Каждый член команды дает дополнительные 20% шансов на успех в решении задачи, но у одного члена команды, A, есть специальный инструмент, который гарантирует 90% -ный шанс успеха, пока есть как минимум один дополнительный член в команде. Если наша команда сегодня состоит из трех человек, A, B и C - с общим шансом на успех 90% - насколько каждый вносит свой вклад в этот шанс?

Давайте вычислим это для члена команды C, используя все возможные комбинации, не содержащие их:

Применяя формулу (первый член суммы в формуле Шепли равен 1/3 для {} и {A, B} и 1/6 для {A} и {B}), мы получаем значение Шепли, равное 21,66% для члена команды C. Член команды B, естественно, будет иметь такое же значение, а повторение этой процедуры для A даст нам 46,66%. Важнейшей характеристикой ценностей Шепли является то, что вклад игроков всегда составляет окончательный результат: 21,66% + 21,66% + 46,66% = 90%.

Ценности Шепли в машинном обучении

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

Основная проблема с получением значений Шепли - вычислительная сложность - в частности, тот факт, что для их вычисления требуется 2ᴹ (где M - количество функций). Независимо от того, насколько укомплектован ваш графический процессор, экспоненциальная сложность почти всегда является препятствием (просто подумайте, сколько это шагов, когда ваши функции, например, 20x20 пикселей изображения). В теоретической литературе эта проблема чаще всего решается методами выборки - вместо того, чтобы перебирать все возможные коалиции признаков, оцените значение Шепли, используя их подвыборку (если вас это интересует, см., Например, Castro et al. 2009 , Кастро и др., 2017 или Бенати и др., 2019 ).

Войдите в библиотеку Python SHAP

Библиотека SHAP - недавнее и мощное дополнение к инструментарию специалистов по анализу данных. Он предоставляет три основных класса объяснителей - TreeExplainer, DeepExplainer и KernelExplainer. Первые два специализируются на вычислении значений Шепли для древовидных моделей и нейронных сетей соответственно и реализуют оптимизацию, основанную на архитектуре этих моделей. Объяснение ядра - это слепой метод, работающий с любой моделью. Я объясню эти классы ниже, но для более подробного объяснения того, как они работают, рекомендую эту главу.

KernelExplainer

Подход KernelExplainer к вычислению значений Шепли можно резюмировать в следующих двух основных моментах:

  1. Вместо перебора всех 2возможных перестановок функций, выполняется выборка небольшого подмножества. Количество выборок по умолчанию: nsamples = 2 * M + 2048. Таким образом, если у нас есть, например, 20 функций, KernelExplainer будет выбирать 2088 / 2²⁰ или около 0,2% возможных коалиций. Коалиции выбираются не случайно; скорее, первыми будут выбраны те, которые имеют более высокий вес в формуле Шепли (так, сначала будут включены коалиции из 0 или M-1 функций, которые наиболее информативны в отношении эффекта добавления другой функции).
  2. «Отсутствующие функции» моделируются путем усреднения прогноза модели по загруженным выборкам со значениями для этих функций, взятыми из других записей в наборе данных. Этот «фоновый» набор данных не имеет размера по умолчанию, но алгоритм предлагает 100 выборок. . Это означает, что для каждой выбранной коалиции функций алгоритм сгенерирует 100 прогнозов, каждое из которых основано на загрузочной выборке, и усреднит их. Обратите внимание, что тот факт, что результат KernelExplainer основан исключительно на выходных данных модели для различных входных данных, означает, что он будет работать для любого типа функции без каких-либо дополнительных предположений об этом.

Значение (1) состоит в том, что значения Шепли в основном оцениваются с использованием случайной выборки. Соответственно, увеличение nsamples (или размера фонового набора данных) приводит к увеличению времени выполнения (более или менее линейно) и уменьшению дисперсии в оценке (это означает, что, когда вы запускаете объяснитель несколько раз, значения Шепли будут более похожи друг на друга и на ожидаемое значение). Это легко продемонстрировать, запустив Kernel Explainer с разными значениями nsamples:

Значение (2) - обработка «отсутствующих» функций путем замены их значений суррогатными «фоновыми» данными - более сложная:

  • Во-первых, это проще всего: это дополнительный источник отклонений для оценки значения Шепли, поскольку результаты, по крайней мере, в некоторой степени зависят от выбора фонового набора данных.
  • Во-вторых, он делает предположение о независимости функций: если, например, функции x1, x2 сильно коррелированы в наших обучающих данных, заменяя значения x1 со случайными из фонового набора данных игнорирует эту зависимость и генерирует прогнозы на основе экземпляров {x1, x2}, которые вряд ли появятся в обучающий набор, что делает оценку значения SHAP менее надежной.
  • И, наконец, он представляет интерпретацию вклада функций в прогноз не как то, как они влияют на саму модель прогнозирования, а скорее как они влияют на результат уже обученной модели, если значения этих функций были неизвестный. Еще одна прекрасная возможность напомнить вам, что все это приводит к следующему посту, в котором исследуется другая интерпретация.

TreeExplainer

TreeExplainer - это класс, который вычисляет значения SHAP для древовидных моделей (Random Forest, XGBoost, LightGBM и т. Д.). По сравнению с KernelExplainer это:

  1. Точное: вместо моделирования отсутствующих элементов путем случайной выборки используется древовидная структура, просто игнорируя пути принятия решений, основанные на отсутствующих элементах. Таким образом, выходные данные TreeExplainer являются детерминированными и не зависят от фонового набора данных.
  2. Эффективно: вместо того, чтобы перебирать каждую возможную комбинацию функций (или ее подмножество), все комбинации проталкиваются по дереву одновременно с использованием более сложного алгоритма для отслеживания результата каждой комбинации, что снижает сложность с O (TL2) для всех возможных коалиций к многочлену O (TLD ² ) (где M - количество элементов, T - количество деревьев, L - максимальное количество листьев и D - максимальная глубина дерева) .

Что мы получили, используя TreeExplainer? Во-первых, мы избавились от всей дисперсии оценок на основе выборки, поскольку нам не нужно использовать фоновый набор данных или выбирать подмножество коалиций функций. Во-вторых, наши результаты больше не искажаются из-за зависимостей между функциями, поскольку они содержатся в древовидной структуре (хотя при некоторых обстоятельствах нам, возможно, придется отказаться от обоих предыдущих преимуществ). В-третьих, наше время выполнения значительно быстрее, что в некоторых случаях делает разницу между довольно быстро и неприемлемо медленно. Наконец, обратите внимание, что нет никакой разницы между двумя объяснителями с точки зрения их интерпретации вкладов функций в отношении прогнозов данной обученной модели, а не в отношении того, как они влияют на саму модель.

Подождите, а как насчет DeepExplainer?

DeepExplainer - это класс, специализирующийся на вычислении значений SHAP для моделей нейронных сетей. Я не включаю подробное объяснение этого здесь, потому что 1, мне не хватает практического опыта работы с другими объяснителями, который позволяет мне поручиться за свои объяснения по ним, и 2 , этот пост в основном является преамбулой к следующему, где объяснители SHAP будут сравниваться с подходом наивных ценностей Шепли, и это сравнение в значительной степени не имеет отношения к объяснению нейронных сетей.

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

Как я могу использовать SHAP для объяснения моих моделей?

О, это действительно просто. Просто импортируйте shap и сделайте что-нибудь вроде этого (например, для KernelExplainer):

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

Понятно! Что дальше?

Все это было сделано для того, чтобы синхронизировать нас по значениям Шепли и объяснениям SHAP. На этом вы можете остановиться и продолжить (или начать) использовать этот замечательный инструмент в своей работе. Но если вы хотите пойти немного глубже, лучше понять эту тему и, возможно, еще один инструмент в вашем наборе инструментов, продолжайте читать следующий пост!.

Первоначально опубликовано на https://edden-gerber.github.io 28 ноября 2019 г.