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

Перейдите на GitHub для получения репозитория: https://github.com/davidweisscode/churn-prediction-sparkify

Обзор

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

Деловая потребность

Учитывая поведение пользователя в Sparkify, насколько вероятно, что он откажется (отменит подписку)? Вопрос решается с помощью подхода классификации машинного обучения. Проект исследует различные типы алгоритмов классификации, чтобы поддержать аргумент о том, что существует сильная частичная корреляция между поведением пользователя и его вероятностью оттока. Обученные и протестированные алгоритмы: классификатор случайного леса, логистическая регрессия. Модели дополнительно настраиваются для своих гиперпараметров, чтобы улучшить их характеристики, а алгоритмы оцениваются на основе F1-Score.

Оценка

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

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

Загрузка и предварительная обработка

Набор данных содержит 228 108 строк, где каждая строка представляет собой действие пользователя, описанное с помощью его метаданных (см. схему данных ниже). Действие пользователя кодируется в столбце page. Примеры действий пользователя: Thumbs Up / Add to Playlist / Submit среди прочих.

root
 |-- artist: string (nullable = true)
 |-- auth: string (nullable = true)
 |-- firstName: string (nullable = true)
 |-- gender: string (nullable = true)
 |-- itemInSession: long (nullable = true)
 |-- lastName: string (nullable = true)
 |-- length: double (nullable = true)
 |-- level: string (nullable = true)
 |-- location: string (nullable = true)
 |-- method: string (nullable = true)
 |-- page: string (nullable = true)
 |-- registration: long (nullable = true)
 |-- sessionId: long (nullable = true)
 |-- song: string (nullable = true)
 |-- status: long (nullable = true)
 |-- ts: long (nullable = true)
 |-- userAgent: string (nullable = true)
 |-- userId: string (nullable = true)

Чтобы очистить данные, мы проверяем наличие null, nan или пустых значений. Например. один урок из части понимания данных заключался в том, что поле artist отсутствует для действий пользователя, которые не связаны с воспроизведением музыки, а скорее с навигацией по меню.

Исследовательский анализ данных

Во-первых, на основе заданных записей журнала будет определена метка churn. В качестве индикатора мы используем событие Cancellation Confirmationв поле page.

Из 225 отдельных пользователей в очищенном наборе данных 52 ушли.

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

+-----+------------+
|churn|songs_played|
+-----+------------+
|    0|      191714|
|    1|       36394|
+-----+------------+
+-----+-----------+
|churn|songs_liked|
+-----+-----------+
|    0|      10692|
|    1|       1859|
+-----+-----------+
+-----+---------------+
|churn|songs_not_liked|
+-----+---------------+
|    0|           2050|
|    1|            496|
+-----+---------------+

Разработка функций

Затем мы создаем функции, которые обещают обучать наши модели. Мы делаем это для:

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

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

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

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

Из-за несбалансированного набора данных (группа тех, кто не отдает, в три раза больше, чем группа оттока), мы будем использовать показатель F1 в качестве нашей оценочной метрики. Это гармоническое среднее точности и отзыва.

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

Случайный лес

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

После 10-кратной перекрестной проверки модель Random Forest получает оценку F1 74,19% на проверочном наборе. Однако обратите внимание, что точность ниже, чем у F1-Score, что указывает на несбалансированный набор данных.

Логистическая регрессия

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

После перекрестной проверки модель логистической регрессии достигает 67,74% в баллах F1 и 54,71% в точности.

Настройка модели

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

maxDepthи numTreesпараметры модели Random Forest будут настроены.

  • maxDepth — это глубина каждого дерева решений в ансамбле. Чем глубже деревья, тем больше информации собирается для классификации, но это также может привести к переоснащению.
  • numTrees — это общее количество деревьев решений, которые нужно запустить в ансамбле. Значение по умолчанию — 20.

Окончательные показатели для настроенного классификатора Random Forest:

  • Оценка F1: 77,41%
  • Точность: 74,85%

Заключение

Настройка гиперпараметров с поиском по сетке действительно улучшила модель классификатора случайного леса на 3,8 % до общего балла F1 77,41 %.

По сравнению с моделью логистической регрессии с оценкой 67,74% модель случайного леса рекомендуется с точки зрения масштабирования алгоритма для большого набора данных объемом 12 ГБ.

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

Перспектива

Возможные улучшения перечислены ниже.

Попробуйте другие модели, такие как

  • GradientBoostedTreeClassifier
  • Наивный байесовский классификатор
  • Дерево решенийКлассификатор

Дальнейшая разработка функций

  • Относительные функции, например. (нравится / (нравится + не нравится))

Обширная настройка модели

  • Больше времени на обучение
  • Расширенные диапазоны параметров поиска по сетке