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

Но сначала давайте поговорим о мотивации и интересе к объяснимости в Saegus, которые мотивировали и финансировали мои исследования.

Объяснимость - теория

Объясняемость алгоритмов занимает все больше места в дискуссиях о Data Science. Мы знаем, что алгоритмы мощные, мы знаем, что они могут помочь нам во многих задачах: прогнозирование цен, классификация документов, видео рекомендации.

С этого момента об этом предсказании задают все больше и больше вопросов:
- Этично ли оно?
- На него влияет предвзятость?
- Используется ли оно по правильным причинам?

Во многих областях, таких как медицина, банковское дело или страхование, алгоритмы могут использоваться тогда и только тогда, когда можно отслеживать и объяснять (или, лучше сказать, интерпретировать) решения этих алгоритмов.

Словарные скобки

В этой статье мы хотели бы выделить термины:

Объяснимость: возможность объяснить с технической точки зрения предсказание алгоритма.

Интерпретируемость: способность объяснять или передавать значение в терминах, понятных человеку.

Прозрачность: модель считается прозрачной, если она понятна сама по себе.

Почему нас волнует интерпретируемость?

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

Иногда было бы целесообразнее отказаться от подхода машинного обучения и использовать детерминированные алгоритмы, основанные на правилах, обоснованных отраслевыми знаниями или законодательством [1].

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

Для достижения этих целей возникла новая область: XAI (объяснимый искусственный интеллект), целью которой является создание мощных и объяснимых алгоритмов.

Было предложено множество фреймворков для объяснения непрозрачных алгоритмов. Очень хорошее представление этих методов можно найти в официальном документе Cloudera [3].

В этой статье мы рассмотрим один из наиболее часто используемых фреймворков: SHAP.

XAI, для кого это?

Были выявлены различные профили, заинтересованные в объяснимости или интерпретируемости:

  • Бизнес-эксперт / пользователь модели - чтобы доверять модели, понять причинно-следственную связь прогноза
  • Регулирующие органы по сертификации соблюдения законодательства, аудит
  • Менеджеры и исполнительный совет для оценки соответствия нормативным требованиям, понимания корпоративных приложений ИИ
  • На пользователей влияют модельные решения, чтобы понять ситуацию, проверить решения
  • Специалист по анализу данных, разработчик, заказчик для обеспечения / повышения производительности продукта, поиска новых функций, объяснения функций / прогнозов начальству

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

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

Например, Dataiku - платформа ML - добавила в свою последнюю версию 7.0, опубликованную 2 марта 2020 года, инструменты объяснимости: ценности Шепли и Индивидуальные условные ожидания (ICE).

Azure ML предлагает собственную версию Shap и альтернативные инструменты, добавляющие интерактивные дашборды.

Существуют также веб-приложения с открытым исходным кодом, такие как это, описанное в статье о среде [4], которые облегчают изучение библиотеки SHAP.



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

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

Объяснимость - практика

Большинство специалистов по данным уже слышали о фреймворке SHAP.
В этом посте мы не будем подробно объяснять, как выполняются вычисления, лежащие в основе библиотеки. Многие ресурсы доступны в Интернете, такие как документация SHAP [5], публикации авторов библиотеки [6,7], замечательная книга «Интерпретируемое машинное обучение» [8] и множество статей по средам [9,10,11].

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

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

Дьявол в деталях

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

Кроме того, существует несколько технических нюансов, позволяющих использовать SHAP с вашими данными. Статья в блоге Франческо Поркетти [12] выражает некоторые из этих разочарований, исследуя библиотеки SHAP, LIME, PDPbox (PDP и ICE) и ELI5.

В Saegus я работал над курсом, целью которого было прояснить структуру SHAP и облегчить использование этого инструмента.

В этом посте я хотел бы поделиться с вами некоторыми наблюдениями, собранными в ходе этого процесса.

