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

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

Это заставило меня искать альтернативы. Одной из платформ, которая вызвала у меня интерес, была HackerRank. HackerRank - это не совсем платформа для соревнований по машинному обучению, как Kaggle. Вместо этого он является местом проведения конкурсов по программированию, и одним из его (под) доменов является машинное обучение.

Конкурс, в котором я участвовал, назывался Machine Learning CodeSprint. Однонедельное соревнование, состоящее из двух отдельных задач, задачи бинарной классификации и задачи рекомендации. В окончательных представлениях должны быть не только результаты, но также (читаемый) исходный код и документация, что еще больше усложняет и без того сжатые сроки. Если вас интересует первое, продолжайте читать, в противном случае переходите ко второй части серии (она скоро выйдет!).

Для тех из вас, кто еще здесь, приступим!

Задача

Первая задача - «Предсказать количество открытий писем», и, как следует из названия, наша цель - определить, откроет ли пользователь из HackerRank данное электронное письмо или нет. Для этой задачи у нас есть доступ к набору обучения и тестов, которые содержат информацию об отправленном электронном письме и пользователе, который его получил. Наборы данных имеют 48 общих функций, а обучающий набор имеет 6 дополнительных функций, включая целевую переменную. Возможности можно разделить на следующие категории:

  • Характеристики профиля: основная информация о пользователе, такая как идентификатор пользователя, подтверждена ли его учетная запись и дата регистрации пользователя;
  • Функции электронной почты: информация об электронной почте, такая как идентификатор электронной почты, категория электронной почты и дата ее отправки;
  • Особенности действия: информация о поведении пользователя, количестве раз, когда он входил в систему, количестве сообщений, количестве конкурсов и т. Д. Они в основном разделены на несколько временных рамок (1, 7, 30 и 365 дней) и составляют большинство Особенности;
  • Целевые функции: функции, связанные с целевой переменной (открытая), например, дата открытия электронного письма, щелкнул ли пользователь по какой-либо ссылке в нем, отказался ли он от подписки на это письмо или нет. Они доступны только в обучающем наборе.

(Light) Исследование данных и выбор функций

Самый важный урок, который я извлек из соревнований по машинному обучению, заключается в том, что вы должны начинать работать с конца. Чего ждать? Да это правильно. Первое, что нужно сделать, это настроить конец фреймворка моделирования. Другими словами, ваша стратегия проверки.

При разработке моделей прогнозирования для соревнований единственное, в чем мы должны убедиться, - это то, что наша модель сможет быть обобщена на тестовый набор. Для этого мы проверяем тестовые данные на предмет возможных «мусорных» функций и искажений. Для этой задачи я нашел 12 функций, которые имели отклонение менее 1% в тестовом наборе. Для некоторых функций присутствовало только одно значение. Отказ от этих переменных делает модель более устойчивой, а также сокращает время обучения, что очень ценно, учитывая временные рамки в одну неделю.

Одна странность, которую я обнаружил, касалась одной из функций электронной почты, «категории электронной почты», как показано на следующей гистограмме:

Всего было 18 различных категорий, причем категория 15 была самой распространенной в обучающей выборке. Удивительно, но в тестовой выборке этой категории не было, наряду с категорией 13. Что делать дальше? Я пробовал следующее:

  • Преобразуйте недостающие категории в тестовом наборе в NA
  • Полностью удалить кейсы с отсутствующими категориями в тестовом наборе
  • Удалить функцию категории электронной почты
  • Ничего не делать

Моя первоначальная ставка была на третий вариант. Но оказывается, что «ничего не делать» привело к лучшим результатам. В данном случае это не имело большого значения, но мы должны опасаться такого рода искажений, поскольку они могут негативно повлиять на нашу работу в рейтинге конкурса.

Функциональная инженерия

Следующим шагом после удаления мусора является разработка некоторых новых функций. Для задач, связанных с каким-либо взаимодействием между двумя или более участниками, в данном случае пользователем и электронной почтой, вычисление среднего значения целевой функции для каждого отдельного субъекта, которое переводится в P (цель | субъект), обычно дает хорошие результаты. Вы также можете попробовать P (цель | актер_1, актер_2,…, актер_n), однако из-за количества комбинаций для этого требуется объем данных, который не был доступен для этого соревнования. Некоторые из этих функций представлены на следующих графиках:

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

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

С чистыми данными и множеством новых функций мы можем перейти к обучению модели.

Модельное обучение и результаты

Когда дело доходит до контролируемых алгоритмов классификации, существует множество вариантов. Я выбрал XGBoost из-за его истории побед в классификационных соревнованиях. Немного утомительно оптимизировать его бесконечные параметры, но он превосходит большинство альтернатив, будучи очень быстрым. Позже я обнаружил auto-sklearn, фреймворк, сочетающий оптимизацию гиперпараметров с ансамблями моделей. Я не тестировал его, но если он выполнит обещанное, то определенно станет достойным конкурентом автономной модели XGBoost.

Помимо производительности, у XGBoost есть несколько полезных функций. Он принимает большое количество оценочных показателей и может выводить важность характеристик модели. Метрикой соревнования была F1 Score, которая изначально не поддерживается XGBoost, поэтому я выбрал AUC в качестве замены, поскольку это также своего рода сбалансированная метрика точности.

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

  • Оценка обучения: 0,76
  • Оценка валидации: 0,70
  • Рейтинг в публичной таблице лидеров: 0,58
  • Рейтинг Private Leaderboard: 0,59

В этом испытании я получил результат 36/411. Не удивительно, но и неплохо. Я проиграл всего 0,01 от выигрышного решения. Эта небольшая разница также показывает, что данные были не очень хорошими с самого начала, поскольку не было много информации, которую можно было бы использовать.

Также имеет место явное плохое переоснащение, о чем можно судить по разнице между оценками. Интересная концепция для изучения в будущих проектах - это состязательная проверка. К сожалению, я узнал об этом только после конкурса. Это помогло бы создать более надежную структуру проверки.

Код: https://github.com/caiotaniguchi/hackerrank-ml-sprint

На этом пока, увидимся во второй части!