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

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

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

  • Объяснить модель бизнес-пользователям.
  • Чтобы помочь специалистам по обработке данных понять важность функций с точки зрения бизнеса.
  • Развить уверенность и доверие к разработанной модели.
  • Чтобы помочь в отладке и проверке модели.

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

SHAP (Пояснения к добавкам Шепли)

SHAP был предложен Скоттом Лундбергом и Су-Ин Ли в 2017 году, а исходную статью можно найти здесь.

Алгоритм SHAP не зависит от модели, и предлагаемые методы резко сокращают сложность дополнительных методов атрибуции признаков от O (TLD ^ M) до O (TLD²), где T и M - количество деревьев и объектов, соответственно, а D и L - максимальная глубина и количество листьев на деревьях. Библиотека SHAP с открытым исходным кодом хорошо работала практически со всеми популярными ансамблевыми моделями, такими как модели XGBoost, LightGBM, CatBoost и sklearn tree.

Алгоритм SHAP основан на Теории кооперативных игр и использует Shapley Values ​​ для объяснения характеристик с помощью веса (коэффициентов).

Использование SHAP в машинном обучении

Для простой модели легко объяснить важность и влияние функции (ей) интуитивно, например: как рассчитываются связанные веса для прогнозирования, почему для класса было сформировано конкретное дерево решений и т. д. Однако для сложных моделей это не очень просто, и здесь возникает идея Shapely Value для объяснения как отдельный объект или группа функций влияет на прогнозируемую цель.

В общем, значение Шепли рассчитывается как среднее значение предельного вклада каждого игрока в коалицию игроков. При этом учитывается справедливое распределение «выплаты» между игроками.

Чтобы понять математику и детали, взгляните на исходную статью

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

Теория кооперативных игр: кооперативная игра (или коалиционная игра) - это игра с соревнованием между группами игроков из-за возможности внешнего принуждения к кооперативному поведению.

Игроки: агенты (игроки), участвующие в игре.

Коалиции: временный союз между игроками для внесения вклада в игру.

Справедливое распределение: насколько справедливо распределяется вклад между игроками?

Аксиомы

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

где N = общее количество агентов, φ (v) = значение Shapley, v (N) = большие коалиции для всех игроков.

ii) Симметрия: у всех игроков есть шанс присоединиться к игре. Это свойство также называется равным обращением с равными.

Если i и j - два актора, эквивалентные в том смысле, что

Для каждого подмножества S из N, которое не содержит ни i, ни j, тогда

iii) Линейность:. Если две коалиционные игры, описываемые функциями выигрыша v и w, объединены, то распределенные выигрыши должны соответствовать выигрышам, полученным из v, и выигрышам, полученным из w. .

для каждого i в N.

iv) Нулевой или фиктивный игрок: значение Шепли для нулевого игрока i в игре v равно нулю. Игрок i равен нулю в v, если

для всех коалиций S, которые не содержат, т.е. если игрок ничего не вносит в коалиции, то вклад будет равен нулю.

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

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

Трое друзей F1, F2 и F3 собираются разделить такси, чтобы добраться до своего дома. Если они идут индивидуально, то каждый должен заплатить 10, 15 и 30 долларов соответственно. Если они путешествуют в группе, максимальная оплата составит 30 долларов. Но вопрос в следующем: помимо общего среднего взноса в заработную плату [(10 + 15 + 30) / 3], как мы можем рассчитать справедливую индивидуальную оплату для коалиции?

А вот и знаменитая Шепли Вэлью на помощь.

Согласно предоставленным данным мы знаем, что если каждый друг поедет к себе домой индивидуально, то они будут платить

F1- › $ 10
F2 -›
$ 15
F3 - ›
30

Однако, если они собираются путешествовать вместе, то будет сформирована следующая комбинация.

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

Как мы вычисляли наборы перестановок?

