Авторы Рагху Адитья Чавали, Пранай Лохия и Халли Динг

[1. Введение

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

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

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

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

[2] Что такое объяснимость модели?

Объяснимость модели – это процесс анализа и выявления внутренней работы модели машинного обучения или других алгоритмов "черного ящика", чтобы сделать их более прозрачными. Это делается путем просмотра вклада каждой из точек данных (или функций) в выходные данные (также известные как важность функций) или путем визуализации различных представлений данных или весов модели для дальнейшего просмотра. Объяснимость модели направлена ​​на ответ на вопрос «Почему модель делает этот прогноз?»

[3] Почему важна объяснимость модели?

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

  1. Определение наличия неосознанной предвзятости в модели, когда она делает определенные прогнозы. Выявление предвзятости имеет решающее значение при разработке решений, предназначенных для миллионов пользователей по всему миру. Некоторые из многих сценариев, которые могут негативно сказаться на опыте конечного пользователя, включают просмотр состава данных, учитываемых при обучении модели, наличие сильных выбросов, искажающих выходные данные, отсутствие достаточного представления когорты или выбор оптимального варианта. подмножество обучающих данных.
  2. Лучшее объяснение результатов моделирования и укрепление доверия с заинтересованными сторонами. Понимание того, какие функции положительно и отрицательно влияют на прогноз, может помочь конечным пользователям получить более четкое представление и укрепить доверие к этим алгоритмам «черного ящика». Это также помогает выявить ограничения или предположения, сделанные на этапе построения модели, чтобы пользователи не были потенциально введены в заблуждение ложными заявлениями о мастерстве модели.
  3. Помогает выявлять непредвиденные факторы, влияющие на результаты модели машинного обучения. В случае больших наборов данных модель учится сопоставлять различные точки данных и оценивать их по функции потерь, чтобы сделать прогноз. В наборе данных могут существовать определенные корреляции, которые не очевидны для разработчика, но могут иметь решающее значение для приложения. Обращение к ним на этапе разработки модели обеспечивает лучшие возможности отладки и создание справедливых решений.
  4. Помощь в проверке модели и отслеживание влияния ее решений на людей. Это особенно важно во время проверок регулирующими органами, чтобы определить, безопасно ли развертывание модели для нескольких пользователей по всему миру.

В этой серии статей, состоящей из двух частей, мы представляем централизованную, независимую от модели структуру объяснимости, поддерживающую архитектуру Bring-Your-Own-Model (BYOM). Мы рассмотрим некоторые методы объяснимости, которые мы внедрили, наш подход к просмотру важных показателей модели и исследования наборов данных, а также рассмотрим различные методы внедрения, доступные для тех, кто хочет использовать эту работу для своих собственных вариантов использования.

[4] Предлагаемая схема объяснимости

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

  1. Простой и эффективный способ вычисления важности локальных и глобальных функций с использованием различных методов.
  2. Возможность визуализировать выходные данные последовательным и понятным образом, что упрощает их использование и помогает получать ценные сведения.
  3. Простота масштабирования за счет включения новых современных технологий и централизованного источника обслуживания.
  4. Простая интеграция с существующими производственными конвейерами.
  5. Простота адаптации модели.

Рисунок 1 суммирует два основных рабочих процесса объяснимости и их соответствующие результаты в предлагаемой нами структуре.

[4.1] Исходные данные структуры

Наша структура принимает два входа:

  1. Обученная модель обычно в виде файла рассола. Это может быть готовая модель (например, sklearn или lightGBM) или пользовательская модель, созданная для конкретных приложений.
  2. Набор обучающих данных, который представляет собой фрейм данных, содержащий обучающие данные в виде файла .parquet, .csv или .tsv.

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

[4.2] Методы объяснения

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

  • Направление 1 (показано зеленым цветом): используются современные методы объяснимости, не зависящие от модели, для создания глобальных и локальных объяснений.
  • След 2 (показан синим цветом): использует пакет Azure Interpret ML для выполнения анализа и вывода интерактивной панели мониторинга в дополнение к локальным и глобальным графикам и значениям пояснений.

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

[4.3] Выходные данные платформы

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

[4.3.1] Объяснения SHAP

SHAP (SHapley Additive exPPlanations) — это основанный на теории игр подход к объяснению выходных данных модели машинного обучения. Он связывает оптимальное распределение кредитов с локальными объяснениями, используя классические значения Шепли из различных расширений теории игр для вычисления важности. SHAP присваивает каждой функции значение важности для конкретного прогноза. Общая идея заключается в том, что наиболее важными функциями являются те, удаление которых приводит к наибольшим изменениям в выходных данных модели. Мы применяем анализ на основе SHAP как с локальной, так и с глобальной точки зрения, чтобы обеспечить всестороннее представление. К его основным преимуществам относятся:

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

Результаты глобального анализа SHAP выделены на рисунке 2. В этом примере представлен обзор основных факторов, влияющих на прогноз модели. В некоторых бизнес-сценариях нам может быть интересно понять действия, которые необходимо предпринять для каждой точки данных. В этом случае можно использовать локальный анализ SHAP для объяснения ключевых функций, определяющих прогноз каждой строки. Это показано на рисунке 3.

В следующем примере показана работа объяснителя SHAP. Здесь мы смотрим на набор данных SpeedDating, в котором участников спрашивали, хотят ли они снова увидеть свое свидание. Их также попросили оценить свое свидание по шести параметрам: привлекательность, искренность, интеллект, веселье, амбиции и общие интересы. Набор данных также включает данные анкеты, собранные от участников на разных этапах процесса.

import flaml
from flaml.data import load_openml_dataset
# Retrieve openML speed dating dataset
X_train, X_test, y_train, y_test = load_openml_dataset(dataset_id=40536, data_dir=’./’)

Этот набор данных содержит 59 числовых признаков, 61 категориальный признак и два класса: «1» и «0». Давайте обучим модель классификации смотреть на результаты объяснения.

from lightgbm import LGBMClassifier
# Train classification model
lgbm_model = LGBMClassifier()
lgbm_model.fit(X_train, y_train)

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

def encode_features(Data):
    # Function to encode categorical features
    le = preprocessing.LabelEncoder()
    # Define list of categorical columns
    cat_list = [col for col in Data.columns.tolist() if Data[col].dtype == ‘category’]
    # Transform required columns
    for col in cat_list:
        Data[col] = le.fit_transform(Data[col])
    return Data
X_train = encode_features(X_train)
X_test = encode_features(X_test)

Мы инициализируем объяснитель SHAP (в данном случае объяснитель дерева), предоставляя модель в качестве параметра, а затем вычисляя значения Шепли, предоставляя обучающие данные.

import numpy as np
import shap
explainer = shap.TreeExplainer(lgbm_model)
shap_values = explainer.shap_values(X_train)

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

shap.force_plot(explainer.expected_value[0], shap_values[0][0], X_train.iloc[0,:])

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

shap.summary_plot(shap_values)

SHAP также предоставляет глобальную важность функций в виде сводного результата. Из следующего графика на рисунке 5 мы можем определить такие функции, как «нравится», «attractive_o» и «attractive_partner», как важные глобальные функции.

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

[4.3.2] Пояснения к FastSHAP

Одной из основных проблем при использовании SHAP являются его дорогостоящие вычисления. Чтобы решить эту проблему, FastSHAP был создан для ускорения выполнения за счет поддержки параллельных вычислений. FastSHAP — это амортизированный подход к расчету оценок значений Шепли для больших наборов данных. Он включает в себя обучение модели объяснения для вывода оценок значений Шепли за один прямой проход. Для сравнения, в пакете SHAP параллельные вычисления не включены, за исключением случаев интерпретации моделей XGBoost, LightGBM и CatBoost, когда пакет SHAP внутренне использует функции TreeSHAP в пакетах. Выходные данные FastSHAP идентичны выходным данным, сгенерированным алгоритмом SHAP.

В следующем примере показана работа эксплейнера FastSHAP. Здесь мы смотрим на набор данных диабет, который предсказывает, есть ли у женщины диабет или нет, на основе характерных признаков.

import flaml
from flaml.data import load_openml_dataset
# Retrieve openML speed dating dataset
X_train, X_test, y_train, y_test = load_openml_dataset(dataset_id=37, data_dir=’./’)

Этот набор данных содержит восемь числовых признаков и два класса: «tested_positive» и «tested_negative». Давайте обучим модель классификации смотреть на результаты объяснения.

from lightgbm import LGBMClassifier
# Train classification model
lgbm_model = LGBMClassifier()
lgbm_model.fit(X_train, y_train)

Мы инициализируем объяснитель FastSHAP (в данном случае объяснитель дерева), предоставляя модель и алгоритм в качестве параметров. Аргумент алгоритма указывает алгоритм TreeSHAP, используемый для запуска FastTreeSHAP. Он может принимать значения «v0», «v1», «v2» или «auto», а его значение по умолчанию — «auto». Позже мы вычисляем быстрые значения Шепли для всего набора тестовых данных.

import fasttreeshap
explainer = fasttreeshap.TreeExplainer(lgbm_model, algorithm = “auto”, n_jobs = -1)
shap_values = explainer(X_test).values

Для дальнейшего извлечения быстрых значений Шепли для отдельных строк мы запрашиваем «shap_values» по индексу строки.

idx = 0
output = shap_values[idx]

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

[4.3.3] Объяснения LIME

LIME (Local Interpretable Model-agnostic Explanations) — это современный метод локальной объяснимости, который определяет важность функций для прогнозирования класса с использованием метода линейной аппроксимации. Для каждой точки данных он создает несколько контрольных точек вокруг исходной точки данных в пространстве данных, нарушая ее. Затем он сопоставляет линейную модель (например, модель линейной регрессии) с точками данных, а затем определяет важность функции этой линейной модели как локальную объяснимость исходной точки данных. Это метод объяснимости, не зависящий от модели, поскольку он требует только функции прогнозирования модели, а не ее внутренних деталей.

В следующем примере показана работа эксплейнера Lime. Здесь мы смотрим на набор данных Credit-G, который классифицирует людей, описываемых набором признаков, как людей с хорошим или плохим кредитным риском.

import flaml
from flaml.data import load_openml_dataset
# Retrieve openML credit-g dataset
X_train, X_test, y_train, y_test = load_openml_dataset(dataset_id=31, data_dir=’./’)

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

from lightgbm import LGBMClassifier
# Train classification model
lgbm_model = LGBMClassifier()
lgbm_model.fit(X_train, y_train)

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

def encode_features(Data):
    # Function to encode categorical features
    le = preprocessing.LabelEncoder()
    # Define list of categorical columns
    cat_list = [col for col in Data.columns.tolist() if Data[col].dtype == ‘category’]
    # Transform required columns
    for col in cat_list:
        Data[col] = le.fit_transform(Data[col])
    return Data
X_train = encode_features(X_train)
X_test = encode_features(X_test)

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

import numpy as np
from lime import lime_tabular
lime_explainer = lime_tabular.LimeTabularExplainer(
    training_data=np.array(X_train),
    feature_names=X_train.columns,
    class_names=lgbm_model._classes,
    mode=’classification’)

Наконец, мы можем использовать объяснитель LIME, чтобы посмотреть на функции, которые способствовали прогнозированию одной точки данных. Например, давайте посмотрим на строку 76 тестового набора данных. Примечание: в случае регрессионных задач в функции predict_fn будет использоваться функция «model.predict» вместо «model.predict_proba».

lime_results = lime_explainer.explain_instance(
    data_row=X_test.iloc[75],
    predict_fn=lgbm_model.predict_proba)
lime_results.show_in_notebook(show_table=True)

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

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

[4.3.4] Пояснения к якорям

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

В следующем примере представлен обзор реализации метода Anchors. Здесь мы используем знаменитый набор данных Взрослый, который классифицирует, будет ли человек зарабатывать более 50 000 долларов в год или нет, на основе характеристик, связанных с его возрастом, образованием, опытом работы, отношениями и капиталом.

import flaml
from flaml.data import load_openml_dataset
# Retrieve openML adult dataset
X_train, X_test, y_train, y_test = load_openml_dataset(dataset_id=1590, data_dir=’./’)

Этот набор данных содержит шесть числовых и девять категориальных признаков и два класса: «›50K» и «‹50K». Чтобы использовать объяснитель Anchors, нам нужно преобразовать категориальные признаки в числовые, закодировав их.

categorical_names = {}
headers = list(X_train)
for idx, feature in enumerate(headers):
    if X_train[feature].dtype == ‘category’:
        feature_codes = dict(enumerate(X_train[feature].cat.categories))
        inv_feature_codes = {v: k for k, v in feature_codes.items()}
        X_train[feature] = X_train[feature].map(inv_feature_codes)
        X_test[feature] = X_test[feature].map(inv_feature_codes)
        categorical_names[idx] = list(feature_codes.values())

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

y_train_codes = dict(enumerate(y_train.cat.categories))
y_train = y_train.cat.codes.to_numpy()
y_train_inv_codes = {v: k for k, v in y_train_codes.items()}
y_test = y_test.map(y_train_inv_codes).to_numpy()
class_names = list(y_train_inv_codes.keys())

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

from lightgbm import LGBMClassifier
# Train classification model
lgbm_model = LGBMClassifier()
lgbm_model.fit(X_train, y_train)

Мы используем AnchorTabularExplainer из пакета привязки, чтобы узнать локальные объяснения.

from anchor import anchor_tabular
anchor_explainer = anchor_tabular.AnchorTabularExplainer(
    class_names = class_names,
    feature_names = X_train.columns.tolist(),
    train_data = X_train.to_numpy(),
    categorical_names = categorical_names)

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

idx = 1
np.random.seed(1)
print(‘Prediction: ‘, anchor_explainer.class_names[lgbm_model.predict(np.array(X_test)[idx].reshape(1, -1))[0]])
exp = anchor_explainer.explain_instance(X_test.to_numpy()[idx], lgbm_model.predict, threshold=0.95)
print(‘Anchors: \n %s’ % (‘\n ‘.join(exp.names())))
print(‘Precision: %.2f’ % exp.precision())
print(‘Coverage: %.2f’ % exp.coverage())

Выходные данные, показанные на рисунке 7, предоставляют список функций, которые привязывают прогноз этой точки данных к классу. В этом случае человек зарабатывает более 50 000 долларов в год. Признаки, которых было достаточно для уверенного присвоения предсказания класса, называются якорями.

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

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

Рекомендации

[1] Лундберг, Скотт М. и Су-Ин Ли. «Единый подход к интерпретации предсказаний моделей». Достижения в области нейронных систем обработки информации 30 (2017 г.).

[2] Ян Цзилэй. «Fast TreeSHAP: ускорение расчета стоимости SHAP для деревьев». препринт arXiv arXiv:2109.09847 (2021 г.).

[3] Рибейро, Марко Тулио, Самир Сингх и Карлос Гестрин. «Почему я должен вам доверять?» Объясняя предсказания любого классификатора». Материалы 22-й международной конференции ACM SIGKDD по поиску знаний и интеллектуальному анализу данных (2016 г.).

[4] Лусс, Ронни и др. «Создание контрастных объяснений с монотонными атрибутивными функциями» (2019).

[5] Рибейро, Марко Тулио, Самир Сингх и Карлос Гестрин. «Якоря: высокоточные объяснения, не зависящие от модели». Материалы конференции AAAI по искусственному интеллекту, Vol. 32, № 1 (2018).

[6] Примеры записных книжек Jupyter AzureML и справочные материалы:

[7] Наборы данных OpenML.