Главная » Хабрахабр » Как правильно «фармить» Kaggle

Как правильно «фармить» Kaggle

farming) — долгое и занудное повторение определенных игровых действий с определенной целью (получение опыта, добыча ресурсов и др.). image
*фарм — (от англ.

И, как обычно, после окончания любого курса у выпускников возникает вопрос — а где теперь получить практический опыт, чтобы закрепить пока еще сырые теоретические знания. Недавно (1 октября) стартовала новая сессия прекрасного курса по DS/ML (очень рекомендую в качестве начального курса всем, кто хочет, как это теперь называется, "войти" в DS). Kaggle — это да, но с чего начать и как наиболее эффективно использовать эту платформу для прокачки практических навыков? Если вы зададите этот вопрос на любом профильном форуме — ответ, скорее всего, будет один — иди решай Kaggle. В данной статье автор постарается на своем опыте дать ответы на эти вопросы, а также описать расположение основных грабель на поле соревновательного DS, чтобы ускорить процесс прокачки и получать от этого фан.

Несколько слов про курс от его создателей:

yorko и компания (~ 60 чел.) демонстрируют, что классные навыки можно получить и вне стен университета и даже абсолютно бесплатно. Курс mlcourse.ai — одна из масштабных активностей сообщества OpenDataScience. С одной стороны, изложение основных концепций происходит не без математики, с другой стороны — куча домашних заданий, соревнования Kaggle Inclass и проекты дадут, при определенном вложении сил с вашей стороны, отличные навыки машинного обучения. Основная идея курса — оптимальное сочетание теории и практики. Также курс отличается тем, что он проходит в действительно живом сообществе. Нельзя не отметить соревновательную природу курса — ведется общий рейтинг студентов, что сильно мотивирует.

Оба очень интересные, в них неплохо работает построение признаков. В рамках курса проходят два соревнования Kaggle Inclass. Второе — предсказание популярности статьи на Медиуме. Первое — идентификация пользователя по последовательности посещенных сайтов. Главная польза — от двух домашних заданий, где надо проявить смекалку и побить бейзлайны в этих соревнованиях.

Отдав должное курсу и его создателям, продолжаем нашу историю...

Нет, как решать задачу — понятно, какие алгоритмы применять — тоже понятно, но вот код пишется очень тяжело, с поминутным заходом на хелп sklearn / pandas, и т.д. Вспоминаю себя полтора года назад, пройден курс (еще первая версия) от Andrew Ng, закончена специализация от МФТИ, прочитана гора книг — теоретических знаний полна головушка, но при попытке решить любую базовую боевую задачу — возникает ступор. Почему так — нет наработанных пайплайнов и ощущения кода "на кончиках пальцев".

Сразу с боевого соревнования начинать было страшно, и первой ласточкой стало Getting started соревнование "House Prices: Advanced Regression Techniques", на котором и оформился тот подход к эффективной прокачке, который описан в этой статье. Так дело не пойдет, подумал автор, и ушел на Kaggle.

По крайней мере, следуя им, автору удалось взять плашку Kaggle Competition Master за полгода и три соревнования в соло режиме и, на момент написания данной статьи, входить в top-200 мирового рейтинга Kaggle. В том, что будет описано дальше, нет никакого know-how, все техники, методы и приемы — очевидны и предсказуемы, но это не умаляет их эффективности. Кстати, это отвечает на вопрос, почему автор вообще позволил себе смелость написать статью такого рода.

Участникам дается от 3 до 5 попыток (по воле организаторов) в день на "сабмит" (посылку своего варианта решения). image
Kaggle — одна из наиболее известных платформ для проведения соревнований по Data Science, В каждом соревновании организаторы выкладывают описание задачи, данные для решения этой задачи, метрику, по которой будет оцениваться решение — и устанавливают сроки и призы.

Для тренировочной части известно значение целевой переменной (target), для тестовой — нет. Данные делятся на тренировочную выборку (train) и тестовую (test). Задача участников создать модель, которая, будучи обучена на тренировочной части данных выдаст максимальный результат на тестовой.

Каждый участник делает предсказания для тестовой выборки — и отсылает результат на Kaggle, далее робот (которому известна целевая переменная для теста) оценивает присланный результат, который отображается на лидерборде.

В течение соревнования присланное решение оценивается, согласно установленной организаторами метрике, на публичной части данных и выкладывается на лидерборд (т.н. Но не все так просто — тестовые данные, в свою очередь, делятся в определенной пропорции на публичную (public) и приватную (private) часть. Окончательное решение (обычно два — по выбору участника) оценивается на приватной части тестовых данных — и результат попадает на приватный лидерборд, который доступен только после окончания соревнования и по которому, собственно, и оцениваются финальные результаты, раздаются призы, плюшки, и медальки. паблик лидерборд) — по которому участники могут оценивать качество своих моделей.

Если, в случае сферического коня в вакууме, приватная часть данных совпадает по распределению и статистикам с публичной — все прекрасно, если же нет — то модель, которая показала себя хорошо на паблике может не сработать на приватной части, то есть заоверфититься (переобучиться). Таким образом, в течение соревнования участникам доступна только информация как их модель повела себя (какой результат — или скор она показала) на публичной части тестовых данных. И вот тут-то возникает то, что на жаргоне называется "полетом", когда люди с 10 места на паблике улетают вниз на 1000-2000 мест на приватной части из-за того, что выбранная ими модель переобучилась и не смогла выдать необходимую точность на новых данных.

image

Для этого, в первую очередь, необходимо построить правильную схему валидации, то, чему учат на первых уроках практически на всех курсах по DS. Как этого избежать? если ваша модель не может выдать правильный прогноз на данных, которых она никогда не видела — то какую бы навороченную технику вы бы не применяли, сколь сложные нейронные сети не строили — в продакшен такую модель выпускать нельзя, т.к. Т.к. ее результаты ничего не стоят.

Для каждого соревнования на Kaggle создается своя отдельная страничка на которой есть раздел с данными, с описанием метрики — и самое для нас интересное — форум и кернелы.

А вот кернелы — это уже интереснее. Форум он и на Kaggle форум, народ пишет, обсуждает и делится идеями. Два года назад Kaggle был приобретен компанией Google, так что неудивительно, что "под капотом" данный функционал использует Google Cloud Engine. По сути, это возможность запускать свой код, который имеет непосредственный доступ к данным соревнования в облаке Kaggle (аналог амазоновского AWS, гугловского GCE, и т.д.) На каждый кернел выделяются ограниченные ресурсы, поэтому если данных не очень много, то работать с ними вы можете прямо из браузера на сайте Kaggle — пишете код, запускаете на выполнение, сабмитите результат.

Очень интересный формат, нивелирующий разницу в железе у участников и заставляющий включить мозг на предмет оптимизации кода и подходов, так как, естественно, в кернелах было жесткое ограничение по ресурсам, на тот момент — 4 cores / 16 GB RAM / 60 minutes run-time / 1 GB scratch and output disk space. Более того было несколько соревнований (недавнее — Mercari), где с данными можно было работать вообще только через кернелы. Немного не хватило до золота, финишировал соло 23-м, но опыта и удовольствия получил изрядно… Работая над этим соревнованием, автор узнал больше об оптимизации нейронных сетей, чем из любого теоретического курса.

Вообще было много интересных моментов, Konstantin Lopuhin (kostia), взявший первое место вместе с Paweł Jankiewicz, потом выложил то, что в чатике назвали "эталонное унижение в 75 строк" — кернел в 75 строк кода, выдающий результат в золотую зону лидерборда. Пользуясь случаем еще раз хочу сказать Спасибо коллегам из ods.aiArthur Stsepanenka (arthur), Konstantin Lopuhin (kostia), Sergei Fironov (sergeif) за советы и поддержку в этом соревновании. Это, конечно, надо видеть 🙂

Обычно в каждом соревновании через пару недель появляется один-два прекрасных EDA (exploratory data analysis) кернела, с подробнейшим описанием датасета, статистик, характеристик и т.д. Ладно, отвлеклись, так вот — народ пишет код и выкладывает кернелы с решениями, интересными идеями и прочим. И парочка бейзлайнов (базовых решений), которые, конечно, показывают не самый лучший результат на лидерборде, но их можно использовать в качестве отправной точки для создания своего решения.

image

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

Очень часто, в статьях, разговорах и прочем общении звучит мысль, что это все туфта, к реальным задачам опыт в соревнованиях не имеет никакого отношения, и народ там занимается тем, что тюнит 5-й знак после запятой, что есть маразм и оторвано от реальности. Небольшое отступление вообще на тему соревновательного DS. Давайте разберемся в этом вопросе немного подробнее:

То есть (тут отсылка к CRISP-DM) для решения поставленной задачи необходимо: Как практикующие DS-специалисты, в отличие от академии и науки, мы, в нашей работе, должны и будем решать задачи бизнеса.

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

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

У нас есть описанная бизнес-цель, выбрана аппроксимирующая метрика, собраны данные — и наша задача построить из всего этого лего работающий пайплайн. В любом соревновании большую часть работы за нас выполнили организаторы. И вот тут-то и прокачиваются навыки — как работать с пропусками, как готовить данные для нейронных сетей и деревьев (и почему нейронные сети требуют особого подхода), как грамотно построить валидацию, как не переобучиться, как подобрать гиперпараметры, как …… да еще десятка два "как", грамотное исполнение которых и отличает хорошего спеца от проходных людей в нашей профессии.

image

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

  • Фарм медалей и плашек
  • Фарм репутации в Kaggle-коммьюнити

Главное, что надо помнить — эти три цели абсолютно разные, для их достижения требуются разные подходы, и не надо их смешивать особенно на начальном этапе!

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

Пройдемся кратко по целям снизу вверх:

  • Репутация — прокачивается написанием хороших постов (и комментариев) на форуме и созданием полезных кернелов. Например EDA кернелы (см. выше), посты с описанием нестандартных техник и т.д.
  • Медали — очень неоднозначный и хейтовый топик, но да ладно. Прокачивается блендингом паблик кернелов (*), участием в команде с перекосом в опыте, ну и созданием своего топ-пайплайна.
  • Опыт — прокачивается разбором решений и работой над ошибками.

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

Рекомендую первой целью выбрать "опыт" и придерживаться его до момента, когда вы почувствуете, что готовы работать над двумя/тремя целями одновременно.

Есть еще два момента, которые стоит упомянуть (Vladimir Iglovikov (ternaus) — спасибо за напоминание).

Как бы ни были нивелированы сейчас плашки Kaggle, но для понимающих людей строчка в резюме "Kaggle Competition Master", да и другие ачивки все-таки чего-то да стоят. Первое — это конвертация усилий, вложенных в Kaggle в новое, более интересное и/или высокооплачиваемое место работы.

В качестве иллюстрации этого момента можно привести два интервью с нашими коллегами Сергеем Мушинским (@cepera_ang) и Александром Буслаевым (@albu).

А также мнение Valeriy Babushkin (venheads):

Валерий Бабушкин — Head of Data Science в X5 Retail Group (текущая численность подразделения 30 человек + 20 вакансий с 2019 года)

Руководитель группы аналитики Яндекс Советника

Конечно в связи с последними событиями в виде команд по 30 человек и неприкрытых паровозов требуется чуть более тщательное изучение профиля чем раньше, но это все равно дело нескольких минут. Kaggle Competition Master является отличной прокси метрикой для оценки будущего участника команды. Если лычкой мастера еще нельзя похвастаться, то сам факт участия это тоже плюс, как минимум кандидат знает про существования Кагла и не поленился и потратил время на его освоение. Человек, добившийся звания мастера, с большой долей вероятности умеет писать как минимум среднего качества код, сносно разбирается в машинном обучении, умеет чистить данные и строить стабильные решения. Единственная чего следует опасаться и с чем я сталкивался, что некоторые люди думают что работа DS это примерно как Кагл, что в корне не верно. А если было запущено что-то кроме публичного кернела и полученное решение превзошло его результаты (что довольно легко проверить), то это повод для детальной беседы по поводу технических деталей, что гораздо лучше и интереснее, чем классические вопросы по теории, ответы на которые дают меньше понимания как человек будет в будущем справляться с работой. Еще многие думают что DS = ML, что тоже является ошибкой

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

Для примера список работ наших коллег по итогам нескольких соревнований

Авторы (в алфавитном порядке):

Andrei O., Ilya, albu, aleksart, alex.radionov, almln, alxndrkalinin, cepera_ang, dautovri, davydov, fartuk, golovanov, ikibardin, kes, mpavlov, mvakhrushev, n01z3, rakhlin, rauf, resolut, scitator, selim_sef, shvetsiya, snikolenko, ternaus, twoleggedeye, versus, vicident, zfturbo

image

Забить!

Практически в каждом соревновании ближе к его окончанию на паблик выкладывается кернел с решением, которое сдвигает весь лидерборд вверх, ну а вас, с вашим решением, соответственно вниз. Поясню. Что за дела, верните все взад. И каждый раз на форуме начинается БОЛЬ! Как же так, вот у меня было решение на серебро, а теперь я даже на бронзу не тяну.

В том, на каком месте лидерборда вы находитесь — зависит только от вас. Помните — Kaggle — соревновательный DS. Не от того парня, что выложил кернел, не от того сошлись звезды или нет, а только от того сколько усилий вы приложили к решению и все ли возможные пути к его улучшению вы использовали.

Если паблик кернел сбивает вас с вашего места на лидерборде — это не ваше место.

Серьезно, паблик кернел с лучшим решением, чем ваше означает, что вы чего-то упустили в своих пайплайнах. Вместо того, чтобы изливать боль от несправедливости мира — поблагодарите этого парня. Помните, чтобы вернуться на свое место вам надо просто быть чуть-чуть лучше чем этот паблик. Найдите что именно, улучшите ваш пайплайн — и обойдите всю ту толпу хомячков с одинаковым скором.

Ничего, надо просто собраться, понять где и что ты упустил — переделать свое решение — и вернуться на место. Как меня этот момент расстраивал в первых соревнованиях, аж руки опускались, вот ты в серебре — и вот ты в … низу лидерборда.

Чем опытнее вы станете — тем меньше на вас будут оказывать влияние выложенные кернелы и звезды. Тем более, что этот момент будет присутствовать только на ранней стадии вашего соревновательного процесса. То есть весь полезный сигнал, который вытаскивал из данных этот кернел был уже вытащен нашими моделями. В одном из последних соревнований (Talking Data, в котором наша команда заняла 8-е место) тоже выложили такой кернел, но он удостоился всего одной строчки в нашем командном чате от Павла Плескова (ppleskov): "Парни, я заблендил его с нашим решением, стало только хуже — выбрасываем".

И еще насчет медалей — помните:

"пояс без техники нужен только для поддержания штанов"(С)

image

6 на jupyter notebook под ubuntu. Тут моя рекомендация — python 3. Python уже давно стал стандартом де-факто в DS, учитывая наличие огромного количества библиотек и коммьюнити, jupyter, особенно с наличием jupyter_contrib_nbextensions очень удобен для быстрого прототипирования, анализа и обработки данных, ubuntu — удобна сама по себе, плюс часть обработки данных иногда проще делать в bash 🙂

После установки jupyter_contrib_nbextensions сразу рекомендую включить:

  • Collapsible headings (очень помогает в организации блоков кода)
  • Code folding (то же самое)
  • Split cells (редко, но полезен если надо что-то дебажить в параллель)

И ваша жизнь станет намного проще и приятней.

Поверьте — переписывать его вы будете не раз и не два и даже не пять. Как только ваши пайплайны станут более-менее стабильными, код рекомендую сразу выносить в отдельные модули. Но — это нормально.

(адептом такого варианта является, например, Vladimir Iglovikov (ternaus)) Есть прямо противоположный подход, когда участники стараются использовать jupyter notebook как можно реже и только в случае необходимости, предпочитая, сразу писать пайплайны скриптами.

И есть те, кто пытается совместить jupyter с какой-либо IDE, например pycharm.

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

Но при любом варианте возьмите за правило

сохранять код для каждого сделанного сабмита/OOF (см.ниже).

Незаменима для дальнейшей сборки нескольких решений в ансамбль. (*) OOF — out of folds, техника получения предсказаний модели для тренировочной части датасета используя кросс-валидацию. Преподается опять же на курсах или легко гуглится.

Ну тут есть как минимум три варианта: Как?

  • Для каждого соревнования создается отдельный репозиторий на гитхабе или битбакете и код для каждого сабмита коммитится в репозиторий с комментарием, в котором содержится полученный скор, параметры модели, и т.д.
  • Код каждого сабмита собирается в отдельный архив, с именем файла, в котором указана вся метаинформация сабмита (тот же скор, параметры, и т.д.)
  • Используется система контроля версий заточенная именно под DS/ML. Например https://dvc.org.

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

image

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

image

Примечание

Картинки, которых сейчас очень много на Kaggle — это отдельная тема с отдельными фреймворками. Все дальнейшее описание будет основано на работе с табличными и текстовыми данными. На базовом уровне хорошо уметь их обрабатывать, хотя бы для того, чтобы прогнать через что-то типа ResNet/VGG и вытащить фичи, но более глубокая и тонкая работа с ними — это отдельная и очень обширная тема, не рассматриваемая в рамках данной статьи.

Единственная попытка приобщиться к прекрасному была в соревновании Camera Identification, в котором, кстати, наши команды с тегом [ods.ai] взорвали весь лидерборд до такой степени, что админам Kaggle пришлось зайти к нам в слак в гости, убедиться, что все в рамках правил — и успокоить коммьюнити. Автор честно признается, что не очень умеет в картинки. Так вот, в этом соревновании мне досталось почетное серебро с 46-м местом, а когда прочитал описание топовых решений от наших коллег, то понял, что забраться выше и не светит — там у них применяется реально черная магия с аугментацией, добросом 300Гб данных, жертвоприношениями и прочим.

В общем если хотите начинать с картинок — то вам нужны другие фреймворки и другие руководства.

Основная цель

Ваша задача написать пайплайны (оформленные в виде jupyter notebooks + модули) для следующих задач:

  • EDA (exploratory data analysis). Тут надо сделать замечание — на Kaggle есть специально обученные люди :), которые в каждом соревновании пилят сногсшибательные EDA кернелы. Переплюнуть их у вас вряд-ли получится, но понимать, как можно смотреть на данные все-равно придется, т.к. В боевых задачах этим специально обученным человеком будете вы. Поэтому изучаем подходы, расширяем наши библиотеки.
  • Data Cleaning — все, что касается очистки данных. Выбросы, пропуски, и т.д.
  • Data preparation — все, что касается подготовки данных для модели. Несколько блоков:
    • Общий
    • Для регрессий/нейронных сетей
    • Для деревьев
    • Специальный (временные ряды, картинки, FM/FFM)
    • Текст (Vectorizers, TF-IDF, Embeddings)
  • Models
    • Linear models
    • Tree models
    • Neural Networks
    • Exotic (FM/FFM)
  • Feature selection
  • Hyperparameters search
  • Ensemble

