Определение проекта

Обзор проекта

В этом проекте будет использоваться большой набор данных Sparkify из Udacity.

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

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

Постановка задачи

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

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

Метрики

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

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

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

Анализ

Исследование данных и визуализация данных

Необработанный набор данных состоит из следующих столбцов: исполнитель, авторизация, имя, пол, itemInSession, фамилия, длина, уровень, местоположение, метод, страница, регистрация, sessionId, песня, статус, ts, userAgent, userId. Он имеет 26 259 199 зарегистрированных событий.

Мы очистили набор данных, удалив строки с нулевым или пустым «userId» или «sessionId».

Мы также удалили строки о том, что событие произошло до регистрации пользователя. Так как анализ будет производиться в момент после регистрации пользователя.

Отток определяется путем проверки того, обращался ли пользователь к странице «Подтверждение отмены». А коэффициент оттока составляет 22,46%.

Дата регистрации пользователя — между 2017–10–14 и 2018–11–30. Окно зарегистрированных событий находится между 2018–09–30 и 2018–11–30.

Во-первых, мы проверим даты регистрации пользователей. Мы видим, что большинство пользователей зарегистрированы с июля 2018 года по сентябрь 2018 года, когда начинается дата окна событий.

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

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

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

Еще одно интересное поведение — сезонность пользовательской активности. Количество активных пользователей в выходные уменьшается, и это справедливо для обеих групп пользователей. Мы даже можем заметить падение активности в День благодарения, который был 22 ноября 2018 года.

Возраст пользователя и средний возраст пользователя, который представляет собой среднее значение всех событий пользователя, также ниже для пользователей, которые отменили услугу. Ожидается, что первый будет 63 дня против 89 дней. Средний возраст пользователей составляет 53 и 67 дней соответственно. Их гистограмма показана на рисунке ниже.

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

Методология

Предварительная обработка данных

Набор данных состоит из строк с событиями. Это не подходит для ввода контролируемой модели машинного обучения. Обычный фрейм данных, который должен быть загружен в модель, имеет уникальную строку для каждого пользователя. И у каждого из пользователей должно быть несколько фич и ярлык. Таким образом, используемый фрейм данных должен содержать столбец с каждым «userId», несколько столбцов функций и столбец меток.

Первым шагом является обработка уникальных индексов, которые мы будем использовать. В данном случае это «userId» и «artist».

Несколько строк имеют нулевой «исполнитель», и поэтому мы позволяем индексатору Spark обрабатывать их как отдельную категорию с одним идентификационным номером, чтобы он не удалял эти столбцы. Это необходимо, так как исполнители есть только у событий страницы «NextSong».

Затем мы создаем столбцы «timestamp» и «registration_date», которые представляют собой преобразование столбцов «registration» и «ts» в формат «timestamp» Spark. Мы также создаем столбец «истекшее», который представляет собой время, прошедшее с момента регистрации до отметки времени события. В столбце «elapsed_days» это прошедшее время указано в днях.

Затем мы приступаем к удалению отрицательных прошедших дней, так как мы будем анализировать данные после регистрации пользователя.

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

Первой характеристикой, которую мы выбираем, является «художник». Если бы мы создали столбцы для подсчета каждого исполнителя, сыгранного пользователем, у нас было бы 38 336 столбцов. И было бы очень мало. Для большинства пользователей он будет заполнен нулями.

Это когда уменьшение размерности полезно. Мы можем создать некоторые скрытые функции, которые могут описывать, какие артисты нравятся пользователю.

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

Spark будет обучать модель, а предсказания станут новыми «художниками». Однако нам нужны не рекомендации, а скрытые черты модели.

Поскольку у нас нет пользовательских рейтингов исполнителей, мы можем приблизиться к этому, подсчитав, сколько раз пользователь проигрывал песню определенного исполнителя. Затем для каждого пользователя мы делим все подсчеты на артиста с наибольшим количеством, чтобы сохранить диапазон от 0 до 1. Интуиция такова, что пользователю больше нравится самый популярный исполнитель. Мы выбрали 20 в качестве количества скрытых функций, это можно настроить, но, поскольку у нас есть несколько других параметров для настройки, это займет много времени.

