Предисловие

Статистика и машинное обучение

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

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

Машинное обучение иногда называют прикладной или прославленной статистикой, и мнений гораздо больше. Есть некоторое совпадение между статистикой и машинным обучением, но различия между этими полями в основном связаны с приложением. В статье 2001 года Статистическое моделирование: две культуры Лео Брейман разделил сферу статистического моделирования на два сообщества:

  1. Моделирование данных. Это сообщество полагается на предположение о существовании стохастической модели данных и обычно сосредоточено на оценке параметров на основе данных и использовании модели для получения информации. Оценка основана на критериях согласия и остаточном анализе.
  2. Алгоритмическое моделирование. Это сообщество считает механизм данных неизвестным. Входные переменные x используются для прогнозирования переменной y ответа. Оценка основана на точности прогнозов [1].

Машинное обучение заботится о производительности модели, но объяснимость попадает в категорию обучающей информации (первое сообщество - статистика). Тогда, может быть, есть чему поучиться у статистиков? Р. А. Фишер выделил три основных аспекта, которые следует учитывать для правильного вывода:

  1. Спецификация модели. Джордж Э. П. Бокс отметил, что «все модели неправильные, но некоторые полезны». Этот шаг включает установку моделей-кандидатов и выбор одной или нескольких моделей. Выбор моделей-кандидатов - непростая задача, обычно это субъективный процесс, основанный на опыте.
  2. Оценка параметров модели. параметры модели оцениваются или извлекаются из данных (внутренняя конфигурация) и требуются для прогнозирования (например, коэффициентов оценок линейной модели, оценок весов нейронной сети) [2]. На практике оценка параметров модели в Python обычно требует вызова .fit() метода модели.
  3. Оценка точности. Здесь важно отложить некоторые данные для оценки модели и выбрать показатели ошибок для измерения точности модели. Алгоритмы машинного обучения могут потребовать настройки гиперпараметров. Гиперпараметры обычно указываются пользователем (внешняя конфигурация) и помогают оценить параметры модели. Современные алгоритмы машинного обучения содержат от нескольких до сотен гиперпараметров. Стандартный подход к выбору гиперпараметров - выполнить k-кратную перекрестную проверку и оптимизировать желаемую метрику [3].

В статистике целью моделирования является аппроксимация и понимание процесса генерации данных. Понятно, что если разные алгоритмы машинного обучения (SVM, k-NN, XGBoost и т. Д.) Будут соответствовать одному и тому же набору данных, возникнут различия в том, как они объясняют данные. Ни один из них не рассматривается как «истинная модель», которая генерировала данные, а скорее как абстракция эмпирических данных, которая может помочь ответить на определенные вопросы. Кроме того:

«Модель не отражает убеждений или обязательств в отношении процесса генерации данных. Его назначение чисто функциональное. Ни один специалист по ОД не будет готов свидетельствовать о «валидности» модели; это не имеет значения в машинном обучении, поскольку модель на самом деле только способствует его эффективности »[4].

Подводя итог, можно сказать, что машинное обучение заботится о производительности, и часто отношения функций с целью считаются черным ящиком. Но как только объяснимость модели становится важной, следует проявлять больше осторожности (положите шляпу статистика). Например, некоторые статистические модели предполагают независимость функций, в то время как специалист по анализу данных может счесть это несущественным. Если существует 10 важных предикторов X, которые обладают высокой степенью мультиколлинеарности (допустим, корреляция Пирсона ρ ›0,9), то может случиться так, что они разделят важность одного и того же основного драйвера и его Разглядеть внутреннее устройство такой модели будет сложнее, чем той, у которой меньше возможностей.

InterpretML

InterpretML - это новый фреймворк, поддерживаемый Microsoft, с простой идеей собрать существующие фреймворки интерпретации моделей в одном месте и упаковать их на практике. Он работает с обоими типами моделей: стеклянным ящиком (интерпретируемым - линейные модели, деревья решений и т. Д.) И черным ящиком (неинтерпретируемым - усиление градиента, SVM и т. Д.).

Еще одна интересная вещь, которую предлагает InterpretML, - это реализация модели стеклянного бокса - Explainable Boosting Machine (EBM). Авторы утверждают, что он разработан не только так, чтобы его можно было интерпретировать, но и чтобы иметь сопоставимую точность с такими популярными алгоритмами, как Random Forest, XGBoost и т. Д. Вы можете узнать больше о его механике в репозитории InterpretML и их исследовательской работе [5, 6] .

EDA

Данные

Для следующего эксперимента был выбран набор данных Прогнозирование кликов по рекламе из hackerearth. Чтобы загрузить данные, перейдите по ссылке (требуется вход в систему) и клонируйте этот репозиторий, чтобы получить доступ к коду.

