Хакатоны во многом повлияли на мою карьеру в области науки о данных. Они помогли мне понять важность структурированного мышления и то, как его использовать при работе в сжатые сроки. Эта идея на самом деле является той сущностью, которая определяет роль успешного специалиста по данным.
Я получаю много вопросов от начинающих профессионалов в области науки о данных, которые задаются вопросом, как выделиться среди конкурентов и занять достойное место в этой области. Это многослойный вопрос, но я всегда указываю на один из общих элементов - начните участвовать в хакатонах и оцените, где вы стоите.
А если вы сможете подняться в таблице лидеров, то даже лучше!
В этой статье я с радостью расскажу о трех наиболее успешных подходах (и кодах!) С хакатона WNS Analytics Wizard 2019. Это был самый крупный хакатон Analytics Vidhya на сегодняшний день, и у победителей есть чему поучиться.
Так что берите ручку и бумагу, делайте заметки и не пропустите другие хакатоны! Отправляйтесь прямо на платформу DataHack и записывайтесь на предстоящие соревнования уже сегодня.
О хакатоне WNS Analytics Wizard 2019
WNS Analytics Wizard 2019 стал крупнейшим хакатоном, когда-либо проводившимся Analytics Vidhya. Вот краткие цифры этого исторического хакатона:
- Всего регистраций: 6 456
- Всего отправлено: 11 564
- Призовой фонд: на сумму 4 Lacs (и возможность прохождения собеседования с WNS)
Это был запоминающийся 9-дневный хакатон, в котором приняли участие специалисты по данным со всего мира.
Описание проблемы для хакатона WNS Analytics Wizard 2019
Давайте посмотрим на постановку задачи на этом хакатоне.
Zbay - это веб-сайт электронной коммерции, который продает различные продукты на своей онлайн-платформе. Zbay записывает пользовательское поведение своих клиентов и сохраняет его в форме журнала. Однако в большинстве случаев пользователи не покупают продукты мгновенно, и существует временной промежуток, в течение которого покупатель может путешествовать по Интернету и, возможно, посещать веб-сайты конкурентов.
Теперь, чтобы улучшить продажи продуктов, Zbay нанял Adiza, компанию Adtech, которая создала систему, в которой реклама продуктов Zbay отображается на веб-сайтах своих партнеров.
Если пользователь заходит на веб-сайт Zbay и ищет продукт, а затем посещает эти партнерские веб-сайты или приложения, его / ее ранее просмотренные товары или аналогичные им товары отображаются как реклама (реклама). Если пользователь нажимает на это объявление, он / она будет перенаправлен на веб-сайт Zbay и может купить продукт.
В этой задаче задача состоит в том, чтобы спрогнозировать вероятность клика, т. е. вероятность того, что пользователь нажмет на рекламу, которая будет показана ему на партнерских сайтах в течение следующих 7 дней, на основе данных журнала просмотра истории, показов рекламы. данные и данные пользователя.
Участникам были предоставлены:
- Просмотр журнала пользователей (2018/10 / 15–2018 / 11/11)
- Описание продукта собрано с сайта Zbay
- Данные обучения и данные тестирования, содержащие подробную информацию о показах рекламы на партнерских сайтах (Train + Test)
Данные обучения содержат журналы показов за период 2018/11 / 15–2018 / 12/13 вместе с меткой, которая указывает, нажимают ли объявление или нет. Окончательная модель была оценена на основе данных тестирования, в которых есть журналы показов за 2018/12 / 12–2018 / 18/18 без этикеток.
Описание набора данных
Участникам были предоставлены следующие файлы:
- train.zip: он содержал 3 файла, описание каждого из которых я привел ниже.
- test.csv: тестовый файл содержал показы, для которых участникам нужно было спрогнозировать рейтинг кликов.
train.csv:
Variable Definition impression_id AD impression id impression_time Time of the impression at partner website user_id user id app_code Code for partner website where ad was shown os_version Version of operating system is_4G 1-Using 4G, 0-No 4G is_click (target) Whether user clicked AD (1-click, 0-no click)
view_log.csv:
Variable Definition server_time Timestamp of the log device_type Device type of the user session_id Browser session id user_id user id item_id Item id
item_data.csv:
Variable Definition item_id Item id item_price Price of the item category_1 Category depth 1 category_2 Category depth 2 category_3 Category depth 3 product_type anonymized item type
Победители хакатона WNS Analytics Wizard 2019
Победа в хакатоне - задача в высшей степени сложная. Необходимо преодолеть множество препятствий, не говоря уже об огромной конкуренции со стороны ведущих ученых мира.
Мне понравились лучшие решения и подходы, предложенные нашими победителями. Для начала посмотрим, кто победил, и поздравим их:
- 1 место: Роман Пьянков.
- 2 место: Сергей Арефьев.
- 3 место: Команда АК (predictt.ai)
Вы можете проверить окончательные рейтинги всех участников в Таблице лидеров.
Три лучших победителя поделились своим подробным подходом к конкурсу. Я уверен, что вам не терпится узнать их секреты, так что приступим.
Ранг 3: Team AK (predictt.ai) (Аакаш Керават и Акшай Карангале)
Вот чем поделились с нами Team AK.
Подход
Нашим окончательным решением стал ансамбль моделей LightGBM, Neural Networks и CatBoost.
Беглый взгляд на наборы данных показал, что функции, созданные из view_logs, будут играть важную роль в улучшении оценки. Но вскоре мы обнаружили, что большинство функций, сгенерированных из view_logs, не соответствовали обучающему набору.
Это произошло потому, что более высокий процент обучающих данных имел недавние журналы view_logs, чем в тестовом наборе. Итак, мы больше сосредоточились на разработке функций в обучающей выборке.
Для нас работали следующие функции: процент_clicks_tilldate на пользователя / app_code / user_app_code. Только эти функции помогли нам достичь 0,73xx в общедоступной таблице лидеров. Наряду с этим мы использовали некоторые функции, основанные на времени, и несколько функций из view_logs.
У нас обоих были немного разные подходы, и мы получили схожие результаты в общедоступной таблице лидеров - около 0,75хх.
Помимо этих общих функций, мы использовали несколько различных техник / функций в наших индивидуальных подходах, получив оценку около 0,75xx. В нашей последней отправке мы оценили среднее значение наших лучших индивидуальных моделей.
Подход Аакаша:
- Мои самые мощные функции были ориентированы на цель, т. Е. На среднее значение предыдущих кликов для user_id, для app_code и для user_id / app_code вместе взятых. Средневзвешенное значение вышеупомянутого также оказалось важным (придание более высокого веса более поздним записям). Другие функции, которые я создал:
1. time_since_prev_ad
2. number_of_impressions (для пользователя)
3. sum_of_prev_clicks
4. impression_time_hour, и т. Д. - Я разработал функции для view_logs отдельно, а затем присоединил к ним на основе самого последнего server_time. Однако , только одна функция - количество просмотров - была полезной, в то время как другие переоснащались
- Для решения этой проблемы важна была сильная стратегия проверки, поскольку данные train и view_logs пересекались. Я разработал набор проверки, воспроизводящий набор тестов (нет пересечения между набором проверки и view_logs)
- Наконец, я обучил 20 моделей LightGBM и 20 полносвязных нейронных сетей (все модели имеют случайное состояние как единственное отличие), взял среднее арифметическое для моделей LightGBM и моделей нейронных сетей. И, наконец, я взял среднее гармоническое значение двух выходов. Это дало оценку общедоступной таблице лидеров 0,754x.
Подход Акшая
Моя стратегия проверки заключалась в простом разбиении по времени:
- Поскольку функции view_logs переоснащались в обучающем наборе, я создал дополнительный набор данных из набора данных view_logs: train_view_logs (подмножество исходных данных без перекрытия на наборе данных поезда)
- Я использовал train_view_logs для создания функций для обучающего набора данных и использовал исходный view_logs для создания функций для тестового набора данных.
- Функция app_code была очень важна, поэтому я решил закодировать ее таким образом, чтобы уловить скрытые отношения между ними. Я использовал модель word2vec для преобразования app_codes в 100-мерные векторы и использовал их вместо исходной переменной app_codes.
- Помимо этого, я создал такие функции, как:
1. time_since_prev_impression
2. time_to_next_impression
3. last_impression_app_code
4. peak_to_peak_server_time (для каждого пользователя) и т. Д. - Используя эти функции, я обучил 15 моделей LightGBM с разными начальными числами и одной моделью CatBoost. Я взял простое среднее этих моделей, чтобы достичь 0,754xx в общедоступной таблице лидеров.
Вы можете ознакомиться с полным кодом этого подхода здесь.
2 место: Арефьев Сергей.
Вот чем поделился с нами Арефьев.
Общий подход
- Использование повышения градиента в качестве основного алгоритма
- Стратифицированная перекрестная проверка
- Пользовательский стандарт для функций прогнозирования кликов (количество значений и среднее кодирование по идентификаторам, разница между временем кликов, группировка по идентификатору и длина уникальных элементов)
- Выбор функций и параметры тонкой настройки модели
Давайте теперь посмотрим на подход Арафьева по шагам.
Предварительная обработка данных и разработка функций
- Стандартные функции из train.csv:
- ‘Os_version’
- ‘is_4G’
а. ‘Value_counts_app_code’: частотная кодировка для функции кода приложения.
б. ‘Mean_target_user_id’: среднее значение цели для каждого user_id в прошлом
- Характеристики времени User_id:
a. Время с последнего и с момента следующего показа по user_id
b. Минимальное время между показами по user_Ids - Возможности номеров User_id:
a. Количество уникальных app_code для каждого user_id
b. Разница между количеством уникальных app_code и value_counts для каждого user_id - Количество уникальных элементов из view_log.csv, которые пользователь искал более недели назад (impression_time - 7 дней)
- Количество показов пользователей в прошлом и value_counts по user_ids в view_log
- Группировка по app_code: для каждого app_code рассчитайте среднее значение по этим функциям:
- ‘Mean_target_user_id’
- ‘Value_counts_user_id’
- Время до следующего показа от user_id
Моя последняя модель
- Моя последняя модель - это средний ранг (отсортируйте прогнозы от одной модели и присвойте им ранг от 0 до длины тестового набора данных) прогнозов от 5 моделей. Они обучаются на разных наборах поездов путем стратифицированной проверки.
- Смена валидации с временного ряда на стратифицированную дала мне скачок на 0,01 балла. Кроме того, я отказался от таких функций, как app_code и user_id, хотя они дали лучший результат при проверке.
- Теперь у меня было около 50 функций. Я вычислил важность функции повышения градиента для полного набора функций, отсортировал их по убыванию и начал отбрасывать функции одну за другой. В итоге я получил финальное подмножество описанных выше функций.
Основные выводы
- Используйте стратифицированную перекрестную проверку, если распределение целевой переменной не меняется со временем
- Использовать статистику времени и чисел по идентификаторам
- Группировать по основным идентификаторам
- Отбросьте элементы, если вы думаете, что они больше подходят вашей модели.
На чем должен сосредоточиться участник при решении таких проблем
- Выберите правильную валидацию
- Начните с небольшого набора функций
- Начать использовать усиление градиента
- Сделать выбор функции
Вот полный код подхода Арефьева.
1 место: Роман Пьянков.
Вот чем поделился с нами Роман.
Подход
Мое решение состоит в основном из разработки функций.
Я создал функции на основе идентификатора пользователя и характеристик кода приложения. Более подробно это описано ниже. Я обучил модель LightGBM на 10 различных подвыборках. В качестве окончательного прогноза я усреднил эти модели по рангам.
Схема валидации
Для проверки я использовал StratifiedKFold (из выбора sklearn.model) со следующими параметрами:
- n_splits = 10
- случайное состояние = 228
- shuffle = True
Функциональная инженерия
- Я закодировал строковые значения столбцов os version в целочисленные значения (номер категории)
- Из столбца «время показа» я сделал две новые функции - «час» и «минута».
- user_id: Я вычислил количество уникальных значений из столбца app_code (cnt unique app). Вычислил разницу и соотношение между количеством уникальных значений и количеством всех значений для user_id (’gg 1 diff’, ’gg 1 ratio’) -
- app_code: Я подсчитал количество уникальных значений из столбца user_id. Вычислил разницу и соотношение между количеством уникальных значений и количеством всех значений для идентификатора кода приложения (’gg 2 diff’, ’gg 2 ratio’).
- Для каждого «user_id» я рассчитал среднюю, минимальную и максимальную разницу между двумя последовательными «impression_time» («среднее время разницы», «максимальное время разницы», «время разницы мин»).
Для каждого user_id и impression_time я рассчитал:
- Время от текущего времени показа до предыдущего и следующего действия пользователя. Вычислено среднее количество действий, на которые пользователь щелкнул в предыдущий раз («различное время идентификатора пользователя последний», «различное время пользовательского идентификатора следующего», «значение означает идентификатор пользователя»)
- Время от текущего времени показа до предыдущего и следующего действия кода приложения для каждого app_code и impression_time. Вычисленное среднее количество действий, которые пользователи с этим app_code нажимали в предыдущий раз ('diff time app code last', 'diff time app code next', 'value mean app code')
- Количество действий в журнале просмотра за предыдущий раз (’value cnt view user id’)
- Средняя, минимальная и максимальная разница между двумя последовательными «серверными временем» в журнале просмотра за предыдущее время («значение разницы времени просмотра идентификатора пользователя» значения разницы времени просмотра идентификатора пользователя max »,« значения разницы времени просмотра идентификатора пользователя min »)
- Количество уникальных значений столбцов из view_log с данными элемента: ['идентификатор сеанса', 'идентификатор элемента', 'категория 1', 'категория 2', 'категория 3', 'тип продукта'] ('идентификатор пользователя уникальный идентификатор сеанса ',' идентификатор пользователя уникальный идентификатор элемента ',' идентификатор пользователя уникальная категория 1 ',' идентификатор пользователя уникальная категория 2 ',' идентификатор пользователя уникальная категория 3 ',' идентификатор пользователя уникальный тип продукта ')
- Режим значений столбцов из view_log с данными элемента: ['item id', 'category 1', 'category 2', 'category 3', 'product type'] ('user id mode item id', ' категория режима идентификатора пользователя 1 »,« категория режима идентификатора пользователя 2 »,« категория режима идентификатора пользователя 3 »,« тип продукта в режиме идентификатора пользователя »)
Окончательная модель
В качестве последней модели я использовал LightGBM со следующими параметрами:
- фракция мешков = 0,8
- частота упаковки = 1
- boost = gbdt
- доля признаков = 0,8
- скорость обучения = 0,01
- метрика = «AUC»
- количество листьев = 31
- цель = бинарный
Я использовал StratifiedKFold с 10 сгибами, поэтому у меня было 10 моделей, которые использовались для прогнозирования тестовых данных. В качестве окончательного прогноза использовалось ранговое усреднение этих 10 прогнозов. При локальной проверке я получил следующее среднее значение ROC-AUC: 0,7383677000.
Для таких задач участник должен сосредоточиться на:
- Функциональная инженерия
- Компетентная проверка строительства
- Грамотная работа с категориальными признаками
- Установка параметров модели
- Контроль переобучения
И вот полный код выигрышного решения Романа!
Конечные заметки
Уф - сделай глубокий вдох. Это были потрясающие фреймворки, выигравшие этот хакатон. Как я упоминал ранее, выиграть хакатон - непростая задача, и трое наших победителей действительно выделялись своим мыслительным процессом.
Я призываю вас перейти на платформу DataHack СЕГОДНЯ и принять участие в текущих и предстоящих хакатонах. Это будет бесценный опыт обучения (не говоря уже о хорошем дополнении к вашему многообещающему резюме!).
Если у вас есть какие-либо вопросы, не стесняйтесь размещать их ниже.
Первоначально опубликовано на www.analyticsvidhya.com 10 сентября 2019 г.