{F1, F2, F3} = › Если F1 и F2 образуют коалицию, они заплатят вместе 15 долларов. Поскольку F1 опускается первым, он заплатит 10 долларов, оставшаяся сумма 5 долларов будет предоставлена ​​F2, а 15 долларов будет выплачена F3 (поскольку 15 долларов уже выплачены).

{F1, F3, F2} = › На этот раз коалиция будет сформирована из F1 и F3. Таким образом, F1 заплатит 10 долларов, а оставшуюся сумму заплатит F3, что составляет 30–10 долларов = 20 долларов. А когда будет сформирована коалиция между F3 и F2, F2 не придется ничего платить.

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

Рассчитанные средние - это значение Шепли, при котором люди платят за всех своих друзей, если они путешествуют вместе. И если мы суммируем среднее значение всех друзей и коалиционных выплат в наборе перестановок, то всегда получается 30, что показывает, что выплаты справедливо распределены.

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

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

Игра - ›Модель

Игроки - ›Возможности

Подмножество игроков - ›Подмножество функций

Shapley value of Features - ›вклад функции.

LIME (местные интерпретируемые независимые от модели объяснения)

LIME также является популярным алгоритмом, предложенным Марко Тулио, Самиром Сингхом и Карлосом Гестрином. с заголовком Почему я должен тебе доверять »

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

Математическое представление LIME:

Таким образом, объяснение модели измеряет , насколько оно близко к предсказанию исходной модели (f), сохраняя при этом низкую сложность модели.

где x = экземпляр, L = функция потерь с учетом местоположения, f = модель для объяснения (исходная модель), g = линейная модель, G = семейство моделей объяснения, Pi - мера близости экземпляра x для определения местоположения и Omega ( g) = сложность модели.

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

Местный: Местное надежное объяснение. Это ключевая интуиция алгоритма LIME.

Интерпретируемый. Информация, которую можно обработать и понять. Если мы обрабатываем текст, то он показывает наличие / отсутствие слов, для изображений это наличие / отсутствие суперпикселей, а для табличных данных - взвешенная комбинация признаков (коэффициентов).

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

Пояснения: взаимосвязь и понимание входных и выходных данных модели.

Шаги по выполнению LIME

i) Выберите наблюдение, которое мы хотим объяснить.

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

См. Диаграмму ниже из оригинальной бумаги.

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

iii) Вычислите расстояние между новыми точками и наблюдением (мера сходства).

iv) Найдите подмножество из m объектов, которые имеют самая сильная связь с нашим целевым классом.

v) Подобрать линейную модель или любую интерпретируемую модель в наборе данных в n- измерениях, взвешенных по сходству .

vi) Веса линейных моделей используются в качестве объяснения решений, и мы знаем, что простые модели объяснимы.

Недостатки

i) Это зависит от случайной выборки новых точек, поэтому она может быть нестабильной.

ii) Подгонка для линейных моделей может быть неточной. Однако LIME предоставляет значение R², и то же самое можно проверить, чтобы увидеть, подходит ли локальная линейная регрессия или нет.

iii) Поскольку нам необходимо создать образец набора данных для каждого наблюдения, чтобы объяснить, это делает его относительно медленным для одного наблюдения, особенно с изображениями.

Важность перестановки или точность среднего уменьшения (MDA)

Это также один из методов, используемых для объяснения модели. Он измеряет, насколько уменьшается оценка, если функция недоступна. Алгоритм этого метода очень прост - Удалить особенности и переобучить модель. Проверьте R², значение F1 и точность модели. Таким образом, любые изменения этих значений могут объяснить важность функций.

Недостатки

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

Графики частичной зависимости (PDP)

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

Недостатки

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

Доступные пакеты Python

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

shap, LIME, Skater, azureml-interp, azureml-интерпретация-contrib, ELI5 (Explain Like I’m 5) → обеспечивает реализацию MDA .

Модуль sklearn.ensemble предоставляет функцию частичной_ зависимости.