Так вам потом будет проще. В кернелах обычно все эти задачи собраны в единый код, что и понятно, но очень рекомендую для каждой из этих подзадач завести отдельный ноутбук и отдельный модуль (набор модулей).

Предупреждая возможный холивар — структура данного фреймворка не истина в последней инстанции, есть много других способов структурировать свои пайплайны- это всего лишь один из них.

Данные передаются между модулями либо в виде CSV, либо feather/pickle/hdf — что вам удобнее и к чему вы привыкли или лежит душа.

На самом деле много еще зависит и от количества данных, в TalkingData, например, пришлось идти через memmap, чтобы обойти нехватку памяти при создании датасета для lgb.

Повторюсь — шаблонов нет, кто к чему привык, с тем и работайте. В остальных случаях — основные данные хранятся в hdf/feather, что-то маленькое (типа набора выбранных атрибутов) — в CSV.

Начальный этап

image

Читаем паблик кернелы, копируем куски кода, процедуры, подходы, и т.д. Идем в любое Getting started соревнование (как уже упоминалось, автор начинал с House Prices: Advanced Regression Techniques), и начинаем создавать наши ноутбуки. Прогоняем данные через пайплайн, сабмитим — смотрим на результат, улучшаем и так по кругу. и т.п.

Задача на данном этапе — собрать эффективно работающий пайплайн полного цикла — от загрузки и очистки данных до финального сабмита.

