Описание Проекта

Следующий проект пытается предсказать скорость оттока пользователей в вымышленном музыкальном потоковом сервисе под названием Sparkify.

Я использовал Spark в Amazon Web Services (AWS) с кластером Elastic Map Reduce (EMR) из 3 компьютеров m5.xlarge. Один водитель и два рабочих. Размер набора данных составляет 12 Гбайт, и он был прочитан из корзины AWS Simple Storage Service (S3) в формате JSON. Этот файл содержит информацию о действиях, зарегистрированных пользователями по мере их ежедневного использования сервиса.

В качестве программных библиотек я использовал: PySpark, Python Spark API. AWS EMR версии 5.29.0. Логистическая регрессия, случайный лес, классификатор градиентных деревьев (GBT) и наивный байесовский алгоритм составляют библиотеку машинного обучения Spark. Pandas и Matplotlib из стандартного стека Python для обработки данных.

понимание бизнеса

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

Отток клиентов обходится компаниям примерно в 136 миллиардов долларов в год, согласно исследованию, проведенному ведущей аналитической фирмой по взаимодействию с клиентами 1.

Исследование, проведенное Bain & Company, показывает, что увеличение показателей удержания клиентов всего на 5 % увеличивает прибыль на 25–95 % 2.

Обоснование расходования ресурсов на сокращение оттока основано на исследовании, проведенном Lee Resource Inc., в котором они показали, что привлечение новых клиентов может стоить компании в пять раз больше, чем удержание существующего! 3.

Понимание данных

Всего в наборе данных 543 705 строк и 18 столбцов. Схема следующая:

Всего у нас есть 22 уникальных записи в категории page.

Я определил новый столбец под названием Churn, который состоит из любого из следующих элементов: Подтверждение отмены или Отправить События Downgrade как подтверждение выхода пользователя из сервиса или прекращения его оплаты (бесплатная подписка). Распределение обращений на страницу:

Мы видим, что страница NextSong используется часто, что имеет смысл, так как это указывает на то, что пользователи слушают песни. Далее идет Главная, за которой следуют три, указывающие на взаимодействие со службой: Мне нравится, >Добавить в плейлист и Добавить друга. Эти три указывают на положительный опыт работы с сервисом. С другой стороны, у нас есть Прокрутить рекламу, Мне нравится и Ошибка как возможные индикаторы плохого опыта пользователей со службой.

Как видно из сводки, мы сталкиваемся с очень несбалансированным набором данных. Соотношение отсутствия оттока (0) и оттока (1) составляет 2516.

Всего существует 225 393 женщины и 302 612 мужчин, из которых 15 700 пользователей не указали свой пол, и я отнес их к категории U (недоступно):

Всего у нас 428 597 платных пользователей и 115 108 пользователей бесплатного плана. /услуга. Как мы заявляли ранее, мы должны убедиться, что мы сохраняем этих платных подписчиков настолько, насколько это возможно, чтобы максимизировать доход (или минимизировать потери).

Подготовка данных

Первое, за что я взялся, это решить проблему дисбаланса. Я использовал технику под названием избыточная выборка. Это очень простой метод, в котором я воспользовался функцией PySpark explode dataframe, чтобы выбрать как можно больше событий из недопредставленного класса (в данном случае отток равен 1), чтобы заполнить разницу, пока не получу сбалансированные данные. настроен на работу с.

Есть более продвинутые методы, о которых я читал, но они в основном созданы для кадров/наборов данных Pandas/Numpy и плохо распараллеливаются в моей среде Spark. Это определенно требовало больше времени и исследований, чтобы найти более надежное решение. Наиболее многообещающим методом, который я изучил, является SMOTE, где заинтересованные читатели могут найти более подробную информацию здесь и здесь.

После применения этой техники я расширил и сбалансировал фрейм данных, увеличив его ~50%:

Общее количество записей увеличилось с 543 705 до 1 086 945. Это оказалось очень полезным, так как точность моей модели повысилась, и я значительно уменьшил проблемы переобучения, с которыми сталкивался без нее. Даже если он не идеален и может быть улучшен дальше.

userAgent предоставляет некоторую информацию. Я создаю две функции, которые использовал: os и браузер. .

В браузере видно, что 642 801 используют Safari и 249 372 используют Firefox. .