Мы добавили в модель взаимодействие пользователя со страницей. Для каждого пользователя мы подсчитываем взаимодействия для каждой страницы, затем делим на сумму всех взаимодействий пользователя со страницей. Мы также ведем только подсчеты. Для обеих групп у нас есть 17 функций. Мы удалили «Отмена» и «Подтверждение отмены», поскольку это то, что мы пытаемся предсказать.

Мы создали столбец для последнего уровня пользователя, который может быть «бесплатным» или «платным». Также мы подсчитали процент событий, произошедших при «оплате» уровня. У каждого есть одна особенность. Первое — это 0 или 1, второе — процент «оплаченных» событий.

Мы добавили столбец пола, который также является одним столбцом со значениями 0–1. Мы также добавили среднюю длину песни и стандартное отклонение для каждого пользователя.

Мы создали почасовые воспроизводимые песни и среднюю продолжительность для каждого из 24 часов.

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

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

Общее количество функций 116.

Выполнение

Мы обучили четыре модели машинного обучения: случайный лес, логистическую регрессию, классификатор GBT и линейный SVM.

Сначала мы разделили данные на тренировочный и тестовый наборы в соотношении 75–25 %.

Мы масштабировали наши функции с помощью Spark «MaxAbsScaler», который в основном делит конкретный столбец функций на его максимальное абсолютное число, которое сохраняет диапазон от -1 до 1.

Затем мы загружаем четыре модели масштабированными функциями и обучаем их предсказывать столбец «метка», который равен 0–1. Одним из них являются пользователи, которые отменили услугу.

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

Сначала мы проводим все это обучение в «мини» наборе данных. Затем мы выбираем две лучшие модели и обучаем полный набор данных.

Уточнение

Мы пытаемся улучшить оценки с помощью двух методов: увеличения количества признаков и добавления весов к каждому примеру модели.

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

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

Веса были рассчитаны в соответствии с коэффициентом оттока. Таким образом, пользователи, отказавшиеся от услуги, имеют вес «1 — churn_rate», а остальные — вес «churn_rate».

Результаты

Оценка модели

Мы обучили четыре модели с помощью мини-набора данных. Затем мы тренировались с функциями прошлой недели, а затем с функциями прошлой недели плюс веса. Мы выбрали две лучшие модели и обучили их с использованием характеристик и весов прошлой недели на полном наборе данных. Результаты F1 представлены на рисунке ниже.

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

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

Однако добавление функций прошлой недели не улучшает модели в целом. Классификатор ББТ становится даже хуже.

Алгоритмы на основе дерева решений (случайный лес и классификатор GBT) также имеют более низкий балл, чем две другие модели.

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

Если и линейный SVM, и логистическая регрессия сопоставимы, лучше выбрать более простую модель, то есть логистическую регрессию.

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

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

Обоснование

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

Добавление весов примеров увеличило оценку, потому что наименее заметные метки имеют большее значение для оптимизации модели. И поскольку мы измеряем F1, оно увеличивается, даже если это может повредить точности.

Мы ожидали, что добавление функций прошлой недели повысит оценку, но оказалось, что это не улучшает большинство моделей, а только Linear SVM. Причина может быть та же, что и у алгоритмов на основе дерева решений: количество функций по сравнению с количеством пользователей.

В мини-наборе данных у нас есть примерно 200 пользователей, 100 функций и 200 функций, если мы включим функции прошлой недели. Полный набор данных насчитывает около 22 000 пользователей.

Когда у нас меньшее отношение количества пользователей к количеству функций, лучше использовать алгоритмы с низким смещением и высокой дисперсией, такие как логистическая регрессия и линейный SVM [1].

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

Вывод

Отражение

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

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

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

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

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

Улучшения

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

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

Мы также можем сделать выбор параметров тестируемых моделей.

Не стесняйтесь комментировать! Блокноты с кодом находятся в репозитории проекта.

Ссылка