Примерный список того, что должно быть уже готовым и работающим на 100% перед переходом к следующему этапу:

  • EDA. (статистики по датасету, боксплоты, разброс категорий, ...)
  • Data Cleaning. (пропуски через fillna, чистка категорий, объединение категорий)
  • Data preparation
    • Общий (обработка категорий — label/ohe/frequency, проекция числовых на категории, трансформация числовых, бининг)
    • Для регрессий (различное масштабирование)
  • Models
    • Linear models (различные регрессии — ridge/logistic)
    • Tree models (lgb)
  • Feature selection
    • grid/random search
  • Ensemble
    • Regression / lgb

Идем в бой

image

Выбираем любое понравившееся соревнование и … начинаем 🙂

  • Не будет нормальной схемы — будете летать на лидерборде, как в соревнованиях от Mercedes, Santander и прочих. Смотрим на данные, читаем форумы и строим устойчивую схему валидации. Посмотрите на лидерборд Mercedes, например (зеленые стрелочки и цифры означают на сколько позиций народ поднялся в лидерборде по сравнению с пабликом, красные — на сколько улетел вниз):

    Также рекомендую почитать статью и выступление danila_savenkov:

    Также данная тема хорошо освещена в курсе How to Win a Data Science Competition: Learn from Top Kagglers"