Ради эксперимента была выбрана выборка поменьше - 100000. Этот набор данных удобен для экспериментов, потому что он имеет всего несколько предикторов (5 категориальных и 4 числовых) для выполнения бинарной классификации. Подробнее:

  • ID полностью уникален и тип объекта, не будет использоваться;
  • datetime содержит подробное время и может быть предварительно обработан различными способами, чтобы максимизировать его полезность;
  • siteid, offerid, category, merchant будут использоваться как числовые столбцы (даже если они фактически представляют категории с высокой мощностью);
  • countrycode, browserid, devid являются категориальными и поэтому будут предварительно обработаны и преобразованы в числовые.
  • click - целевая переменная, которая будет классифицирована. 1 относится к случаям, когда он был нажат.

Выборка данных случайным образом разделяется на обучающий (70%) и задерживающий (30%) наборы. Случайное разбиение поддерживает примерно одинаковую долю целевой переменной в обоих наборах (96% - 0 и 4% - 1).

Числовые особенности

На этом шаге давайте просто кратко проверим изменение функции по целевой переменной. Можно использовать популярные библиотеки визуализации, такие как matplotlib и seaborn, но это было бы слишком популярно для публикации в блоге. Давай попробуем что-нибудь другое. Например, библиотека визуализации Altair имеет несколько устрашающий синтаксис, но дает красивые графики.

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

Графики плотности Альтаира дают довольно изменчивые распределения (другие библиотеки по умолчанию сглаживают их сильнее). Распределения более или менее выровнены по числовым характеристикам, но есть заметный скачок category между 35 000 и 50 000 значений:

Категориальные особенности

Категориальные признаки с низкой мощностью можно передать с помощью тепловой карты. Поскольку цель click несбалансирована (количество кликов значительно меньше, чем отсутствие кликов), ключевым моментом здесь является отображение относительной частоты по группам (0 и 1 категория кликов в сумме равны 1 соответственно, если отсутствуют пропущенные значения). :

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

  • c и d countrycode;
  • Google Chrome и InternetExplorer browserid;
  • и Рабочий стол devid.

Обратите внимание, что этот набор данных, скорее всего, не очищен полностью, потому что одни и те же браузеры называются по-разному как отдельные категории (IE, Internet Explorer, и т. Д.), Но здесь это не будет учтено.

Модель конвейера

Обычно конвейер модели является более сложным, чем простой вызов методов .fit() и .predict(). Поэтому построим простой, но реалистичный конвейер. При этом важно смотреть вперед. Если какие-либо методы в структуре интерпретации модели не поддерживают отсутствующие значения или категориальные особенности, то это следует решить до построения модели. Например, ExplainableBoostingClassifier InterpretML выдаст следующую ошибку, если какая-либо из функций содержит пропущенные значения:

ValueError: отсутствующие значения в настоящее время не поддерживаются.

Конвейер будет состоять из следующих этапов:

  1. Преобразуйте функцию datetime в числовую (день, час, и т. Д.), Чтобы модель могла в полной мере использовать переменную даты. Для этого будет использоваться пользовательский DateTransformer() (навеянный этим сообщением в блоге и ответом StackOverflow).
  2. Категориальные признаки необходимо закодировать в числовом представлении, и есть разные способы сделать это. Вместо того, чтобы создавать множество фиктивных переменных, давайте посмотрим, могут ли алгоритмы повышения самостоятельно извлекать полезные шаблоны. Здесь OrdinalEncoder() был выбран из библиотеки category_encoders , поскольку версия scikit-learn не поддерживает отсутствующие значения или кодировку, отличную от образца.
  3. В наборе данных есть 3 функции, которые содержат пропущенные значения, и часто алгоритм машинного обучения не поддерживает их. Один из вариантов - вменять недостающие значения. Поскольку в этом наборе данных присутствует смесь категориальных и числовых характеристик, одно решение для вменения среднего, медианного или модового может иметь нежелательные побочные эффекты. Для этого эксперимента SimpleImputer(fill_value=0) должен сделать трюк, заменив отсутствующие значения на 0 (опять же, пусть алгоритм сам все думает).
  4. После преобразования данных последним шагом в конвейере является алгоритм прогнозирования (также называемый оценкой). Для сравнения будут построены два конвейера, один будет содержать ExplainableBoostingClassifier, а другой LGBMClassifier.

Проверка модели

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

Не вдаваясь в подробности метрики точности, можно использовать один удобный метод для проверки модели - classification_report() scikit-learn. В этом случае он использовался для обеих моделей в обучающем (70k) и удерживающем (30k) наборах и был сжат в единый фрейм данных:

Здесь отображаются показатели обучающего набора, чтобы увидеть, насколько хорошо модель усвоила обучающие данные. LightGBM может легко перекрыть меньшие наборы данных, и здесь он показывает более высокие значения метрик на обучающем наборе, чем Explainable Boosting Machine.

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

Интерпретация модели

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

Начнем с InterpretML, у него есть полезный ClassHistogram(), который позволяет выполнять некоторые операции EDA с данными. Есть нюанс. Чтобы использовать это, набор данных не может содержать пропущенные значения, что означает, что он должен пройти этапы конвейера. Поэтому давайте создадим обучающий набор, который будет предварительно обработан, а затем визуализировать его.