SHAP используется для объяснения существующей модели. Рассмотрим случай двоичной классификации, построенный с помощью модели sklearn. Обучаем, настраиваем и тестируем нашу модель. Затем мы можем использовать наши данные и модель для создания дополнительной модели SHAP, которая объясняет нашу модель классификации.

Запас слов

Важно понимать все кирпичики, из которых состоит объяснение SHAP.

Часто при использовании значений по умолчанию для параметров сложность выбора, который мы делаем, остается неясной.

общие объяснения
объяснения того, как модель работает с общей точки зрения.

местные пояснения
пояснения модели для образца (точки данных)

объяснитель (shap.explainer_type (params))
тип алгоритма объяснимости, который следует выбрать в соответствии с используемой моделью.

Параметры разные для каждого типа модели. Обычно необходимо предоставить как минимум модель и данные для обучения.

базовое значение (объясняющее. ожидаемое_значение)
E (y_hat) - это «значение, которое было бы предсказано, если бы мы не знали каких-либо характеристик текущего вывода» - это среднее значение (y_hat) для набора обучающих данных или фонового набора. Мы можем назвать это «эталонным значением», это скаляр (n).

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

# equilibrated case
background = X.sample(1000) #X is equilibrated
# background used in explainer defines base value
explainer = shap.TreeExplainer(xgb_model,background,model_output="raw" )
shap_values = explainer.shap_values(X)
# background used in the plot, the points that are visible on the plot
shap.summary_plot(shap_values,background, feature_names=background.columns)

# base value shifted
class1 = X.loc[class1,:] #X is equilibrated
# background from class 1 is used in explainer defines base value
explainer = shap.TreeExplainer(xgb_model,class1,model_output="raw" )
shap_values = explainer.shap_values(X)
# points from class 0 is used in the plot, the points that are visible on the plot
shap.summary_plot(shap_values,X.loc[class0,:], feature_names=X.columns)

Значения SHAPley (объяснитель.shap_values ​​(x))
средний вклад каждой функции в каждый прогноз для каждой выборки на основе всех возможных функций. Это (n, m) n - образцы, m - матрица функций, которая представляет вклад каждой функции в каждую выборку.

выходное значение (для образца)
значение, предсказанное алгоритмом (вероятность, логит или исходные выходные значения модели)

функции отображения (n x m)
матрица исходных значений - до преобразования / кодирования / разработки функций и т. д. - которая могут быть предоставлены некоторым графикам для улучшения интерпретации. Часто упускается из виду и важен для интерпретации.

____

Значения SHAPley

Ценности Шепли остаются центральным элементом. Как только мы поймем, что это просто матрица с теми же размерами, что и наши входные данные, и что мы можем анализировать ее по-разному, чтобы объяснить модель, и не только. Мы можем уменьшить его размеры, мы можем кластеризовать его, мы можем использовать его для создания новых функций. Интересное исследование, описанное в статье [12], направлено на улучшение обнаружения аномалий с помощью автокодировщиков и SHAP. Библиотека SHAP предлагает обширные, но не обменные исследования посредством визуализаций.

Визуализации

Библиотека SHAP предлагает различные визуализации. Хорошее объяснение того, как читать цвета сводного графика, можно найти в этой статье [14].

Сводный график показывает наиболее важные особенности и степень их влияния на модель. Он может принимать несколько графических форм, и для моделей, объясненных TreeExplainer, мы также можем наблюдать значения взаимодействия, используя «компактную точку» с входными значениями shap_interaction_values.

График зависимости позволяет анализировать функции по два, предлагая возможность наблюдать за взаимодействиями. Диаграмма рассеяния представляет собой зависимость между признаком (x) и значениями формы (y), окрашенными вторым признаком (оттенком).

От себя лично я считаю, что одновременное наблюдение трехфакторной взаимосвязи не является интуитивным для человеческого мозга (по крайней мере, для моего). Я также сомневаюсь, что наблюдение зависимости путем наблюдения за цветами может быть точным с научной точки зрения. Shap может дать нам взаимосвязь взаимодействия, которая рассчитывается как корреляция между формальными значениями первого признака и значениями второго признака. Если возможно (для TreeExplainer), имеет смысл использовать значения взаимодействия shapley для наблюдения за взаимодействиями.