Пока нет рабочей валидационной схемы — дальше не идем!!!

  • Прогоняем данные через наш сформированный пайплайн и сабмитим результат
  • Хватаемся за голову, психуем, успокаиваемся… и продолжаем…
  • Читаем все кернелы на предмет использованных техник и подходов
  • Читаем все обсуждения на форуме
  • Переделываем/дополняем пайплайны новыми техниками
  • Переходим к п. 1

Наполнить наши пайплайны рабочими подходами и методами, заполнить наши модули работающим кодом. Помним — наша цель на данном этапе — получить опыт! Мы пришли сюда не на пять минут, медали и плашки никуда не уйдут. Не заморачиваемся на медалях — вернее как, здорово, если получится сразу занять свое место на лидерборде, но если нет — не паримся.

Вот соревнование закончено, вы где-то там, казалось бы все — хватаемся за следующее?

НЕТ!

Что вы делаете дальше:

  • Ждете пять дней. Не читайте форум, забудьте про Kaggle на это время. Дайте мозгу отдохнуть и размылить взгляд.
  • Возвращаетесь к соревнованию. За эти пять дней по правилам хорошего тона все топы выложат описание своих решений — в постах на форуме, в виде кернелов, в виде гитхабовских репозиториев.

И тут начинается ваш персональный АД!

  • Вы берете несколько листов формата А4, на каждом пишете название модуля из вышеописанного фреймворка (EDA/ Preparation/ Model/ Ensemble/ Feature selection/ Hyperparameters search/ ...)
  • Последовательно читаете все решения, выписываете на соответствующие листочки новые для вас техники, методы, подходы.

