Всем привет! Меня зовут Андрей, недавно я присоединился к команде VS Robotics и занимаюсь проектом автопостроителя сценариев диалогов робота-оператора. В этом посте хочу поделиться историей своего трудоустройства и решением задачи LGD prediction, которое мне в этом очень помогло. Не секрет, что начинающим DS-специалистам приходится преодолевать серьезные трудности, чтобы получить начальную позицию. Мне же повезло получить офер, поучаствовав в соревновании и миновав изнурительные интервью и муки сомнений в собственной компетенции. Надеюсь, мой рассказ будет полезен и обратит внимание новичков на хакатоны и конференции как на отличные инструменты для активного поиска работы.
Вступление — прошлая жизнь и первые шаги в Data Science
По прошлой профессии я финансист, точнее, инвестиционный аналитик. Но классические алгоритмы машинного обучения широко применять в отборе акций мне не приходилось, хотя периодически строил модели линейной регрессии. Совсем не умея программировать, я относительно спокойно жил и работал, но где-то глубоко сидела мысль о том, что упускаю что-то интересное и важное. Я всегда трепетно относился к любым большим массивам данным, слышал, что data scientist — это профессия будущего. В общем, всячески пытался посматривать в сторону мира продвинутого анализа данных, но приверженность инвестиционному делу, занимавшая рабочее и существенную часть свободного времени, не давали основательно развиться в этом направлении.
В период начала пандемии у меня освободилось время за счет отсутствия поездок до офиса, которое удалось использовать для изучения основ языка Python. Постигать азы начал с прочтения первого тома Лутца «Изучаем Python». Летом 2020 я попрощался с работой, чтобы перезарядить батарейки и уйти в перестройку. Выбрал онлайн курс по Data Science и начал учиться.
Для себя я сформулировал, что хочу работать в крупной компании, чтобы быть частью большого сообщества — после учебы поставил себе цель найти подходящую позицию в Сбере. Я отслеживал информацию о конференциях и мероприятиях, в которых компания участвует. Благодаря странице https://ict2go.ru/companies/19/, я узнал, что Сбер участвует в конференции ScoringDay Весна 2021 и к этой конференции приурочен хакатон на площадке dsbattle.com под названием LGD Prediction. Призеры соревнования (топ-3) получают бесплатный билет на конференцию и возможность присоединиться к команде блока «Риски». Ну что ж, вызов принят!
Тяжело в учении, легко в бою!
0. Дрожащими руками, терзаемый сомнениями «смогу ли я?», открыл ссылку с baseline-решением на колабе. Посмотрел. Смогу. Визуальное знакомство с данными показало, что в целом такие задачки решать я умею. Обычные табличные данные, задача регрессии, призовем CatBoost. Отмечу, что на тот момент опыта участия в соревнованиях, кроме как в Титанике на Kaggle, у меня не было.
Ниже разберу основные шаги решения, которые позволили занять заветную вторую строчку и отправиться в Москву на конференцию. Также прикладываю ссылку на github и colab.
Целью задания было построить модель машинного обучения, предсказывающую LGD (Loss Given Default), другими словами, ту долю от выданного кредита, которую банк потеряет в случае дефолта заемщика. Для оценки качества модели использовалась метрика MAE — mean absolute error, средний модуль отклонений.
В распоряжении участников была обучающая выборка с 1400 объектами и тестовая — с 691, где каждый объект — это характеристики предприятия, которому был выдан кредит, и впоследствии это предприятие объявило о дефолте. Организаторы предупредили, что данные синтетические, поскольку реальные цифры представляют коммерческую тайну. В тестовой выборке не было столбца с целевым признаком.
1. После знакомства с датасетом я разбил 35 признаков для обучения на 2 группы: первая группа — 24 признака — это финансовые показатели (выручка, чистая прибыль, совокупные активы и т.п.), вторая группа — 11 признаков — различные прочие характеристики предприятия (срок ведения бизнеса, величина уставного капитала, объект в залоге).
Далее важно было взглянуть на распределение целевого признака — LGD — чтобы понять, с чем мы вообще имеем дело.
Распределение целевого признака имеет U-образную форму, то есть, наиболее вероятные сценарии развития событий для банка — что он либо вернет всю сумму, либо не получит ничего.
На этапе предобработки данных важно проверить данные на пропуски. В данном случае это был ключевой момент, так как в обучающей выборке только 38% объектов имели значения всех признаков, а у 60% вообще отсутствовали данные из группы признаков финансовых показателей, только прочие характеристики. Для тестовой выборки картина была схожей.
Кроме того, я проверял данные на дубликаты по строкам (их не было) и по столбцам (были).
2. Изначально, решая данный кейс, я пошел по длинному пути. Видя, что есть очень много признаков, я сразу понял, что какие-то из них лишние. Сгенерировав новые и глядя на коэффициенты корреляции и значимость, я постарался отбросить ненужные. Это принесло свои плоды и позволило мне держаться с приличным отрывом на первой строчке публичного лидерборда почти неделю.
Однако затем участник с ником art совершил мощный рывок и опередил меня на одну десятитысячную! Сначала я немного расстроился, поскольку я уже видел себя победителем соревнования и думал, что дело сделано. Но собравшись с мыслями и силами, я решил переработать проект и пойти по другому пути — не отбрасывать ненужное, а брать из признаков только самое необходимое. Поэтому все дальнейшие шаги относятся уже к конечному варианту решения.
Помог опыт участия в Титанике на Kaggle — создание хороших категориальных признаков помогло мне улучшить результат, поэтому я решил, что этот трюк пройдет и здесь.
Как уже можно было догадаться, наиболее очевидным вариантом разделения на 2 категории стало «наличие/отсутствие финансовой отчетности». Разбив объекты, я составил сводную таблицу, чтобы убедиться в существенном различии целевого признака по группам.
Заметно, что средний и медианный LGD у компаний с финансовыми данными существенно ниже, чем у оставшихся компаний.
Далее я решил перейти к еще одному потенциально плодовитому на улучшение результата столбцу — это «объект в залоге». Данный признак содержал относительно неоднородные данные, там можно было увидеть «квартира», «Дом жилой», «жилой дом», «Скотомогильник...», «автомобиль легковой» и «Легковой автомобиль». Здесь на помощь пришел учебный опыт — в первом моем проекте было задание выделить группы залога. Визуальный анализ значений позволял выделить три категории — жилое здание, нежилое здание, автомобиль или поручительство. Поиском подстроки в строке эти категории я и выделил. Автомобиль и поручительство пришлось объединить в одну категорию, поскольку статистика в этих группах отличалась не сильно. Сводная таблица показала следующее:
Все пропуски в финансовых данных я заполнил нулями.
Затем обратился к исследованию признаков «выручка» и «величина уставного капитала». По обоим столбцам я попытался выделить крупные компании в отдельную категорию. Исследовав медиану и средние при различных вариантах, остановился на границе в 50 млн руб. для выручки (больше — категория «corporation») и 100 тыс. руб. для уставного капитала (больше — категория «big»).
Из сводных таблиц выше видно, что у выделенных категорий LGD существенно различаются.
Далее я решил построить pairplot для признаков, которые есть у всех объектов — это «срок ведения бизнеса», «срок с момента регистрации ОГРН», сгруппировав объекты по категории залога.
Этот график позволил сделать следующие выводы:
«срок ведения бизнеса» достаточно тесно коррелирует с целевым признаком;
«срок ведения бизнеса» и «срок с момента регистрации ОГРН» до определенного момента имеют тесную связь, но значение второго ограничено сверху (поскольку по физическому смыслу они выражают примерно одно и то же — то, сколько компания существует, было принято решение остановиться на менее зашумленном признаке «срок ведения бизнеса»);
также любопытным инсайтом было то, что заемщики с залогом «жилое здание» по истечении определенного срока почти всегда переходили в категорию безопасных для банка – их LGD падал до 0 (второй график в первом ряду). Продемонстрируем его отдельно.
Здесь видно, что примерно после значения на уровне 70 «срока ведения бизнеса» LGD у кредиторов, отдавших в залог жилое здание, падал до нуля. Было только 4 исключения. Я решил ими пренебречь и выделить такую группу в отдельную категорию — «безопасный заемщик».
Получилось 100 таких компаний в обучающей выборке.
3. Потом я решил посоздавать количественные признаки на основе данных финансовой отчетности. Но поскольку таких объектов было меньшинство и сами финансовые данные были зашумлены (совокупные активы не были равны совокупным обязательствам и капиталу, например), результативность таких действий была низкой. Однако мне удалось выделить два признака, повысивших качество модели.
В этом мне помог опыт финансового анализа предприятий, я решил, что нужно рассчитать метрики, характеризующие уровень долговой нагрузки. Это было отношение общего долга к собственному капиталу (debt_equity) и отношение операционной прибыли к общему долгу (debt_op_profit).
Так моя обучающая выборка содержала всего 9 признаков: 4 количественных и 5 категориальных. Я решил использовать признак «выручка» (ar_revenue), так как он в значительной степени характеризует величину компании и является определяющим для получения денежных потоков.
4. Затем я начал обучать модели. Перед градиентными алгоритмами я пробовал и случайный лес, но его качество было ощутимо хуже. CatBoost показал себя лучше других, поэтому тюнил дальше его. Изначально обучал его «из коробки» со стратегией кросс-валидации на 9 разбиениях.
Среднее качество модели, рассчитанное таким образом, составило 0.086. Затем я обучил модель на всей обучающей выборке и получил качество 0.066.
Ниже график ошибок «фактический LGD — предсказание» для обучающей выборки.
Заметно, что самые серьезные ошибки возникали тогда, когда модель выдавала LGD = 1, когда это не было нужно, и не предсказывала 0, когда это было нужно.
Затем я сделал предсказания для тестовой выборки, и система показала, что их качество около 0.087: налицо было переобучение, но поиграв с количеством итераций в CatBoost и регуляризацией, я добился лишь небольшого улучшения — 0.086. Так или иначе, оценка качества модели, сделанной по методу «берем только необходимое», оказалась выше, чем модель «отбрасываем ненужное».
Далее посмотрим на значимость признаков итоговой обученной модели.
Наиболее значимым является «срок ведения бизнеса», который, как мы помним, тесно коррелировал с lgd. Второе и третье места заняли созданные категории — наличия отчетности и вида залога. Также сам параметр выручки (ar_revenue) оказался важен. Прочие созданные мной признаки были существенно менее важны, но без них качество на открытой части тестовой выборки было ниже.
Тут надо отметить, что, являясь новичком в соревнованиях, я только в процессе решения понял, что имеют в виду организаторы, когда говорят, что итоговый результат будет оцениваться по приватной части выборки, а размер ее неизвестен. Поэтому напишу важное наблюдение для таких же новичков: во многих соревнованиях конечный результат определяется по закрытой части выборки! Участник делает предсказания для всей тестовой выборки, но в открытом лидерборде его оценка рассчитывается только по какой-то доле от нее. Очевидно, делается это для того, чтобы человек не сделал миллион вариантов предсказаний и не получил простым перебором идеальный результат.
Качество 0.086 на тесте снова позволило выйти на промежуточное первое место. Ребята с третьего места и ниже существенно не улучшали свои результаты. Но мой основной соперник выдал очередной мощный рывок и обогнал меня уже на две тысячных. Уже исчерпав идеи улучшения модели и в целом чувствуя небольшую усталость от решения кейса (в сумме потратил около семи полноценных рабочих дней), я решил ждать завершения соревнования. Подумал, что победителем станет тот, кто меньше переобучился.
После открытия итогового лидерборда оценки ожидаемо снизились, а статус-кво сохранился — я остался на второй строчке. Отлично, серебро — тоже замечательный результат!
Большой итог
Будучи наслышанным о силе нетворкинга и важности общения с людьми в относительно неформальной обстановке, перед самим соревнованием я сформулировал цель — обязательно поучаствовать в конференции. Очень хотелось окунуться в атмосферу DS-сообщества и прочувствовать то, чем живут профессионалы данной отрасли, а также, если повезет, пообщаться с представителями компаний на предмет карьерных возможностей.
После всех докладов на конференции и награждения (где мне также вручили приз за соответствие модели регуляторным требованиям), мне удалось приятно пообщаться с победителем Артемом и руководителем направления в VS Robotics Александром. Выяснилось, что в компанию, по счастливому для меня стечению обстоятельств, нужны люди! После вопросов о том, знакомы ли мне основные понятия из области обработки естественного языка и вообще интересно ли мне это, мы обменялись контактами, и я отправил свое резюме и портфолио на рассмотрение. Спустя некоторое время мне перезвонили, сделали предложение, и я присоединился к команде VS Robotics!
В качестве итога хотел бы поделиться некоторыми мыслями и выводами, которые я для себя сделал.
Считаю, что мне во многом повезло с соревнованием — в частности, там было мало участников — только у 45 человек результат оказался выше baseline. Правда, наверное, главное все-таки не количество, а качество.
Повезло так же и в том, что соревнование соприкасалось с доменной областью, которая была мне знакома. Знание небольших тонкостей финансового анализа позволило улучшить качество модели. Поэтому всем начинающим свой путь data scientist’ам, которые меняют профессию, рекомендовал бы смело проявлять свои сильные стороны, заключающиеся в хорошем знании какой-либо области, и искать близкие им по духу соревнования и проекты.
В целом хочется всем порекомендовать участвовать в соревнованиях! Основной плюс хакатонов — ориентация на результат, который легко измерить. И это заставляет тебя мобилизовать все знания и опыт и искать возможности улучшения модели с разных сторон — предобработки данных, инжиниринга признаков, тюнинга параметров моделей.
Лучше мало хороших признаков, чем много плохих.
Если датасет маленький — кросс-валидация важна, нужно обращать внимание на качество модели, оцененное таким образом, а не стремится подогнать решение под открытую часть тестовой выборки.
Во время и после участия у меня сохранилось чувство сопричастности к чему-то объединяющему, и всех участников я рассматривал не как конкурентов, а как товарищей, у которых можно чему-то научиться и чем-то интересным поделиться с ними.
Спасибо, что дочитали до конца! Буду рад выслушать конструктивную критику решения и ответить на вопросы!