Давайте посмотрим на интерпретируемость кода

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

полную записную книжку можно найти здесь

Необходимые библиотеки sklearn, numpy, matplotlib, shap, azureml, eli5

 from sklearn.model_selection import train_test_split
 from sklearn.ensemble import RandomForestClassifier
 from sklearn.metrics import classification_report
 import numpy as np
 import matplotlib.pyplot as plt
 import shap
 from interpret.ext.blackbox import TabularExplainer
 from interpret_community.widget import ExplanationDashboard
 shap.initjs()

Я загружаю набор данных о раке груди, чтобы показать, как интерпретируемость модели может быть объяснена на сложной модели, такой как Random Forest.

cancer_dataset = shap.datasets.sklearn.datasets.load_breast_cancer()
feature_names = cancer_dataset.feature_names
class_names = ["Malignant(0)", "Benign(1)"]
X_train, X_test, Y_train, Y_test = train_test_split(cancer_dataset.data, cancer_dataset.target, test_size=0.25, random_state=23)
rfc = RandomForestClassifier()
rfc.fit(X_train, Y_train)

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

def plot_imp_features(model, top_n):
     try:
         tree_feature_importances = rfc.feature_importances_
     except Exception as e:
         raise TypeError(f"Model must be a type of DecisionTree to use feature_importances_ Excpetion is {e}")
     sorted_idx = tree_feature_importances.argsort()
     select_n = sorted_idx[:top_n]
     y_ticks = np.arange(0, len(select_n))
     fig, ax = plt.subplots()
     
     ax.barh(y_ticks, tree_feature_importances[select_n])
     ax.set_yticklabels(feature_names[select_n])
     ax.set_yticks(y_ticks)
     ax.set_title("Random Forest Feature Importances (MDI)")
     fig.tight_layout()
     plt.show()
     
plot_imp_features(rfc, 15)

print(classification_report(Y_test, rfc.predict(X_test),  target_names=class_names))

Теперь пришло время использовать shap lib, чтобы увидеть, как мы можем объяснить влияние функций на целевой класс.

explainer = shap.TreeExplainer(rfc, X_train, link="logit")
shap_values = explainer.shap_values(X_test, check_additivity=False) 

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

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

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

#first 10 classes for X_test dataset
Y_test[:10] # (array([1, 1, 0, 1, 0, 0, 0, 1, 1, 0]),)
expected_index = 1 # indexes are 1,0
test_data_index = 1 # test_data_index can range from 0 to #len(test_data_index)
shap.force_plot(explainer.expected_value[expected_index], 
                 shap_values[expected_index][test_data_index,:], 
                 X_test[test_data_index,:],
                 feature_names=feature_names)

График силы показывает совокупное влияние различных характеристик и их значений на выходные данные модели. На приведенной выше диаграмме прогнозируемое значение составляет 0,60; а среднее значение вогнутых точек подталкивает прогнозы с 0,5167 до 0,60.

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

Теперь давайте проанализируем вторую точку данных, и здесь мы увидим эти функции, например наихудший периметр, средние точки вогнутости, средняя площадь, наихудший радиус и т. д. подталкивают прогноз к 0, т.е. злокачественный

expected_index, test_data_index = 1, 2 #test_data_index can range     #from 0 to len(test_data_index)
shap.force_plot(explainer.expected_value[expected_index], 
                 shap_values[expected_index][test_data_index, :], 
                 X_test[test_data_index, :],
                 feature_names=feature_names)

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

i=0 # class label. Can be change to 1 to see the behavior
shap.force_plot(explainer.expected_value[i], shap_values[i], features=X_test, feature_names=feature_names)

shap также предоставляет другой тип графика под названием сводный график. На этом графике средняя линия представляет значение shap = 0, а отклонение (от + ve до -ve значения) от средней линии показывает, как конкретная функция влияет на прогноз целевого значения.

i=1
shap.summary_plot(shap_values[i], features=X_test, 
                   feature_names=feature_names, 
                   class_names=class_names)