И самое страшное:

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

И вот только после этого переходим к следующему соревнованию.

Да, можно и проще. Нет, я не охренел. Вам решать.

На данном этапе (на мой взгляд) лучше читать уже сформированные треды с обсуждениями решений, вопросы, которые у вас могут возникнуть — либо кто-то уже задаст, либо их лучше пока вообще не задавать, а искать ответ самим ) Почему ждать 5 дней, а не читать сразу, ведь на форуме можно позадавать вопросы?

Ну, еще раз — задача данного этапа наработать базу решений, методов и подходов. Зачем все это делать именно так? Чтобы в следующем соревновании вы не тратили время, а сразу сказали — ага, тут может зайти mean target encoding, и кстати, у меня и правильный код для этого через фолды в фолдах есть. Боевую рабочую базу. помнится тогда заходил ансамбль через scipy.optimize, а кстати у меня и код уже готов. Или о!

Как-то так...

Выходим на рабочий режим

image

С каждым разом замечаем, что записей на листках становится все меньше и меньше, а кода в модулях все больше и больше. В таком режиме решаем несколько соревнований. И добавляете в себе в копилку одно-два новых заклинания или подхода. Постепенно задача анализа сводится к тому, что вы просто читаете описание решения, говорите ага, ого, ах вот оно как!