Я предлагаю интерактивный вариант графика зависимости, который позволяет наблюдать взаимосвязь между признаком (x), значениями формы (y) и прогнозом (цвета гистограммы). Что мне кажется важным в этой версии, так это возможность отображать на графике исходные значения (доход в k USD) вместо нормализованного пространства, используемого моделью.

Есть три варианта визуализации объяснений образца: график сил, график решений и график водопада.

Для примера, эти три представления являются избыточными, они представляют информацию очень похожим образом. В то же время некоторые элементы этих графов дополняют друг друга. Помещая все три рядом, у меня создается впечатление, что я понимаю результат более интуитивно. График силы позволяет увидеть, где «выходное значение» соответствует «базовому значению». Мы также видим, какие особенности имеют положительное (красный) или отрицательное (синий) влияние на прогноз и величину этого воздействия. Водный график также позволяет нам увидеть амплитуду и характер воздействия объекта с его количественной оценкой. Это также позволяет увидеть порядок важности характеристик и значения, принимаемые каждой характеристикой для исследуемой выборки. График принятия решения позволяет наблюдать амплитуду каждого изменения, «траекторию», взятую из выборки для значений отображаемых характеристик.

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

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

График решения для набора образцов быстро становится громоздким, если мы выбираем слишком много образцов. Очень полезно наблюдать «отклонение траектории» или «расходящиеся / сходящиеся траектории» ограниченной группы образцов.

Толкователи

Объяснители - это модели, используемые для расчета значений Shapley. На диаграмме ниже показаны различные типы объяснителей.

Выбор объяснителей в основном зависит от выбранной модели обучения. Для линейных моделей используется «Linear Explainer», для деревьев решений и моделей типа «set» - «TreeExplainer». «Kernel Explainer» работает медленнее, чем упомянутые выше объяснители.

Кроме того, «Tree Explainer» позволяет отображать значения взаимодействия (см. Следующий раздел). Это также позволяет преобразовать выходные данные модели в вероятности или лог-потери, что полезно для лучшего понимания модели или для сравнения нескольких моделей.

Kernel Explainer создает модель, которая заменяет наиболее близкую к нашей модели. Kernel Explainer можно использовать для объяснения нейронных сетей. Для моделей глубокого обучения существуют Deep Explainer и Grandient Explainer. В этой статье мы не исследовали объяснимость нейронных сетей.

Шепли ценности взаимодействий

Одним из свойств, позволяющих продвинуться дальше в анализе модели, которую можно объяснить с помощью «Tree Explainer», является расчет условных значений взаимодействий.

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

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

Я использовал набор данных Kaggle [15], который представляет клиентскую базу и двоичную зависимую функцию: принял ли клиент личную ссуду? НЕТ / ДА (0/1).

Я обучил несколько моделей, включая модель xgboost, которую мы обработали с помощью Tree Explainer.

Фоновый набор данных был сбалансирован и составлял 40% набора данных.

# xgb - traned model
# X_background - background dataset
explainer_raw = shap.TreeExplainer(xgb,X_background, model_output="raw", feature_perturbation="tree_path_dependent" )
# project data point of background datasetshap_values = explainer_raw.shap_values(X_background)
# obtain interaction values
shap_interaction_values = explainer_raw.shap_interaction_values(X_background)
# dimensions
shap_values.shape
>>>(2543, 16)
shap_interaction_values.shape
>>>(2543, 16, 16)
shap.summary_plot(shap_interaction_values, 
X_background, plot_type="compact_dot")

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

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

На гистограмме мы непосредственно наблюдаем взаимодействия. Сильнейшие из них: доход - образование, доход - семья, доход - CCAvg и семья-образование, доход-возраст.

Затем я исследовал взаимодействия два на два.
Чтобы понять разницу между dependency_plot и dependency_plot взаимодействий, вот два:

# dependence_plot classique
shap.dependence_plot("Age", shap_values, features= X_background,display_features=X_background_display,  interaction_index="Income")

# dependence_plot des interactions
shap.dependence_plot(("Age","Income"), shap_interaction_values, features= X_background,display_features=X_background_display)

Даже при использовании параметра display_features значения возраста и дохода отображаются в преобразованном пространстве.

По этой причине я предлагаю интерактивную версию, которая отображает непреобразованные значения.

А вот код для воспроизведения этого сюжета:

Здесь самые сильные взаимодействия:

Доход - образование

На этом графике мы замечаем, что с уровнем образования 1 (бакалавриат) низкий доход (менее 100 тыс. Долларов США) является стимулирующим фактором для получения кредита, а высокий доход (более 120 тыс. Долларов США) является препятствующим взаимодействием.
Для лиц с образованием 2 и 3 (законченный и продвинутый / профессиональный) эффект взаимодействия немного ниже и противоположен таковому для образования == 1.

Для характеристик «Семья» и «количество человек» в домохозяйстве взаимодействие положительное, когда доход низкий (менее 100 тыс. Долларов США) и в семье 1–2 члена. Негативно сказывается на более высоких доходах (›120 тыс. Долл. США), на семью из 1–2 человек. Обратное верно для семей из 3–4 человек.

Взаимодействие между доходом и средними расходами по кредитной карте более сложное. Для низкого дохода (‹100 тыс. Долларов США) и низкого CCAvg (‹ 4 тыс. Долларов США) взаимодействие имеет отрицательный эффект, для дохода от 50 до 110 тыс. Долларов США и CCAvg 2–6 тыс. Долларов США эффект является сильно положительным, это может определять потенциальная цель для привлечения кредитов по этим двум осям. Для высоких доходов (›120 тыс. Долл. США) низкий CCAvg положительно влияет на прогноз класса 1, высокий CCAvg оказывает небольшое отрицательное влияние на прогнозы, средний CCAvg оказывает более сильное отрицательное влияние.

Взаимодействие между двумя функциями немного менее читабельно. Для семьи из 1 или 2 человек с «бакалаврским» образованием взаимодействие оказывает негативное влияние. Для семьи из 3–4 человек эффект обратный.

Для низких доходов (‹70 тыс. Долл. США) влияние изменяется линейно с возрастом: чем выше возраст, тем больше влияние меняется в положительную сторону. Для высоких доходов (›120 тыс. Долл. США) влияние взаимодействия ниже, в среднем возрасте (~ 40 лет) влияние незначительно положительное, в младшем возрасте влияние отрицательное, а для возраста› 45 лет влияние нейтрально.

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

Сравнить модели

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

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

# we have tree models : xgb, gbt, rf
# for each model we get an explainer(*_explainer), probabilities (*_probs), predictions (*_pred) and shapley values(*_values)
#xgb
xgb_explainer = shap.TreeExplainer(xgb, X_background, model_output="probability", feature_perturbation="interventional")
xgb_values = xgb_explainer.shap_values(X_background)
xgb_probs = xgb.predict_proba(pipeline_trans.transform(x_background))
xgb_pred = xgb.predict(pipeline_trans.transform(x_background))
# rf
rf_explainer = shap.TreeExplainer(rf, X_background, model_output="probability", feature_perturbation="interventional")
rf_values = rf_explainer.shap_values(X_background)
rf_probs = rf.predict_proba(pipeline_trans.transform(x_background))
rf_pred = rf.predict(pipeline_trans.transform(x_background))
# gbt
gbt_explainer = shap.TreeExplainer(gbt, X_background, model_output="probability", feature_perturbation="interventional")
gbt_values = gbt_explainer.shap_values(X_background)
gbt_probs = gbt.predict_proba(pipeline_trans.transform(x_background))
gbt_pred = gbt.predict(pipeline_trans.transform(x_background))
########
# we make a list of model explaners
base_values = [xgb_explainer.expected_value, rf_explainer.expected_value[1], gbt_explainer.expected_value]
shap_values = [xgb_values, rf_values[1], gbt_values]
predictions = [xgb_probs,rf_probs,gbt_probs]
labels = ["xgb", "rf", "gbt"]
# index of a sample
# Plot
idx = 100
shap.multioutput_decision_plot(base_values, shap_values, idx, feature_names=X_background.columns.to_list(),legend_labels=labels, legend_location='lower right')

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