from interpret import show
from interpret.data import ClassHistogram
X_t_prep = pd.DataFrame(data=pipeline_ebm[0:3].transform(X_t), columns=feature_names)
hist = ClassHistogram().explain_data(X_t_prep, y_t, name = 'Train Data')
show(hist)

Это создает панель мониторинга, на которой отображаются интерактивные гистограммы, окрашенные click подсчетами. Поставляемый набор предварительно обработанных данных содержит только числовые функции, например, сейчасbrowserid находится в числовом представлении от 1 до 12. Две из browserid категорий показывают заметно высокий процент кликов (но с этой кодировкой неясно, какие именно):

Следующее, что нужно проверить, - это общие объяснения как с InterpretML, так и с SHAP. Поскольку конвейер не поддерживается напрямую, оценщик необходимо извлекать в каждом случае:

# InterpretML
ebm_global = pipeline_ebm['model'].explain_global()
show(ebm_global)
# SHAP
explainer = shap.TreeExplainer(pipeline_lgb['model'])
shap_values = explainer.shap_values(X_t_prep)
shap.summary_plot(shap_values, X_t_prep, plot_type="bar", plot_size=(10,5))

Сводка по важности функций показывает, что две категориальные характеристики countrycode и browserid очень важны. Их способность разделять клики уже была замечена в разделе EDA. Определенно есть небольшое разногласие между обоими оценщиками в важности характеристик. В чем они оба согласны, так это в том, что month - это наихудшая функция, не имеющая никакого значения. Для этого есть веская причина - у него нет дисперсии (все клики произошли в одном месяце).

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

#InterpretML
show(ebm_global)
#SHAP
shap.dependence_plot(ind="countrycode", shap_values=shap_values[0], features=X_t_prep, interaction_index=None)

В этом конкретном случае InterpretML имеет более привлекательную визуализацию, но они оба рассказывают одну и ту же историю (только в противоположных направлениях). График зависимости SHAP показывает, что коды стран 1 и 5 сильно влияют на прогноз click вниз до 0. InterpretML также показывает, что одни и те же коды стран имеют наибольшее влияние.

И, наконец, для сравнения локальных объяснений было выбрано одно случайное наблюдение.

ind = [69950]
# InterpretML
ebm_local = pipeline_ebm['model'].explain_local(X_t_prep.iloc[ind], y_t.iloc[ind], name='Local')
show(ebm_local)
# SHAP
shap.initjs()
shap.force_plot(explainer.expected_value[0], shap_values[0][ind,:], X_t_prep.iloc[ind])

EBM предсказал 0,35 и LightGBM 0,88, в то время как истинное значение было 1 - щелкнул. Графики SHAP и InterpertML показывают, что countrycode был основным драйвером в их соответствующих пояснениях. day = 17 имеет некоторое влияние на решение, но этот образец данных охватывает только один месяц, и в более реалистичном приложении создание переменной типа dayofweek должно быть более полезным.

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

Конечные заметки

В этом сообщении в блоге было кратко обсуждено, что нужно для построения конвейера, и это объяснимо. Обобщить:

  • Вначале есть данные. Любые шаги предварительной обработки повлияют на конвейер модели, прогнозы и объяснения. При построении объяснимой модели аналитик должен учитывать такие вещи, как несуществующие категориальные метки признаков, определение значения и полезности функции, обработка пропущенных значений и т. Д. Потому что это будет видно в конечном результате.
  • Порядковый кодировщик не требует создания большого количества столбцов в конвейере модели, но впоследствии усложнит интерпретируемость. Было бы больше ясности с кодировкой фиктивной переменной.
  • Функция без отклонений month на самом деле не принимала никаких решений в моделях LightGBM или Explaining Boosting Machine (EBM). В данном конкретном случае эту функцию можно было бы отбросить, но она, вероятно, станет интересной функцией в реальном мире, когда накопится больше данных за несколько месяцев.
  • Эта библиотека представляет алгоритм EBM, который имеет сравнимую точность с LightGBM и предназначен для интерпретации с помощью InterpretML framework. EBM требует более медленного обучения, но делает прогнозы быстрее, что может быть решающим фактором для модели в производстве.
  • Библиотека InterpretML также предоставляет такие инструменты, как ClassHistogram, которые могут быть полезны для проведения EDA, но вам может потребоваться выборка данных. Поскольку он интерактивен и работает под управлением Plotly, он может быстро стать чем-то, что требует много времени для загрузки по мере роста данных.

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

Спасибо за чтение, у вас есть примеры / предложения по улучшению (код доступен здесь)? Поделитесь ими в комментариях, спасибо! Также я рад подключиться к LinkedIn!

использованная литература

  1. Статистическое моделирование: две культуры
  2. В чем разница между параметром и гиперпараметром?
  3. Выбор модели и многомодельный вывод: практический теоретико-информационный подход, второе издание (гл. 1)
  4. Машинное обучение против статистики
  5. Репозиторий InterpretML
  6. InterpretML: Единая структура интерпретируемости машинного обучения