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

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

Благодаря современным приложениям и дизайну сервисы, которые не могут быстро адаптироваться к потребностям своих клиентов, рискуют уступить их конкурентам. Для многих предприятий и инвесторов отток клиентов — важная проблема, которую необходимо не только измерять, но и активно решать, чтобы обеспечить ценность для клиентов и доход для бизнеса. Этот проект от Udacity Data Scientist Nano Degree направлен именно на решение этой проблемы. Код можно найти здесь, в моем репозитории github.

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

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

Компания по потоковой передаче музыки под названием Sparkify предоставляет миллионам пользователей возможность ежедневно транслировать музыку по своему выбору. Чтобы использовать эту услугу, пользователь может зарегистрироваться с использованием платной или бесплатной подписки. Хотя выборка данных, с которой мы работаем в этом конкретном проекте, очень мала (более крупный набор данных также доступен через Udacity), доля отмен подписки очень высока, что приводит к 25% потерям в доходах от подписки. Для нашей задачи мы смотрим на данные о кликах, чтобы определить, измерить и спрогнозировать отток клиентов, чтобы создать ценность для бизнеса.

Стратегия

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

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

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

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

Данные Понимание

Примечание. У нас есть данные о событиях объемом 12 ГБ, которые хорошо подходят для распределенного программирования. Поэтому мы будем использовать Apache Spark для управления нашими данными. Чтобы исследовать данные по мере написания нашей базы кода, мы сосредоточимся на гораздо меньшем наборе данных размером 134 МБ, чтобы тот же код можно было запустить на большем наборе данных.

В наших данных собрано 286 500 событий в период с 1 октября 2018 г. по 3 декабря 2018 г. Сначала мы смотрим на нашу входную схему:

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)

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

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

После очистки и переформатирования наших полей даты у нас осталось:

  • 225 относительно новых пользователей, зарегистрировавшихся в марте в начале года
  • 2312 сеансов
  • 278154 события

Что мы подразумеваем под оттоком?

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

Всего ежедневных событий за октябрь и ноябрь

Гендерное влияние на отток клиентов

Продолжая наше исследование, мы рассмотрим гендер и его влияние на отток.

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

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

Здесь мы суммируем данные на пользовательском уровне со столбцом метки, содержащим 1, если они изменились, или 0, если они не изменились. Агрегируя данные, мы используем входные столбцы для создания следующих функций для каждого клиента:

  • Всего дней на Sparkify
  • Всего посещенных уникальных страниц
  • Всего событий
  • Всего артистов услышали
  • Всего прослушано уникальных песен
  • Средняя длина
  • Минимальная длина
  • максимальная длина
  • Уровень подписки — платный или бесплатный
  • Всего событий следующей песни
  • Всего событий "палец вверх"
  • Всего неудовлетворенных событий
  • Всего событий настроек
  • Всего событий добавления друзей
  • Всего добавить в плейлист событий
  • Всего о событиях
  • Всего ошибок
  • Всего событий помощи
  • Дней между первым последним событием
  • Пол
  • Дней с момента регистрации — во время события зафиксировано первое событие.

Наряду с этим у нас есть «userId» и «churned» в качестве столбца метки.

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

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

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

1- Категориальные столбцы должны быть представлены их числовым индексом

2- Все признаки должны быть собраны в вектор признаков и

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

MLlib предоставляет классную функцию для инкапсуляции этих преобразований в поэтапный конвейер с помощью… Piplines()! Сначала мы создаем индексаторы пола и подписки, а затем аналогичным образом создаем векторный ассемблер и стандартный масштабатор, каждый из которых может выполняться в одном конвейере, используя:

data_prep_pipline = Pipeline(stages=[gender_indexer, subcription_indexer, ассемблер, масштабатор])

scaled_indexed_df = data_prep_pipline.fit(df).transform(df)

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

Показатель

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

Базовые модели

После последнего шага наш входной набор данных готов к использованию для обучения. Мы начинаем с использования 3 моделей: логистическая регрессия, случайный лес и деревья с градиентным усилением с параметрами по умолчанию. Мы снова будем использовать объект Pipeline для встраивания модели и ее выполнения. После запуска трех базовых моделей мы получаем следующие оценки f1:

Судя по базовым моделям, деревья с градиентным усилением показали наилучшую производительность с показателем f1 0,83 в этой итерации.

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

Настройка

Мы будем использовать модель деревьев с градиентным усилением для дальнейшей оптимизации оценки f1 с использованием сетки параметров и перекрестного валидатора. Параметры, используемые в карте параметров для нашей настроенной модели GBT: maxDepth: [2,5,10], maxBins: [5,10], maxIter: [5,10,50]

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

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

Результаты и оценка

Лучшей моделью для этой проблемы с использованием показателя f1 была модель повышения градиента с показателем 0,83.

GBT с параметрами по умолчанию (лучшая модель)

Оценка f1: 0,83

Параметры:maxBins: 32, maxDepth: 5 и maxIter: 20.

Важность функции:

GBT с настройкой параметров

Оценка f1:0,77

Параметры:maxBins: 10, maxDepth: 2 и maxIter: 5.

Важность функции:

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

Развертывание

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

Одно выполнение для всего набора данных объемом 12 ГБ

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

Прогнозирование событий в реальном времени

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

Запланированные пакетные прогнозы

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

Вывод

Подводя итог, хочу сказать, что проект Sparkify Capstone и весь курс Udacity Nanodegree стали отличным способом обновить концепции науки о данных и глубже погрузиться в интересующие их области. В этом проекте мы начали с открытого вопроса о том, можем ли мы предсказать отток, чтобы помочь компаниям лучше удерживать клиентов. Нам предоставили необработанные данные о взаимодействии, которые мы очистили, проанализировали и создали из них ценные функции. Вначале потребовалось некоторое время, чтобы привыкнуть к pyspark и разобраться в предоставленных данных. Тем не менее, использование нескольких простых столбцов для создания комплексного решения было одной из лучших частей этого проекта. Эти данные можно использовать для создания еще большего количества функций на более детальном уровне, например. предсказание того, уйдет ли пользователь в следующем месяце, неделе или даже в день. Документацию и код можно найти в репозитории github, где можно делать дальнейшие итерации.

Весь код, за исключением нескольких визуализаций, написан с использованием pyspark, поэтому затем код может быть выполнен в распределенной среде с 12 ГБ данных (и большой вычислительной мощностью для сетки параметров!),