База у вас уже готова, теперь ее просто надо правильно применять. После этого режим меняется на режим работы над ошибками. Шел достаточно хорошо, в подбрюшье золота, а на private улетел вниз на 1500 позиций. После каждого соревнования, читая описание решений, смотрите — что вы не сделали, что можно было сделать лучше, что вы упустили, ну или где вы конкретно лажанулись, как у меня случилось в Toxic. Обидно до слез… но успокоился, нашел ошибку, написал пост в слаке — и выучил урок.

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

Что примерно должно быть в пайплайнах к концу данного этапа:

  • Всевозможные варианты предобработки и создания числовых фичей — проекции, отношения,
  • Различные методы работы с категориями — Mean target encoding в правильном варианте, частоты, label / ohe,
  • Различные схемы ембеддингов над текстом (Glove, Word2Vec, Fasttext)
  • Различные схемы векторизации текста (Count, TF-IDF, Hash)
  • Несколько валидационных схем (N*M для стандартной кросс-валидации, time-based, by group)
  • Bayesian optimization / hyperopt / что-то еще для подбора гиперпараметров
  • Shuffle / Target permutation / Boruta / RFE — для отбора фич
  • Линейные модели — в едином стиле над одним набором данных
  • LGB/XGB/Catboost — в едином стиле над одним набором данных

Зато теперь можно в едином ключе одной строчкой запускать, например, LGB или XGB над одним обработанным набором данных. Автор сделал метаклассы отдельно для линейных и tree-based моделей, с единым внешним интерфейсом, чтобы нивелировать различия в API у разных моделей.

  • Несколько нейронных сетей на все случаи жизни (не берем пока картинки) — embeddings/CNN/RNN для текста, RNN для последовательностей, Feed-Forward для всего остального. Хорошо еще понимать и уметь автоенкодеры.
  • Ансамбль на базе lgb/regression/scipy — для задач регрессии и классификации
  • Хорошо еще уже уметь Genetic Algorithms, иногда они хорошо заходят

Подытожим

Это не хорошо и не плохо, это факт. Любой спорт, а соревновательный DS — это тоже спорт, это много-много пота и много-много работы. Участие в соревнованиях (если грамотно подойти к процессу) очень хорошо прокачивает технические скиллы, плюс более-менее качает спортивный дух, когда очень не хочется что-то делать, прямо ломает всего — но встаешь к ноутбуку, переделываешь модель, запускаешь на обсчет, чтобы таки выгрызть этот несчастный 5-й знак после запятой.

Так что решайте Kaggle — фармите опыт, медали и фан!

image

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

  • Весь код по фиче-инжинирингу, кроме mean target encoding, вынесен в отдельный модуль в виде функций. Пробовал собирать через объекты, получилось громоздко, да и в данном случае и не надо.
  • Все функции фиче-инжиниринга выполнены в едином стиле и имеют единую сигнатуру вызова и возврата:

def do_cat_dummy(data, attrs, prefix_sep='_ohe_', params=None): # do something return _data, new_attrs

На выходе получаем новый датасет с новыми атрибутами и список этих атрибутов. На вход передаем датасет, атрибуты для работы, префикс для новых атрибутов и дополнительные параметры. Далее это новый датасет сохраняется в отдельный pickle/feather.

Например для категорий делаем сразу три обработки — Label Encoding / OHE / Frequency, сохраняем в три отдельных feather, и далее на этапе моделирования просто играемся этими блоками, одним элегантным движением создавая различные датасеты для обучения. Что это дает — мы получаем возможность быстро собрать датасет для обучения из предсгенеренных кубиков.

