В этой статье я расскажу про свои первые ML-соревнования Tinkoff Data Science Challenge. Турнир по машинному обучению проводился онлайн с 10 января по 27 февраля 2017 года. Конкурс был индивидуальный: обмен кодом и данными между участниками запрещались, а в день можно было отправлять не более 3-х решений. Промежуточный рейтинг участников отображался в режиме реального времени в виде таблицы лидеров на 30% тестовых данных. Финальный результат строился на 70% тестовых данных [1]. Это был мой первый опыт участия в таких мероприятиях, кроме того, я не слишком знаком с предметной областью – никогда не брал кредиты. Однако, с помощью достаточно простых моделей градиентного бустинга и сбора данных из открытых источников мне удалось занять 16 место.
Постановка задачи
Требуется предсказать, выберет ли покупатель магазина электроники и бытовой техники кредит от Tinkoff.ru. Банк работает с сетью магазинов, в которой также присутствуют и другие кредитные организации. Онлайн-заявка на кредит от покупателя поступает одновременно в несколько банков, часть из которых ее одобряют. После этого покупатель выбирает, в каком банке взять кредит. Результатом ML-моделирования является число, которое означает вероятность выбора кредита конкретным покупателем.
Исходный датасет от организаторов соревнования включал следующую информацию:
- категориальные признаки (образование, работа, семейное положение, пол и регион проживания потенциального заемщика, а также номер предполагаемого тарифа);
- вещественные признаки (возраст, месячный заработок, общее количество кредитов и число просроченных кредитов потенциального заемщика, а также ожидаемая сумма и срок кредитования);
- 1 нормированная переменная с неизвестным смыслом, предположительно, оценка кредитного скоринга;
- объем тренировочной выборки – 170 тысяч записей;
- объем тестовой выборки – 91 тысяча записей;
- существенный процент ошибок и пропущенных значений.
На практике ML-модели кредитного скоринга очень простые: каждому возможному значению любого признака присваивается некоторый вес, потом веса суммируются (рис.1.).
Рис. 1. Пример скоринговой карты
Модель должна быть очень простой, чтобы рассчитаться онлайн. Поэтому необходимо заложить устойчивость к выбросам, когда отбрасываются крайние значения, например, возраст более 60 лет. Качество модели оценивается по кривой ошибок, через значение показателя ROC AUC, который чем больше, тем лучше.
Выбор алгоритмов
Сначала я выбрал библиотеку LightGBM от Microsoft [2], которая реализует градиентный бустинг над решающими деревьями с очень высокой скоростью, даже при работе с категориальными признаками. Однако, при том, что LightGBM работает примерно в 10 раз быстрее, чем XGBoost [3], она немного проигрывает по качеству. Поэтому следует сначала обучить ML-модель с помощью LightGBM, затем взять лучшие параметры ее настройки и дотренировать с помощью XGBoost.
Для отбора признаков использовался жадный алгоритм, а для финальной настройки (оптимизации гиперпараметров) – библиотека Hyperopt [4].
Подготовка датасета
Наибольший интерес при подготовке датасета представляет работа с категориальными признаками, поскольку эти данные необходимо очень тщательно чистить. Например, в переменной «регион проживания потенциального заемщика» можно было обнаружить число, город, область, республику или край, написанные с опечатками и разными вариантами названий, в т.ч. устаревшими (рис. 2). К примеру, «РеспубликаТатарстан», «Пермская область» вместо «Пермский край», «Горьковская область» вместо «Нижегородская» и т.д. Одних только вариантов написания слова «область» встречалось как минимум 2: «область», «обл.».
Рис. 2. Пример значений признака «регион проживания»
Вопрос кодирования кредитных тарифов также был нетривиальным, поскольку данные по ним выглядели как вещественные числа, но относились к категориальным признакам. Очистив выборку от многозначных и пропущенных значений, я запустил на ней градиентный бустинг с помощью LightGBM, а затем XGBoost. Полученные результаты заняли 70-е место в рейтинге участников соревнований, и я решил обогатить датасет, чтобы повысить точность прогноза.
Для генерации дополнительных признаков было определено несколько направлений:
- кредитные условия от разных банков;
- экономическая статистика по регионам (средняя зарплата, количество жителей, соотношение бедного и богатого населения и т.д.).
Поскольку исходный датасет от организаторов соревнований не включал этой информации, встал вопрос о ее получении из других источников. Для этого я решил использовать открытые данные: государственную статистику и предложения по кредитам, доступные на банковских сайтах.
Моделирование с данными из открытых источников
На основе открытых данных из государственных ведомств не получилось сгенерировать какие-либо интересные предикторы. С банковскими предложениями тоже оказалось не так все просто. Во-первых, в открытом доступе выложена лишь общая информация по кредитным условиям: примерный размер процентной ставки, список нужных документов, максимальная сумма и срок кредитования. Однако, на практике значения всех этих переменных рассчитываются индивидуально для каждого клиента. Тем не менее, удалось выяснить, что почти все банки предлагают специальные условия для кредита на 10 месяцев. Дальше я решил проанализировать частность поисковых запросов о Тинькофф-банке по регионам с помощью веб-сервиса Wordstat (рис. 3).
Рис. 3. Анализ популярности поисковых запросов через сервис Wordstat
Таким образом, с помощью Wordstat, была собрана статистика поисковых запросов по банкам-конкурентам, которые дают кредиты онлайн: Ренессанс Кредит, Хоум Кредит Банк, ОТП Банк, Почта Банк. Обогатив датасет информацией о популярности банков в разных регионах, я снова запустил LightGBM и получил 40-е место в рейтинге. Затем попробовал контейнеры (pipelines) с различными вариантами кодирования предикторов для замены пропусков и обработки категориальных признаков. После тестирования примерно 30 альтернатив pipelines моя модель достигла 21-го места.
Оптимизация ML-модели и разбор полетов
Для дальнейшего улучшения я объединил в ансамбль несколько не коррелирующих между собой pipelines с помощью простейшего стекинга – блендинга. На заключительном этапе, при переходе от LightGBM к XGBoost выяснилось, что последний работает с категориальными признаками по-другому. Поэтому пришлось заново обучать модели.
Также снова был выполнен отбор признаков с помощью одиночного LightGBM, 250 решающих деревьев, без регуляризации (рис. 4). Расположение 2-х банков-конкурентов (Ренессанс Кредит и ОТП банк) рядом с Тинькофф-банком обусловлено похожестью их кредитных предложений. На практике это означает, если онлайн-заявка клиента была одобрена несколькими кредитными организациями, кроме Тинькофф-банка, то чаще всего он выбирает именно их.
Рис. 4. Отбор признаков в лучшем одиночном LightGBM
В итоге, за счет обогащения датасета информацией из Wordstat, блендингом и стекингом лучших pipelines (5LightGBM + XGBoost) с линейной моделью на 2-м уровне, мне удалось достичь 16-го места в соревнованиях (рис. 5).
Рис. 5. Эволюция рейтинга моих ML-моделей в соревнованиях
Анализ других решений
Среди других результатов соревнований меня больше всего заинтересовали решения участников, занявших 7-е, 3-е и 1-е места (рис.6). Например, участник, занявший 7-е место, просто почистил исходный датасет, не обогащая его данными из сторонних источников. Дополнительные признаки он генерировал из суммы кредита, предполагая, что если размер кредита заканчивается на три девятки, то это одна торговая сеть, если 3 нуля в конце, то другая и т.д. В качестве производных предикторов он использовал статистические преобразования первичных переменных: средние отклонения, квантили и т.д.
На 3-ем месте, помимо обычной обработки признаков (чистка, определение частотности, разбиение по квантилям) в качестве модели использовалась простая нейросеть с 2-мя полносвязными слоями. Также применялся градиентный бустинг на XGBoost и блендинг [5].
Наконец, решение, занявшее 1-е место, потрясает своей простой и красотой реализации: на исходных данных был просто запущен скрипт собственной разработки, без дополнительной подготовки выборки, игр с предикторами и обогащения данных. Основу алгоритма составляло target-кодирование (с регуляризацией) по всем категориальным признакам, затем их пар. Поверх этого был запущен xgboost [6, 7].
Рис.6. Рейтинг других участников соревнований
Выводы
Проанализировав личный опыт и итоги других участников, я сделал следующие выводы:
- очистка данных – важный этап подготовки датасета, который может потребовать достаточно много времени и усилий;
- обогащение исходного датасета дает результаты существенно выше средних, но приходится тратить дополнительное время на поиск и обработку информации из сторонних источников;
- target-кодирование (по значению целевого признака) позволяет получить отличные показатели качества.
Кроме того, я пришел к заключению, что при знании предметной области и заинтересованности в задаче можно добиться хороших результатов и с простой моделью: одним случайным лесом, XGBoost или LightGBM. А само участие в соревнованиях помогло мне узнать много нового и добавило немного спортивного азарта в мою ML-практику.
Полезные ссылки:
- Описание соревнования и исходных данных: https://boosters.pro/championship/tinkoff1/
- Официальная документация по LightGBM: https://lightgbm.readthedocs.io/en/latest/
- Официальная документация по XGBoost: https://xgboost.readthedocs.io/en/latest/
- Репозиторий библиотеки hyperopt и ссылки на официальную документацию: https://github.com/hyperopt/hyperopt
- Решение участника, занявшего 3-е место: https://github.com/vasiliyrubtsov/tinkoff
- Видео-комментарий участника, занявшего 1-е место: https://www.youtube.com/watch?v=NVKDSNM702k
- Презентация участника, занявшего 1-е место: https://gh.mltrainings.ru/presentations/Semenov_TinkoffChallenge_2017.pdf