Доброго времени суток, уважаемые читатели! Сегодня мы вновь рады приветствовать вас в увлекательном мире дата-сайентистов банка "Открытие". На связи Иван Кондраков, Константин Грушин и Станислав Арешин. Недавно мы поделились с вами нашим пайплайном разработки линейных моделей для решения задач бинарной классификации. Теперь же мы решили поведать о нашем опыте построения моделей градиентного бустинга. За последнее время команда проделала колоссальную работу: мы протестировали различные методы отбора факторов, нашли новые инсайты в данных, провели интересную (а, главное, полезную!) аналитическую работу и решили несколько Ad-hoc задач. Зовите всех к экранам, мы начинаем! Итак, в первую очередь следует рассказать о самой решаемой задаче и о наших данных. Сравнение подходов было проведено на модели КИК (Кредитование на исполнение контракта). Это модель предсказания вероятности дефолтов клиентов, которым банк выдает кредит на исполнение контракта по 44-ФЗ, 223-ФЗ и 615-ПП. В случае выдачи экспресс-гарантии клиент дополнительно оценивается моделью КИК. И принимается решение о выдаче кредита на исполнение контракта, по которому была запрошена гарантия. Целевая переменная — просрочка по клиенту 90+ на горизонте 18 месяцев.  Наблюдения состоят из нескольких выборок: Весь объем выданных экспресс-гарантий; Набор не выданных экспресс-гарантий (отказные, а также одобренные, но не выданные); Набор заключенных контрактов для транзакционных клиентов (так называемые условные заявки). Также вкратце напомним пайплайн построения линейной модели для тех, кто все еще не ознакомился с нашей предыдущей статьей (а мы очень советуем!): Текущая модель логистической регрессии является стекингом 6 модулей, разработанных на 6 различных подвыборках, определяемых критериями применимости модуля: Анкетный модуль, Модуль кредитной истории, Модуль контрактной истории, Модуль транзакционной истории, Модуль судебной истории, Модуль финансовой отчетности. Перед нами стоит задача построения моделей градиентного бустинга и анализа полученных результатов, разумеется, в сравнении с существующей линейной моделью и ее модулями. Нам важно понять, насколько лучше алгоритм бустинга решает задачу ранжирования клиентов, мы оцениваем метрику Gini, смотрим на ее значение и на доверительные интервалы [0,025; 0,975]. Исходя из концепции построения логистической регрессии для адекватного сравнения мы строим следующие модели бустинга: Модель на всех факторах и всех наблюдениях, сравнение которой будем проводить с моделью стекинга; Одномодульные модели по каждому модулю, которые логично сопоставить с одномодульными моделями логистической регрессии. Стоит сказать, что как базовое решение мы выбрали алгоритм CatBoost. Разработанный нашей командой подход к построению моделей градиентного бустинга — это некий набор методов для отбора факторов, наиболее подходящих под решение поставленной задачи. Есть методы, которые мы использовали во всех модулях. Есть методы, которые применялись для конкретных модулей. В настоящем разделе мы рассмотрим эти методы в простых определениях, чтобы дальше было удобнее ориентироваться в статье.  Первичный отбор факторов Первичный отбор факторов — это свод правил, по которым на начальном этапе мы стараемся отсеять факторы, содержащие слишком много пропусков, много уникальных категорий, нестабильные во времени. Пример этих правил приведен ниже: Удаление факторов, в которых более 95% значений — пропуски; Удаление категориальных факторов с сильной грануляцией; Удаление факторов по PSI train/test/val/oot или по годам. Отметим, что в отдельных модулях некоторых этапов может не быть или они могут быть проведены позже. Например, расчет PSI не всегда хорошо проводить в самом начале, так как на большом количестве факторов вычислить PSI довольно затратно по времени. Permutation importance Данный метод, пожалуй, основной. Мы применяли его на определенном этапе при построении каждой нашей модели. Permutation importance используется для расчета важности факторов и последующего отбора в зависимости от критерия. Например: Выбор топ N факторов; Отбор факторов, средняя важность которых больше 0; Выбор факторов, важность которых выше важности случайного фактора. Сама важность фактора определяется как снижение оценки модели по целевой метрике на валидационной выборке при случайной перестановке значений этого фактора. Процедура нарушает связь между фактором и целевой переменной. Поэтому снижение метрики показывает, насколько сильно модель зависит от фактора. Преимущество этой техники в том, что она не зависит от выбранного типа модели, зависит от целевой метрики и может быть рассчитана многократно для каждого фактора при различных перестановках. К недостаткам можно отнести требование к наличию заранее построенной модели, относительно долгий расчет пермутаций, который также зависит от скорости расчета метрики. Prediction value change Prediction value change показывает, насколько в среднем изменится прогноз модели при изменении значения фактора. Чем больше изменяется прогноз, тем  важнее рассматриваемый фактор. Метод чем-то похож на рассмотренный ранее Permutation importance, однако у него есть свои плюсы и минусы. Из плюсов стоит сказать о том, что метод довольно шустрый, а для алгоритма CatBoost вообще считается по дефолту, если мы оптимизируем LogLoss. Но есть важный недостаток, за счет которого им нельзя заменить так понравившийся нам Permutation importance: а именно, мы не можем оценить влияние на целевую метрику, так как знаем только факт, что предсказания изменились, а на вопрос, в какую сторону, данный алгоритм не отвечает. Таким образом, Prediction value change хорошо использовать для отбора на одном из первых этапов, когда факторов слишком много для расчета пермутаций за адекватное время, а также для некоего быстрого ранжирования факторов по важности для применения других методов. Отбор по SHAP Значения SHAP (SHapley Additive exPlanations) используются для интерпретации результатов моделей машинного обучения. Они дают возможность объяснить результаты любой модели машинного обучения путем количественной оценки важности каждого признака в определении результатов. Идея значений SHAP заключается в том, чтобы разложить прогноз, сделанный моделью, на вклад каждого признака. Значения SHAP основаны на концепции значений Шэпли, которые первоначально были введены в теории кооперативных игр. Значения Шэпли использовались для измерения вклада каждого игрока в коалиционной игре, а SHAP расширяет эту концепцию на модели машинного обучения. Помимо интерпретации моделей, значения SHAP также можно использовать на одном из первых этапов отбора, так как python библиотека shap достаточно хорошо оптимизирована, в связи с чем вычисления не занимают много времени даже для очень большого количества факторов. Однако этот метод, как и два предыдущих, требует заранее обученной модели. Корреляционный отбор Для начала необходимо получить ранжированный по важности список факторов. Тут можно использовать различные подходы, например: Сортировать факторы по gini фактора; Строить однофакторные модели; Использовать важности метода Prediction value change; Использовать важности метода Permutation importance. Мы остановились на последнем. Затем все просто: начинаем с наилучшего фактора, итерационно рассматриваем новый фактор. Если корреляция нового фактора с одним из уже добавленных больше заданного порога, пропускаем этот фактор, в противном случае добавляем его в итоговый список. Мы используем корреляцию Спирмана для поиска монотонной зависимости. Важно, что данный этап тоже довольно затратный по времени, поэтому его стоит выполнять одним из последних на небольшом количестве факторов. Вы, наверное, уже заскучали, но без описания используемых методов неподготовленному читателю было бы трудно понять, что происходит далее. Мы постарались максимально кратко и простыми словами рассказать, что применяли. А теперь, наконец, давайте посмотрим, как мы это применяли и что получили в итоге. Начинаем с самого интересного — рассмотрим модель на всех факторах. А потом посмотрим на модели на факторах из отдельных источников данных.  Ниже представлена воронка отбора факторов нашей самой большой модели: Данные на первых трех этапах были разбиты по партициям в зависимости от их принадлежности к определенному источнику. Практика не очень хорошая, но нам пришлось ее применить из-за ограничений на вычислительные мощности. На первом этапе проводится обор по первичным статистикам, затем Wrapper отбор по Prediction Value Change, как наиболее быстрый способ отсеять часть не влияющих на итоговые предсказания факторов. Когда остается достаточно факторов, чтобы отбор по PSI не был долгим, мы его проводим, после чего строим бейслайн модель на 935 факторах и рассчитываем пермутации. Далее рассматриваем разные топы факторов и оцениваем наши результаты на валидации. Основная цель данного этапа выбрать такую модель, gini которой не сильно ниже бейслайн модели (а может, и выше), но при этом количество факторов в ней заметно ниже. Это связано с модельным риском расчета слишком большого количества факторов. Мы хотели бы продемонстрировать вам доверительные интервалы всех построенных в рамках этой подзадачи моделей, оценка проводилась бутстрепом на 500 итерациях на выборке OOT: Итоговой моделью была выбрана модель "топ-250" (на графике выделена красным), как наиболее удовлетворяющая поставленным нами критериям. Gini данной модели 79,21, что довольно значительно превосходит нашу линейную стекинговую модель (выделена голубым), у которой 70,48. Плюс к этому ресурсы, затраченные на построение стекинга нескольких модулей линейной модели, несопоставимы с затратами на построение модели бустинга. Еще при построении этой модели была решена одна очень интересная ad-hoc задачка. По воронке отбора факторов видно, что топ числовых постоянно меняется, а категориальные факторы сохраняются, то есть в топ-250 факторов их столько же, сколько и в модели на 935 факторах. Было решено построить и сравнить модели на только категориальных гранулированных, не гранулированных и числовых факторах: Модель Количество факторов Gini OOT Только гранулированные категориальные факторы 26 76,41 Только не гранулированные категориальные факторы 18 76,52 Только числовые факторы 917 76,45 Видно, что модели на категориальных факторах показывают себя так же, как и модель на числовых, а факторов в них меньше в разы. Нас этот результат очень удивил: судя по всему, наши категориальные факторы работают ну уж слишком хорошо 😊. Ну и стоит отдать должное алгоритму CatBoost, не зря он Categorical и действительно хорошо показал себя на категориальных фичах. Перед рассказом об одномодульных моделях нам важно сделать еще одно небольшое отступление. При их построении мы столкнулись с проблемой переобучения на выборке OOT. Справедливости ради скажем, что переобучение было и у модели на всех факторах, но тут оно оказалось сильнее и нам удалось выяснить причину. Дело в том, что в обучающей выборке присутствуют полные дубликаты (записи, у которых одинаковые значения всех рассматриваемых факторов), а для бустинга это приводит к увеличению весов определенных объектов. При уменьшении размерности признакового пространства количество дублированных записей растет. Этой проблемы не было в модели на всех факторах, так как там факторы разной природы, то есть более разнообразное признаковое пространство. В подтверждение вышесказанных слов приводим результаты эксперимента: Строим модель LightGBM с подсчетом количества сплитов по фактору; Сортируем факторы по количеству сплитов; Удаляем полные дубли (KEY, N_FEATURES, TARGET) по подмножествам отсортированных в порядке количества сплитов факторов с шагом 5 штук; Удаляем полные дубли (KEY, N_FEATURES, TARGET) по подмножествам случайно      отсортированных факторов с шагом 5 штук; Строим графики изменения количества наблюдений в обучающей выборке в зависимости от подмножества факторов и сравниваем результаты. По результатам эксперимента видно, что модель чаще делает сплиты по дублированным факторам, дельта в случае удаления по отсортированному подмножеству 200 тыс. наблюдений, а при случайном порядке 20 тыс. наблюдений. Это и приводит к переобучению. Поэтому решено удалять из выборок объекты, которые являются полными дубликатами по подмножеству факторов на этапе обучения модели. Такой подход приводит к построению более стабильных одномодульных моделей. Возвращаемся к результатам и на очереди первая одномодульная модель — Модуль судебной истории. Спойлер... В данном модуле на первых трех этапах отбор также происходил по батчам, но теперь мы просто разделили общее количество факторов на 5 частей.  Вместо Prediction Value Change считаем важности Permutation Importance, чтобы сразу оценить влияние факторов на целевую метрику, а не на сами предсказания, благо ресурсов для такого расчета в данном модуле было достаточно. Факторы были отобраны по критерию средняя важность минус стандартное отклонение больше нуля. Далее, рассматривая топы факторов, была выбрана модель на 100 факторах по критериям, описанным ранее. Что касается результатов, методом бутстрепа на 10000 повторениях были рассчитаны доверительные интервалы Gini линейной модели и итоговой модели бустинга для этого модуля на выборке OOT: На графике видно, что прирост (не побоимся этого слова) огромный, а доверительные интервалы моделей не пересекаются. Если говорить о цифрах, Gini линейной модели 26,52, а у бустинга — 40,75. Кажется, пора менять модель…. Двигаемся дальше, на очереди финансовый модуль и, скажем честно, он самый простой, но при этом доставил больше всего проблем. Дело в том, что финансовые факторы в течение года не меняются, что порождает ну очень дублированную выборку. Так что именно на финансовом модуле мы впервые обнаружили переобучение модели из-за полных дубликатов в выборке. Плюс финансовые факторы очень сильно коррелируют между собой. Давайте взглянем на нашу воронку: В данном модуле меньше всего факторов и меньше всего наблюдений, проходящих критерии применимости, поэтому пайплайн выглядит максимально просто. Осведомленный читатель, конечно, скажет, что для бустинга не стоит удалять коррелирующие факторы, но мы выделили для себя два поинта:  Во-первых, удаление коррелированных факторов значимо не сказывается на метрике качества модели, при этом позволяет освободить признаковое пространство от лишних фичей. Так наша модель для финансового модуля работает лучше, то есть при 26 факторах метрика Gini выше, чем у модели со 165 факторами; Во-вторых, наличие коррелированных факторов зашумляет результаты оценки важностей. Например, удалив такие факторы, гораздо проще интерпретировать результаты конкретно этого модуля библиотекой shap, мы не засоряем наш summary_plot практически одинаковыми по бизнес-смыслу факторами. Об интерпретации вкратце поговорим немного позже. По итогу мы получили модель, Gini которой на OOT выборке 59,89, при этом у линейной модели 56,00. Прирост самый низкий из всех построенных моделей. Это наталкивает на мысль о том, что для финансового модуля, возможно, стоит оставить линейную модель, так как пространство признаков довольно простое, их ожидаемая бизнес-логика в основном линейная и как будто бы линейная модель в данном кейсе — хороший и стабильный подход.  В заключение снова приведем график доверительных интервалов на выборке OOT, результаты же надо как-то подтверждать😊 Ну и завершаем наш рассказ о моделях контрактным модулем. У контрактного модуля наиболее разнообразное признаковое пространство (топ-2 после модели на всех факторах), поэтому проблема дублей не так явно выражена. При разработке вычисления проводились на так называемой "тяжелой ноде", поэтому в ресурсах нас практически не ограничивали. Тем не менее, пайплайн этого модуля не суперзатратный по времени и его точно так же можно было бы разделить на батчи факторов. Ключевое отличие — в применении отбора по среднему абсолютному значению SHAP на втором этапе. Данный подход работает достаточно быстро даже на 4,5 тысячах факторов благодаря великолепно оптимизированной библиотеке shap и позволяет отбросить значительное количество факторов. Главное — построить модель. Оставшиеся действия мы уже комментировали ранее.   Итоговая модель на топ-50 факторах, прирост тоже хороший, ее Gini 45,34, а у линейной 33,33. А вот и доверительные интервалы: Несколько слов об интерпретации данных моделей. Для банка важно объяснить бизнесу, как факторы работают внутри модели, соответствуют ли они заложенной бизнес-логике. Мы для этого используем библиотеку shap. В среднем 90% факторов работают корректно. Однако встречаются факторы, для которых логику либо трудно определить, либо она противоположна, что очень плохо. Такие факторы стоит удалить, пусть их удаление и приводит к снижению Gini итоговых моделей. Сейчас мы разрабатываем инструмент для автоматического сопоставления бизнес логики и SHAP значений. Ведь мы же бережем время, деньги, нервы😊 Кто не понял, это отсылка на нашу первую статью, которую мы также рекомендуем к прочтению! Настало время подводить итоги. Приведенный в качестве примера список моделей полностью описывает все разветвления нашего пайплайна. Полученные модели градиентного бустинга значительно превосходят линейные в качестве (финансовый модуль, ты не считаешься). Однако мы сталкиваемся с новыми проблемами, а именно: Интерпретация влияния факторов на итоговый результат модели; Модельный риск расчета большого количества факторов. Но не существует нерешаемых проблем, и мы уже сейчас успешно движемся к тому, чтобы помножить их на ноль. В заключение приводим наши планы: Оценка возможности отбора факторов по соответствию заложенной бизнес-логики  и SHAP значений; Оценка использования алгоритмов forward/backward selection по финальному списку факторов; Оценка влияния подбора гиперпараметров на итоговый скор модели. Стекинг результатов одномодульных моделей бустинга. Здесь интересно выяснить, лучше ли она модели бустинга на всех факторах, а также дополнительно сравнить со стекингом линейных моделей.   На этом мы заканчиваем наш рассказ, но продолжение не заставит себя ждать!) Если у вас есть интересные практики отбора факторов для моделей градиентного бустинга, интерпретации моделей для заказчиков, просим отписаться в комментариях, нам будет интересно ознакомиться!