pickle_list = [ 'attrs_base', 'cat67_ohe', # 'cat67_freq', ] short_prefix = 'base_ohe' _attrs, use_columns, data = load_attrs_from_pickle(pickle_list) cat_columns = []

Если надо собрать другой датасет — меняем pickle_list, перезагружаем, и работаем с новым датасетом.

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

def do_cat_le(data, attrs, params=None, prefix='le_'): def do_cat_dummy(data, attrs, prefix_sep='_ohe_', params=None): def do_cat_cnt(data, attrs, params=None, prefix='cnt_'): def do_cat_fact(data, attrs, params=None, prefix='bin_'): def do_cat_comb(data, attrs_op, params=None, prefix='cat_'): def do_proj_num_2cat(data, attrs_op, params=None, prefix='prj_'):

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

def do_iter_num(data, attrs_op, params=None, prefix='comb_'):

Плюс разные дополнительные специфические преобразователи.

и т.п. Для обработки текстовых данных используется отдельный модуль, включающий в себя различные методы препроцессинга, токенизации, лемматизирования/стемминга, перевода в частотную таблицу, ну и т.д. Все стандартно, используя sklearn, nltk и keras.

Спасибо François Chollet, что допилил таки keras, чтобы построение моделей seq-2-seq не походило на вудуистский ритуал вызова демонов. Временные ряды обрабатываются также отдельным модулем, с функциями преобразования исходного датасета как для обычных задач (регрессии/классификации), так и для sequence-to-sequence.

В том же модуле, кстати, находятся и функции обычного статистического анализа рядов — проверка на стационарность, STL-декомпозиция, и т.д… Очень помогает на начальном этапе анализа, чтобы "пощупать" ряд и посмотреть что он вообще такое.

  • Функции, которые нельзя применить сразу ко всему датасету, а нужно использовать внутри фолдов при кросс-валидации вынесены в отдельный модуль:

    • Mean target encoding
    • Upsampling / Downsampling

    Они передаются внутрь класса модели (про модели читай ниже) на этапе обучения.

_fpreproc = fpr_target_enc _fpreproc_params = fpr_target_enc_params _fpreproc_params.update(**)

  • Для моделирования создан метакласс, обобщающий понятие модель, с абстрактными методами: fit/predict/set_params/ и т.д. Для каждой конкретной библиотеки (LGB, XGB, Catboost, SKLearn, RGF, ...) создана реализация этого метакласса.

То есть для работы с LGB мы создаем модель

model_to_use = 'lgb' model = KudsonLGB(task='classification')

Для XGB:

model_to_use = 'xgb' metric_name= 'auc' task='classification' model = KudsonXGB(task=task, metric_name=metric_name)

И все функции далее оперируют с model.

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

    res = cv_make_oof(
    model, model_params, fit_params, dataset_params, XX_train[use_columns], yy_train, XX_Kaggle[use_columns], folds, scorer=scorer, metric_name=metric_name, fpreproc=_fpreproc, fpreproc_params=_fpreproc_params, model_seed=model_seed, silence=True
    )
    score = res['score']

  • Для feature selection — ничего интересного, стандартный RFE, и мои любимые shuffle permutation во всех возможных вариантах.

  • Этот блок живет в том же ноутбуке, что и моделирование. Для поиска гиперпараметров в основном используется Bayesian optimization, опять же в унифицированном виде для того, чтобы можно было запустить поиск для любой модели (через модуль кросс-валидации).

  • Для ансамблей сделано несколько функций, унифицировано для задач регрессии и классификации на базе Ridge/Logreg, LGB, Neural network и моего любимого scipy.optimize.

    Далее в модуле ансамбля из указанной директории загружаем пары предсказаний от всех моделей в два датафрейма — df_sub / df_oof. Небольшое пояснение — каждая модель из пайплайна выдает в качестве результата два файла: sub_xxx и oof_xxx, представляющих собой предсказание для теста и OOF предсказание для трейна. Ну а дальше уже смотрим на корреляции, отбираем лучшие, потом строим модели 2-го уровня над df_oof и применяем к df_sub.

    В простейших случаях прекрасно работают стандартные регрессии и scipy.optimize. Иногда для поиска лучшего поднабора моделей хорошо заходит поиск генетическими алгоритмами (автор использует эту библиотеку), иногда — метод от Caruana.

  • Опять же написаны универсальные функции для тренировки, инвариантные к типу сети. Нейронные сети живут в отдельном модуле, автор использует keras в функциональном стиле, да, не так гибко как pytorch, но пока хватает.

Данный пайплайн был в очередной раз протестирован в недавнем соревновании от Home Credit, внимательное и аккуратное применение всех блоков и модулей принесло 94-е место и серебро.

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

image

Почему? Тут не все так однозначно, решать Kaggle в команде или соло — во многом зависит от человека (и от команды), но мой совет для тех, кто только начинает — попробуйте начать соло. Попробую объяснить свою точку зрения:

  • Во-первых вы поймете свои силы, увидите слабые места и, в целом, сможете оценить свой потенциал как DS практика.
  • Во-вторых даже работая в команде (если только это не устоявшаяся команда с разделением ролей), от вас все-равно будут ждать готового законченного решения — то есть рабочие пайплайны у вас уже должны быть. ("Сабмит или не было") (С)
  • Ну и в третьих, оптимально, когда уровень игроков в команде примерно одинаков (и достаточно высок), тогда можно научиться чему-нибудь действительно высокоуровнево-полезному ) В слабых командах (тут нет ничего уничижительного, я про уровень подготовки и опыт на Kaggle) imho очень сложно чему-нибудь научиться, лучше грызть форум и кернелы. Да, можно фармить медальки, но см. Выше про цели и пояс для поддержания штанов )

image