Симуляторы

По умолчанию SHAP не содержит функций, облегчающих ответ на вопрос «Что, если?» вопрос. «Что, если бы я мог зарабатывать дополнительно 10 000 долларов США в год, можно ли было бы продлить мой кредит?»
Тем не менее, можно запустить моделирование, варьируя функцию и вычисляя гипотетические значения шейпли.

explainer_margin_i = shap.TreeExplainer(xgb,X_background, model_output="raw", feature_perturbation="interventional" )
idx = 100
rg = range(1, 202, 10)
r, R, hypothetical_shap_values, hypothetical_predictions, y_r = simulate_with_shap(x_background,100, "Income", rg ,explainer_margin_i, pipeline_trans=pipeline_trans)

Я создал функцию simulate_with_shap, которая имитирует различные значения функции и вычисляет гипотетические значения shapley.

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

Можно смоделировать изменения «функция за функцией», было бы интересно иметь возможность вносить несколько изменений одновременно.

Заключительное примечание

Алгоритмы ИИ занимают все больше места в нашей жизни. Объяснимость прогнозов - важная тема для специалистов по обработке данных, лиц, принимающих решения, и людей, на которых прогнозы оказывают влияние.

Было предложено несколько рамок для преобразования необъяснимых моделей в объяснимые. Один из самых известных и широко используемых фреймворков - SHAP.

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

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

Благодарности

Я хотел бы поблагодарить команду Saegus DATA, которая участвовала в этой работе с хорошими советами, в частности менеджера Фредерика Брайона и старшего менеджера-консультанта Клемана Мутара.

Библиография

[1] Прекратите объяснять модели машинного обучения черного ящика для принятия серьезных решений и используйте вместо них интерпретируемые модели; Синтия Рудин https://arxiv.org/pdf/1811.10154.pdf

[2] Объясняемый искусственный интеллект (XAI): концепции, таксономия, возможности и проблемы ответственного ИИ; Arrietaa et al. Https://arxiv.org/pdf/1910.10045.pdf

[3] Cloudera Fast Forward Interpretability: https://ff06-2020.fastforwardlabs.com/?utm_campaign=Data_Elixir&utm_source=Data_Elixir_282

[4] https://towardsdatascience.com/understand-the-machine-learning-blackbox-with-ml-interpreter-7b0f9a2d8e9f

[5] https://github.com/slundberg/shap

[6] http://papers.nips.cc/paper/7062-a-unified-approach-to-interpreting-model-predictions

[7] https://www.nature.com/articles/s42256-019-0138-9

[8] https://christophm.github.io/interpretable-ml-book/

[9] https://towardsdatascience.com/shap-explained-the-way-i-wish-someone-explained-it-to-me-ab81cc69ef30

[10] https://medium.com/@gabrieltseng/interpreting-complex-models-with-shap-values-1c187db6ec83

[11] https://medium.com/@stanleyg1/a-detailed-walk-through-of-shap-example-for-interpretable-machine-learning-d265c693ac22

[12] https://francescopochetti.com/whitening-a-black-box-how-to-interpret-a-ml-model/

[13] Объяснение аномалий, обнаруженных автоэнкодерами с использованием SHAP; Antwarg et al. Https://arxiv.org/pdf/1903.02407.pdf

[14] https://medium.com/fiddlerlabs/case-study-explaining-credit-modeling-predictions-with-shap-2a7b3f86ec12

[15] https://www.kaggle.com/itsmesunil/bank-loan-modelling