Windows является более используемой операционной системой, за ней следуют Macintosh и X11 (Linux). iPhone является 4-м более используемым и совместимым, возможно, имеется в виду Android?

Я использовал столбец ts (отметка времени) для создания дополнительных функций. Из ts я построил столбцы day_of_week и час.

Используя эти новые столбцы, мы видим, что пользователи, как правило, слушают больше песен к концу дня. Пользователи начинают слушать после обеда, достигая пика в 16–17 часов (во время поездки на работу?).

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

Я построил следующие функции:

  • saved_settings Количество всех событий страницы «Сохранить настройки», сгруппированных по «userId».
  • num_songs Подсчет количества «песен», сыгранных пользователями (сгруппированных по «userId»)
  • thumbs_up Количество всех событий страницы "Мне нравится", сгруппированных по "userId"
  • num_advertisement Счетчик всех событий страницы «Roll Advert», сгруппированных по «userId».
  • thumbs_down Количество всех событий страницы "Thumbs Down", сгруппированных по "userId"
  • playlist_added Количество всех событий страницы «Добавить в плейлист», сгруппированных по «userId».
  • friend_added Количество всех событий страницы "Добавить друга", сгруппированных по "userId"
  • errors_pages Количество всех событий страницы «Error», сгруппированных по «userId».
  • songs_persession Среднее количество композиций (по событию страницы "Следующая песня"), воспроизведенных пользователями (сгруппировано по "userId") для данного сеанса ('sessionId')

Я использовал StringIndexer, VectorAssembler и Normalizer из библиотеки функций PySpark ML. StringIndexer кодирует строковый столбец меток в столбец индексов меток. VectorAssembler, который является преобразователем, объединяет заданный список столбцов/функций в один векторный столбец, как того требуют алгоритмы машинного обучения. Наконец, Normalizer – это преобразователь, который преобразует набор данных из строк Vector, нормализуя каждый Vector иметь единичную норму. Он принимает параметр p, который определяет p-норму, используемую для нормализации. (p=2 по умолчанию.) Эта нормализация может помочь стандартизировать ваши входные данные и улучшить поведение алгоритмов обучения.

Моделирование

Я разделил набор данных на наборы для обучения и тестирования с разделением 80–20 процентов соответственно, чтобы перейти к этапу моделирования.

Для моделирования я использовал алгоритмы логистической регрессии, случайного леса, классификатора GBT и наивного байесовского алгоритма из библиотеки Spark ML. Я измерил лучшего исполнителя, используя метрику F-1 в качестве параметра, чтобы все они могли выбрать лучшего и отрегулировать его.

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

Выбор модели

Я обучил алгоритмы логистической регрессии, классификатора случайного леса, классификатора GBT и наивного байесовского алгоритма с параметрами по умолчанию на «тренировать» набор данных и оценивать его с помощью «тестового» набора данных.

Где:

F1-оценка F-1

WP – взвешенная точность

WR – взвешенный отзыв

Выбор лучшей модели

Из таблицы 1 видно, что наиболее эффективной моделью является GBTClassifier. Я настроил эту модель, выполнив перекрестную проверку с 5 сгибами и сеткой параметров следующим образом:

Я оценил модель с теми же метриками, что и раньше, получив следующие значения:

Вывод

Как мы видим, эта точно настроенная модель обеспечивает увеличение всех показателей на 4% по сравнению с предыдущим запуском и почти на 10% увеличение по сравнению с другими моделями!

Наша модель предсказала, что 46 435 пользователей уйдут, но уйдут (истинно положительные) и 58 499 не уйдут пользователи, которые покинут службу (истинно отрицательные). Модель также предсказала, что 13 790 пользователей уйдут, но не уйдут (ложноположительный результат), и 4047 не уйдут пользователи, которые уйдут (ложноотрицательный результат).

Однако наша модель далека от совершенства. С точностью всего 77% и отзывом из 92% означает, что мы правильно предсказываем 2/3 случаев оттока.

GBTClassifier был лучшим из всех алгоритмов, которые я пробовал в этом проекте, а также тем, который требовал больше времени для обучения, поскольку он обучает одно дерево за другим. У меня были проблемы с производительностью кластера EMR, и мне пришлось выполнить некоторые настройки, чтобы успешно обучить все эти модели в Spark. За всеми этими подробностями обращайтесь в мой репозиторий GitHub.

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