Приведенные советы отражают опыт автора, не являются догмой, и могут (и должны) проверяться собственными экспериментами

  • Еще раз посмотрите на лидерборд Mercedes. Всегда начинайте с построения грамотной валидации — не будет ее, все остальные усилия улетят в топку.

    Автор реально доволен тем, что в этом соревновании построил устойчивую схему кросс-валидации (3x10 фолдов), которая сохранила скор и принесла законное 42-е место )

  • Если скор ваших моделей улучшается на валидации, но ухудшается на паблике — разумнее доверять валидации. Если построена грамотная валидация — всегда доверяйте результатам вашей валидации. Вы же не хотите заоверфитить вашу модель на один фолд? При анализе просто считайте тот кусок данных, на котором считается паблик лидерборд еще одним фолдом.

  • На этапе ансамбля никогда не знаешь что выстрелит. Если модель и схема позволяет — всегда делайте OOF предсказания и сохраняйте рядом с моделью.

  • Неважно на гитхаб, локально, куда угодно. Всегда сохраняйте рядом с результатом/OOF код для их получения. Боль. Два раза у меня получалось, что в ансамбле лучшая модель та, которая была сделана две недели назад "из коробки", и для которой не сохранилось кода.

  • Лучше выберите три любых и сделайте 3хN кросс-валидацию. Забейте на подбор "правильного" сида для кросс-валидации, сам грешил этим сначала. Результат будет стабильнее и проще.

  • В худшем случае — по параметрам, например одно глубокое дерево с жесткой регуляризацией, одно неглубокое. Не гонитесь за количеством моделей в ансамбле — лучше меньше, но разнообразнее — разнообразнее по моделям, по предобработке, по датасетам.

  • Для отбора фич используйте shuffle / boruta / RFE, помните, что feature importance в различных tree-based моделях — это метрика в попугаях на мешок опилок.

  • Личное мнение автора (может и не совпадать с мнением читателя) Bayesian optimization > random search > hyperopt для подбора гиперпараметров.

  • Выложенный на паблик рвущий лидерборд кернел лучше обрабатывать так:

    • Есть время — смотрим что там нового и встраиваем себе
    • Меньше времени — переделываем его на нашу валидацию, делаем OOF — и пристегиваем к ансамблю
    • Совсем нет времени — тупо блендим с нашим лучшим решением и смотрим скор.

  • Ну а если серьезно, то обычно все практикуют следующие подходы: Как выбирать два финальных сабмита — по интуиции, естественно.

    • Консервативный сабмит (на устойчивых моделях) / рискованный сабмит.
    • С лучшим скором на OОF / на паблик лидерборде

  • Используйте классификацию вместо регрессии, рассматривайте последовательности как картинку, и т.д. Помните — все есть цифра и возможности ее обработки зависят только от вашего воображения.

Ну и напоследок:

  • Вступайте в ods.ai 🙂 общайтесь и получайте фан от DS и от жизни! )

image

Общие

Kaggle.com/general/68205 — пост про курс на Kaggle http://ods.ai/ — для тех, кто хочет присоединиться к лучшему DS коммьюнити 🙂
https://mlcourse.ai/ — сайт курса ods.ai
https://www.

В целом еще очень рекомендую в том же режиме, что описан в статье, просмотреть цикл видео mltrainings — много интересных подходов и техник.

Видео

Курсы

Более подробно методы и подходы к решению задач на Kaggle можно узнать из второго курса специализации, "How to Win a Data Science Competition: Learn from Top Kagglers"

Внеклассное чтение:

image

В данной статье автор только слегка раскрыл тему прокачки практических скиллов используя соревновательные платформы. Тема Data Science в целом и соревновательный Data Science в частности, так же неисчерпаема, как и атом (С). Чем больше хорошего контента, тем всем нам будет лучше! Если стало интересно — подключайтесь, осматривайтесь, копите опыт — и пишите свои статьи.

Предвосхищая вопросы — нет, пайплайны и библиотеки автора пока не выложены в свободный доступ.

Огромная благодарность коллегам из ods.ai: Vladimir Iglovikov (ternaus), Yury Kashnitskiy (yorko), Valeriy Babushkin (venheads), Alexey Pronkin (pronkin_alexey), Dmitry Petrov (dmitry_petrov), Artur Kuzin (n01z3), а также всем, кто вычитывал статью перед публикацией, за правки и рецензии.

Отдельная благодарность Nikita Zavgorodnii (njz) — за финальную корректуру.

Спасибо за внимание, надеюсь эта статья будет кому-нибудь полезна.

Мой ник в Kaggle / ods.ai: kruegger


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

[Перевод] Цена персональной безопасности для директоров крупнейших IT-компаний в год

Верхний потолок таких трат стремится к 10 миллионам долларов в год.Крупнейшие IT-компании Силиконовой долины ежегодно планируют в своем бюджете громадные статьи затрат на защиту своей интеллектуальной собственности.Некоторые из этих компаний также выделяют значительные суммы, чтобы организовать комплексную защиту и обеспечение ...

[Перевод] Создание игры для Game Boy

Несколько недель назад я решила поработать над игрой для Game Boy, создание которой доставило мне большое удовольствие. Её рабочее название «Aqua and Ashes». Игра имеет открытые исходники и выложена на GitHub. Как мне пришла в голову эта идея Недавно я ...