Моделирование регрессии с использованием Microsoft MimicExplainer

InterpretML от Microsoft разработан с целью расширения интерпретируемости моделей машинного обучения. Другими словами, облегчить понимание этих моделей и, в конечном итоге, облегчить человеческую интерпретацию.

Interpret-Community от Microsoft - это расширение этого репозитория, которое включает дополнительные методы интерпретируемости.

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

Задний план

В этом примере MimicExplainer используется для интерпретации регрессионных моделей, построенных с использованием SVM (вспомогательные векторные машины) и XGBRegressor (XGBoost для задач регрессии).

В частности, эти две модели используются следующим образом:

  1. SVM используется для прогнозирования средней дневной ставки клиента с использованием определенных функций, таких как его страна происхождения, рыночный сегмент и другие. Оригинальные результаты доступны здесь.
  2. XGBRegressor используется в качестве модели регрессии временных рядов для прогнозирования количества еженедельных отмен путем регрессии ряда с запаздыванием относительно фактического, т.е. 5 серий с запаздыванием с последовательным запаздыванием до t-5 используются в качестве функций в модели для прогнозирования значения отмены. в момент t. Оригинальные результаты доступны здесь.

Исходные данные доступны из Антонио, Алмейда и Нунес (2019): Наборы данных о спросе на бронирование отелей.

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

SVM

Чтобы спрогнозировать среднюю дневную ставку (или ставку, которую клиент платит в среднем за день) за бронирование отеля, создается модель SVM со следующими функциями:

  • Отмена (независимо от того, отменяет ли клиент свое бронирование или нет)
  • Страна происхождения
  • Сегмент рынка
  • Тип депозита
  • Тип клиента
  • Требуемые парковочные места
  • Неделя прибытия

Модель обучается следующим образом:

>>> from sklearn.svm import LinearSVR
>>> svm_reg = LinearSVR(epsilon=1.5)
>>> svm_reg.fit(X_train, y_train)
LinearSVR(C=1.0, dual=True, epsilon=1.5, fit_intercept=True,
intercept_scaling=1.0, loss='epsilon_insensitive', max_iter=1000, random_state=None, tol=0.0001, verbose=0)
>>> predictions = svm_reg.predict(X_val)
>>> predictions
array([100.75090575, 109.08222631,  79.81544167, ...,  94.50700112,
        55.65495607,  65.5248653 ])

Когда эта модель была проверена на тестовом наборе, было получено RMSE (среднеквадратичная ошибка) 44,6 вместе с MAE (средняя абсолютная ошибка) 29,5. При среднем значении ADR, равном 105, модель действительно демонстрирует степень предсказательной силы при оценке значений ADR для клиентов.

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

from interpret.ext.blackbox import MimicExplainer
from interpret.ext.glassbox import LinearExplainableModel
explainer = MimicExplainer(svm_reg, 
                           X_train, 
                           LinearExplainableModel)

MimicExplainer - это модель черного ящика, а LinearExplainableModel используется как глобальный суррогат этой модели черного ящика.

Обратите внимание, что при запуске модели можно установить augment_data = True, если вы имеете дело с данными большой размерности, то есть в ситуации, когда количество столбцов превышает количество строк. Это допускает передискретизацию образцов инициализации.

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

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

global_explanation = explainer.explain_global(X_val)
sorted_global_importance_values = global_explanation.get_ranked_global_values()
sorted_global_importance_names = global_explanation.get_ranked_global_names()
dict(zip(sorted_global_importance_names, sorted_global_importance_values))
global_explanation.get_feature_importance_dict()

Вот результат:

{3: 8.81513709127725,
 7: 4.9616362270740995,
 1: 4.959263897550327,
 6: 2.593931464493208,
 2: 0.9707145503848649,
 5: 0.8455564214901589,
 4: 0.505321879369921,
 0: 0.0}

Из приведенного выше номера функции 3 (рыночный сегмент), 7 (неделя прибытия) и 1 (отмена бронирования) обозначены как наиболее важные функции, влияющие на ADR клиентов.

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

Вот пример.

Из набора для валидации определяются важные характеристики и их значения для клиентов, заказанных от 10 до 15.

local_explanation = explainer.explain_local(X_val[10:15])
sorted_local_importance_names = local_explanation.get_ranked_local_names()
sorted_local_importance_values = local_explanation.get_ranked_local_values()

Вот выявленные важные особенности и их ценности:

>>> sorted_local_importance_names
[[1, 3, 2, 6,  5, 4, 0, 7], [7, 3, 2, 6, 5, 4, 1, 0], [6, 5, 4, 1, 0, 2, 7, 3], [6, 3,  5, 4, 1, 0, 2, 7], [3, 7, 6, 5, 4, 1, 0, 2]]
>>> sorted_local_importance_values
[[17.833762274315003,  9.1394041860457, 1.1694515257954607, 0.0, -0.0, -0.0, 0.0,  -1.707920714865971], [9.955928069584559, 9.1394041860457,  1.1694515257954607, 0.0, -0.0, -0.0, 0.0, 0.0], [0.0, -0.0, -0.0, 0.0,  0.0, -0.5708037209239748, -11.288939359236048, -13.709106279068548],  [19.017733248096473, 9.1394041860457, -0.0, -0.0, 0.0, 0.0,  -0.7448292455959183, -5.040448938994693], [9.1394041860457,  6.623399845455836, 0.0, -0.0, -0.0, 0.0, 0.0, -0.9884649801366393]]

Это позволяет клиенту изолировать важность функции. Например, функция 1 (отмена бронирования) была наиболее влиятельным фактором для клиента 10, тогда как функция 7 (неделя прибытия) была наиболее влиятельным фактором для клиента 11.

XGBRegressor

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

Модель была определена следующим образом:

from xgboost import XGBRegressormodel = XGBRegressor(objective='reg:squarederror', n_estimators=1000)
model.fit(X_train, Y_train)

Вот определенные параметры модели:

Как видно из вышеизложенного, существует множество параметров модели, которые можно изменить при обучении XGBRegressor. Однако в этом случае для n_estimators установлено значение 1000. Это определяет количество деревьев в модели XGBoost. Задача установлена ​​на reg: squarederror, то есть регрессия с квадратом потерь, которая более серьезно наказывает ошибки при экстремальных значениях.

Среднеквадратичная погрешность, полученная для проверочного набора, составила 50,14, а MAE - 38,63, что ниже среднего значения 109, полученного для этого набора.

Используя MimicExplainer, интерпретируемость результатов модели теперь может быть сгенерирована аналогично предыдущему примеру:

from interpret.ext.blackbox import MimicExplainer
from interpret.ext.glassbox import LinearExplainableModel
explainer = MimicExplainer(model, 
                           X_train, 
                           LinearExplainableModel)

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

global_explanation = explainer.explain_global(X_val)
sorted_global_importance_values = global_explanation.get_ranked_global_values()
sorted_global_importance_names = global_explanation.get_ranked_global_names()
dict(zip(sorted_global_importance_names, sorted_global_importance_values))
global_explanation.get_feature_importance_dict()

Вот результаты:

{3: 10.580821439553645,
 2: 7.795196757642633,
 1: 4.973377270096975,
 4: 2.329894438847138,
 0: 1.382442979985477}

Из вышесказанного следует, что задержка для функции 3 (t-4) имеет наибольшее значение при прогнозировании еженедельных отмен в отелях во время t.

Однако что, если мы хотим изолировать определенные недели?

Взяв набор для проверки, давайте выделим недели в наблюдениях с 8 по 13 (что соответствует 2017 году, неделям с 13 по 18).

local_explanation = explainer.explain_local(X_val[8:13])
sorted_local_importance_names = local_explanation.get_ranked_local_names()
sorted_local_importance_values = local_explanation.get_ranked_local_values()

Вот результаты:

>>> sorted_local_importance_names
[[4, 0, 2, 1, 3], [3, 4, 1, 0, 2], [3, 4, 1, 2, 0], [3, 2, 0, 4, 1], [2, 3, 4, 0, 1]]
>>> sorted_local_importance_values
[[1.2079747395122986, 0.655418467841234, -2.068988871651338,  -5.677678197831921, -16.414222669030814], [5.880283637250306,  1.524120206263528, 1.157876862894971, -1.807324914948728,  -11.282397723111108], [7.472748373413244, 7.056665874410039,  6.562734352772048, 3.8926286204696896, 0.353858053622055],  [35.340881256264645, 4.976559073582604, 2.0627004008640695,  1.1289383728244913, -2.3393838658490202], [23.945342003058602,  5.4821674532095725, 1.287011106200106, -0.7518634651816014,  -2.975249452893382]]

Такое определение важных характеристик во временном ряду может потенциально дать полезную информацию о важности запаздывающих значений для прогнозирования отмен в разные недели. Например, мы можем видеть, что при прогнозировании отмен на 13-й неделе задержка в момент t-5 (характеристика 4) была определена как наиболее важная характеристика.

Однако при прогнозировании отмены на 18-й неделе наиболее важной была определена задержка в момент t-3 (характеристика 2).

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

Вывод

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

В частности, мы видели:

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

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

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