Сводный график: построение диаграммы с сохранением объекта на оси X и значения SHAP на оси Y

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

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

for feature_name in range(len(feature_names)):
     for target_label in range(len(cancer_dataset.target_names)):
         shap.dependence_plot(feature_name, shap_values[target_label], features=X_test, feature_names=feature_names)

SHAP lib также содержит другие объяснители, такие как PermutationExplainer, GradientExplainer, KernelExplainer, LinearExplainer, DeepExplainer и т. д. В API мы можем подробно ознакомиться с этими объяснителями

dir(shap)
['BruteForceExplainer', 'DeepExplainer', 'GradientExplainer', 'KernelExplainer', 'LinearExplainer', 'PartitionExplainer', 'PermutationExplainer', 'SamplingExplainer', 'Tree', 'TreeExplainer', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_cext', 'approximate_interactions', 'bar_plot', 'common', 'datasets', 'decision_plot', 'dependence_plot', 'embedding_plot', 'explainers', 'force_plot', 'have_matplotlib', 'hclust_ordering', 'image_plot', 'initjs', 'kmeans', 'matplotlib', 'monitoring_plot', 'multioutput_decision_plot', 'other', 'partial_dependence_plot', 'plots', 'sample', 'save_html', 'summary_plot', 'unsupported', 'warnings', 'waterfall_plot']

LIME (местные интерпретируемые независимые от модели объяснения)

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

from lime.lime_tabular import LimeTabularExplainer
np.random.seed(11)
tab_explainer=LimeTabularExplainer(X_train,feature_names=feature_nam   es,class_names=class_names, discretize_continuous=True,random_state=11)
def explain_model(model, test_data, index=0, num_features=1, top_labels=1): 
    if test_data.size ==0:
        raise ValueError("Empty dataset is passed")
    expl = tab_explainer.explain_instance(test_data[index], 
                                          model.predict_proba, 
                                          num_features=num_features, 
                                          top_labels=top_labels)
    
    expl.show_in_notebook(show_table=True,show_all=False)

explain_model(rfc, X_test, index=0, num_features=10) # Y_test[1] = 1(Benign)

На приведенной выше диаграмме мы видим, что модель предсказала доброкачественный класс, и выделенные функции оказывают большее влияние. С правой стороны мы видим, что худшая область получила значение 517,88, что меньше его фактического значения, то есть 564,20. Мы можем проверить указанное выше значение из набора данных.

cancer_dataset.feature_names[-7] # worst area
X_test[0][-7]
Out[196]:
564.2
cancer_dataset.feature_names[-8] # worst perimeter
X_test[0][-8]
Out[197]:
86.6

График частичной зависимости

scikit-learn предоставляет встроенную реализацию PDP. Функция partial_dependence принимает подобранную модель BaseGradientBoosting в качестве параметра для предоставления PDP. Итак, по этой причине я обучаю новый классификатор.

from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import partial_dependence
gbc = GradientBoostingClassifier()
gbc.fit(X_train, Y_train)
# [20] is the index of columns of train data for PDP
partial_dependence.plot_partial_dependence(gbc, X_train, [20], feature_names=feature_names)

График показывает, как худший радиус взаимодействует с целью (злокачественный и доброкачественный). Как только размер худшего радиуса пересекает отметку 16, прогноз резко падает от доброкачественного к злокачественному классу.

AzureML

Azure также опубликовала библиотеку с открытым исходным кодом в своем пакете azuleml SDK. Эта библиотека может использоваться для всех типов моделей машинного обучения, которые следуют соглашению методологий scikit-learn, то есть fit () и transform ()

Если мы работаем с любым настраиваемым алгоритмом, мы можем просто обернуть нашу основную модель внутри функции fit () и передать ее в azureml для объяснения функций.

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

Теперь, если мы передадим тот же случайный классификатор леса в качестве параметра TabularExplainer, мы сможем получить объяснение модели.

tab_explainer = TabularExplainer(rfc, X_train, features=feature_names, classes=[0, 1])
global_explanation = tab_explainer.explain_global(X_test) # How globally all features set interpretate the outcome
global_feature_rank_values = dict(zip(global_explanation.get_ranked_global_names(),
                                       global_explanation.get_ranked_global_values()))
 global_feature_rank_values
Out[23]:
{'worst perimeter': 0.07595532987463141,
  'worst concave points': 0.06780037332226518,
  'worst radius': 0.06178580090500718,
  'worst area': 0.061688813644569004,
  'worst concavity': 0.051432037342211356,
  'mean area': 0.02544095929461229,
  'mean concavity': 0.022822935606762865,
  'mean perimeter': 0.02230714237151857,
  'mean concave points': 0.014994114385124891,
  'mean texture': 0.01426150261834639,
  'mean radius': 0.012523284263610842,
  'worst texture': 0.012036364340557092,
  'worst compactness': 0.011888211618859144,
  'worst smoothness': 0.007687756633585173,
  'mean compactness': 0.007227320108198555,
  'perimeter error': 0.006870732294207836,
  'area error': 0.006006945019138089,
  'worst symmetry': 0.0059455597100683925,
  'radius error': 0.00498892192057288,
  'compactness error': 0.00440812326792559,
  'mean fractal dimension': 0.004065060877333495,
  'concavity error': 0.003417519253002984,
  'texture error': 0.003318578728239531,
  'worst fractal dimension': 0.0029870047227208156,
  'symmetry error': 0.00259608337064409,
  'mean smoothness': 0.0018153337349097675,
  'concave points error': 0.0015773339816971782,
  'fractal dimension error': 0.001495528819412792,
  'smoothness error': 0.0007389462921350583,
  'mean symmetry': 0.0005036257960195172}

Azureml также предоставляет ExplanationDashboard, который представляет собой мощную службу информационных панелей. Он предоставляет 4 основных графика для объяснения модели.

  1. Анализ данных: на этой вкладке мы можем выбрать значения осей X и Y, чтобы увидеть соответствующее целевое распределение. В правом верхнем углу мы видим целевой класс
  2. Глобальная важность: переменные глобальной важности, и мы можем выбрать K основных функций.
  3. Explanation Exploration: На этой вкладке объясняется, почему та или иная функция важна для прогнозирования.
  4. Сводная важность: сводка всех функций и их взаимосвязи с целевой переменной.
ExplanationDashboard(global_explanation, rfc , datasetX=X_test)

Заключение

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

Ссылки

Https://christophm.github.io/interpretable-ml-book/

Https://arxiv.org/abs/1705.07874

Https://arxiv.org/abs/1602.04938 - Почему я должен вам доверять.

Https://docs.microsoft.com/en-us/azure/machine-learning/how-to-machine-learning-interpretability?WT.mc_id=azuremedium-blog-lazzeri

Https://docs.microsoft.com/en-us/azure/machine-learning/how-to-machine-learning-interpretability

https://books.google.nl/books?id=wlexDwAAQBAJ&pg=SA6-PA21&lpg=SA6-PA21&dq=azureml+Tabular+explainer&source=bl&ots=7_Stxdaw0l&sig=ACfU3U12IPmJI0ImltJIitWY3VO1vdPGeg&hl=en&sa=X&ved=2ahUKEwiDu56gtM3pAhVLwAIHHerQCa0Q6AEwBXoECAoQAQ#v=onepage&q=azureml%20Tabular % 20explainerTreeScoringExplainer & f = false

Https://www.youtube.com/watch?v=C80SQe16Rao&t=2334s

Https://scikit-learn.org/stable/modules/partial_dependence.html

Https://eli5.readthedocs.io/en/latest/#

Https://docs.microsoft.com/en-us/azure/machine-learning/how-to-machine-learning-interpretability