Введение

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

Sparkify – это воображаемый сервис потоковой передачи музыки Udacity, имитирующий реальный сервис потоковой передачи, такой как Spotify. Пользователи Sparkify могут транслировать музыку, используя бесплатный план подписки с рекламой или платный план подписки без рекламы. Помимо использования сервиса для прослушивания музыки, пользователи могут поднимать или опускать палец, добавлять песни в плейлисты или добавлять друзей. Пользователи могут изменить свой план подписки, перейдя с бесплатного на платный, перейдя с платного на бесплатный, или полностью прекратить использование службы, отменив. em> подписка.

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

Для нашего проекта доступно 3 набора данных с информацией журнала событий:

  • полный (большой) набор данных размером 12 ГБ, доступный в кластере Amazon EMR,
  • средний набор данных доступен в кластере IBM Watson,
  • мини (образец) набор данных доступен на локальном компьютере.

Мы будем использовать мини-набор данных, чтобы привыкнуть к нашим данным и выполнить всю необходимую подготовительную работу перед переходом в кластер Amazon EMR, где будет выполняться «настоящая» работа. Поскольку мы работаем с огромным объемом данных, мы будем использовать аналитический механизм Apache Spark для обработки больших наборов данных с языком запросов Spark SQL для обработки структурированных данных.

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

С точки зрения бизнеса слово отток используется для обозначения клиентов, которые отказываются от услуг компании в течение определенного периода времени. Компании стремятся определить потенциальных пользователей, которые могут уйти, до того, как они действительно покинут службу, чтобы принять меры для их удержания. По некоторым оценкам, привлечение нового клиента может стоить в пять или шесть раз дороже, чем удержание уже имеющихся (https://baremetrics.com/academy/churn).

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

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

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

Показатели

Выбор правильных показателей важен для оценки модели машинного обучения. В нашем полном наборе данных содержится 22 278 пользователей, из которых 5003 являются отмененными пользователями (22,46%). Если мы используем точность для измерения качества прогнозирования нашей модели, и наша модель идентифицирует каждого пользователя как не ушедший, мы достигаем точности 77,54%. что является довольно высоким значением для слепой модели, которая всегда предсказывает 0.

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

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

  • точность = 𝑇𝑃/𝑇𝑃+FP
  • отзыв = 𝑇𝑃/TP+FN

TP — это истинно положительные или правильно идентифицированные уволенные пользователи, FP — это ложные срабатывания или не ушедшие пользователи, ошибочно идентифицированные как удаленные пользователи, а FN являются ложноотрицательными или удаленными пользователями, ошибочно идентифицированными как неизмененные пользователи.

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

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

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

  • F1 = 2 ∗ точность ∗ полнота/(точность + полнота)

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

Цель проекта

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

Цель проекта — набрать 0,9 балла F1. Нас также устроит немного более низкое значение, но нас определенно не устроит значение ниже 0,8.

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

Сводка данных

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

  • размер: 125 МБ
  • количество строк: 286 500
  • количество пользователей: 225

Полный набор данных

  • размер: 12 ГБ
  • количество строк: 26 259 199
  • количество пользователей: 22 278:
  • 5003 отмененных пользователя
  • 5 103 пользователя с пониженной версией

Схема

Столбцы

  • исполнитель: исполнители песни. Выдается только при воспроизведении музыки (в событии NextSong).
  • firstName: имя пользователя.
  • пол: пол пользователя.
  • itemInSession: отсчитываемый от нуля индекс события журнала в сеансе.
  • lastName: фамилия пользователя.
  • length: продолжительность песни (в секундах).
  • level: уровень подписки пользователя.
  • местоположение: местоположение пользователя (включая город, штат).
  • method: метод http-запроса.
  • страница: тип взаимодействия с пользователем.
  • registration: отметка времени регистрации пользователя.
  • sessionId: идентификатор сеанса пользователя.
  • song: название песни.
  • status: код состояния ответа http.
  • ts: временная метка журнала событий.
  • userAgent: агент пользователя, используемый для доступа к службе потоковой передачи.
  • userId: идентификатор пользователя.

Отсутствующие значения

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

Нерелевантные столбцы

firstName и lastName не имеют отношения к нашему проекту, поскольку они не предоставляют никакой новой информации, которая еще не содержится в атрибуте userId.

Предварительный анализ (пример набора данных)

  • Общий период наблюдения: 1 октября и 3 декабря 2018 г.
  • Журналы по полу: 154 578 женщин и 123 576 мужчин.
  • Журналы по уровням подписки: 228 162 платных и 58 338 бесплатных журналов.
  • Журналы взаимодействия с пользователем: 228 108 взаимодействий с песнями и 50 056 взаимодействий другого типа (не песни):

  • Журналов на пользователя: среднее 1236,24, стандартное 1329,53, мин. 6, макс. 9632.

  • Распределение журналов по пользователям направо. Могут быть обнаружены некоторые экстремальные выбросы. В целом можно ожидать, что эти выбросы отрицательно повлияют на нашу статистическую модель.
  • Пользователи по сеансам. Распределение сеансов на пользователя аналогично распределению журналов на пользователя — смещено вправо. Неудивительно, что оба распределения имеют нижнюю границу, а данные с нижней границей склонны к искажению вправо.
  • Пользователи по полу: 104 пользователя женского пола и 121 пользователь мужского пола.
  • Пользователи по штатам: большинство пользователей из Калифорнии, 1/3 пользователей из Калифорнии, Техаса, Нью-Йорка, Нью-Джерси, Пенсильвании, Флориды.
  • Сеансы: в среднем 14 сеансов на пользователя, средняя продолжительность сеанса — 299,51 минуты.

Анализ оттока (пример набора данных)

У нас есть два типа удаленных пользователей: те, кто отменил подписку (отмененные пользователи — 52 пользователя), и те, кто перешел на более раннюю версию (пониженные пользователи — 49 пользователей). Оба класса оттока явно несбалансированы. Количество всех пользователей уже невелико, но с таким небольшим количеством удаленных пользователей будет очень сложно создать надежную статистическую модель, которая будет одинаково прогнозировать в случаях различных случайных разделений данных.

Разве не должно быть удобно объединить оба типа оттока в один тип оттока, чтобы получить менее несбалансированный класс оттока?

Если мы сделаем краткую статистику по распределению журналов по типам оттока, то заметим, что значения показывают огромные расхождения: отмененные пользователи имеют в среднем 863 журналы, пониженные пользователи создают гораздо больше журналов — в среднем 2177, что в 2,5 раза выше значения. Аналогичное поведение можно обнаружить и с другими статистическими значениями. Статистика количества журналов с использованием неагрегированных исходных данных — это самая основная статистика, которую мы можем сделать. Если два типа ушедших пользователей не имеют одинаковых базовых статистических данных, то весьма вероятно, что мы столкнемся с расхождениями на определенных уровнях агрегирования. Поскольку мы преследуем цель делать хорошие прогнозы, мы предпочитаем не объединять оба типа.

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

Общий статистический метод (GSM)

Чтобы оценить актуальность определенной функции для нашего набора функций, который будет смоделирован, мы выполним следующие 4 шага:

  1. Сначала мы определим функцию f, которая возвращает определенное статистическое f-значение для каждого пользователя.
  2. Затем определит групповую функцию g, которая возвращает определенную группу (агрегированную) значение g, например среднее или общее количество для группы оттока.
  3. На следующем шаге мы рассчитаем пропорции g-значений для каждой группы относительно суммы g-значений для обеих групп (или ratio r).
  4. На последнем шаге мы рассчитаем разницу коэффициентов дельта следующим образом:
  • Δ = r1 — r0

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

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

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

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

Мы не представляем здесь все функции. Пожалуйста, проверьте код моей записной книжки (https://github.com/amosvoron/sparkify/blob/master/Sparkify-modelling.ipynb) с полным списком протестированных функций.

Уровень журнала

  • LogCount —количество журналов на группу оттока.

  • MethodPutCount (НЕ ИСПОЛЬЗУЕТСЯ)количество методов PUT на группу оттока
  • Status200Count(НЕ ИСПОЛЬЗУЕТСЯ)статус http 200 count на группу оттока
  • Status307Count(НЕ ИСПОЛЬЗУЕТСЯ)количество HTTP-статуса 307 на группу оттока
  • Status404Count (НЕ ИСПОЛЬЗУЕТСЯ)количество HTTP-статуса 404 на группу оттока

Уровень пользователя

  • Пол —количество полов пользователя на группу оттока.

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

  • LevelPerDay(NOT SELECTED)количество уровней пользователя в день, на группу оттока

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

Уровень песни

  • SongCount —количество песен на группу оттока.
  • SongCountPerDay (NOT SELECTED) –количество песен в день для группы оттока.

  • SongCountPerDayOfWeek (NOT SELECTED) —количество песен в день недели для каждой группы оттока.

  • SongCountPerHourOfDay(NOT SELECTED)количество песен в час дня, на группу оттока

  • TotalSongLength —общая длина песни на группу оттока.
  • NonSongCount —количество событий страницы, не связанной с песней, на группу оттока.
  • UniqueSongCount —количество уникальных песен на группу оттока.

  • UniqueSongShare: доля уникальных песен среди всех песен в группе оттока.

Уровень сеанса

  • SessionCount —количество сеансов на группу оттока.

  • SessionCountPerDay: количество сеансов в день на группу оттока.
  • AverageSessionLength: средняя продолжительность сеанса на группу оттока.

  • AverageSessionGap —средний разрыв между сеансами на группу оттока.

Промежуток между сеансами – это период отсутствия активности пользователя между сеансами. Мы используем следующую формулу для расчета среднего разрыва сеанса на пользователя:

средний разрыв сеанса = (время наблюдения — время сеанса) / (счетчик сеансов — 1)

Дивидендом является общее время перерыва между сеансами на пользователя, а делителем — количество перерывов между сеансами на пользователя, равное общему количеству сеансов, уменьшенному на 1, при условии, что n сеансов имеют n1 промежутки.

Уровень страницы

Мы проверим дельта-значения для каждого события страницы, за исключением событий Отмена, Подтверждение отмены и Отправить переход на более раннюю версию. Причина, по которой мы исключаем события Отмена и Подтверждение отмены, заключается в том, что мы используем последнее для определения нашего ярлыка — это часть определения метки отмененных пользователей, а поскольку событие Cancel является его предшествующим событием, мы также должны исключить его. Событие Submit Downgrade используется для определения метки пользователей с пониженной версией. Поскольку мы решили не смешивать оба типа оттокаотмененные и пониженные пользователи, — мы предпочитаем не использовать какие-либо функции, являющиеся частью определение метки другого типа оттока.

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

  • PageCount — количество страниц на группу оттока — ВЫБРАНО: О нас, Не нравится, Прокручиваемая реклама, Добавить Друзья, Добавить в плейлист, Понизить версию, Ошибка, Главная

  • PageCountPerSessionHour –количество страниц за час сеанса на группу оттока — ВЫБРАНО: Ошибка, Настройки, Сохранить Настройки, Выйти, Понизить версию

  • PageCountPerHour — количество страниц в час на группу оттока — ВЫБРАННЫЕ: Прокручивать рекламу, Мне нравится, Обновить, Отправить обновление

  • PageCountPerDay — количество страниц в день на группу оттока. ВЫБРАННЫЕ: Добавить друга, Прокрутить рекламу, Мне нравится, Недурно

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

Обзор

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

  • Подмножество признаков, извлеченное из набора выбранных признаков — обычно мы начинали со всего набора признаков и, согласно результатам, полученным из подогнанных моделей, — если модель предоставляла такой вид информации — функции были дополнительно пересмотрены, рекомбинированы или отброшены.
  • Случайное начальное значение, которое определяет разделение данных — использовались 4 значения: 0, 5, 47, 99.
  • Метод машинного обучения — использовались 3 метода: Random Forest, GBTClassifier, LogisticRegression
  • Гиперпараметры. По возможности поиск по сетке с перекрестной проверкой использовался для настройки гиперпараметров модели.

Из-за большого количества упражнений модельная часть проекта была самой трудоемкой. Упражнения выполнялись в течение длительного периода времени — в течение нескольких недель — например:

  • Предварительные упражнения: мини-набор данных с гиперпараметрами по умолчанию, одно начальное число, различные наборы функций. Предварительные упражнения дали нам приблизительную оценку сделанного нами выбора признаков, чтобы подтвердить его или отбросить, заменить и добавить некоторые новые признаки, не соответствующие общему статистическому методу.
  • Упражнения по умолчанию: мини-набор данных с гиперпараметрами по умолчанию, одно начальное число, различные наборы функций. (Пожалуйста, проверьте блокнот Sparkify-modeling.ipynb для получения более подробной информации.)
  • Упражнения по перекрестной проверке: мини-набор данных, одно исходное значение, настройка гиперпараметров с перекрестной проверкой, единый набор функций, взятый из лучшей модели упражнения по умолчанию. (Пожалуйста, проверьте блокнот Sparkify-modeling.ipynb для получения более подробной информации.)
  • Исходные упражнения: мини-набор данных, несколько исходных значений (0, 5, 47, 99), лучшие гиперпараметры из упражнения перекрестной проверки. (Пожалуйста, проверьте блокнот Sparkify-modeling.ipynb для получения более подробной информации.)
  • Упражнения на кластере EMR (Amazon): большой набор данных, одно начальное число, один набор гиперпараметров (без перекрестной проверки), различные наборы функций:
  • Блокнот Sparkify-cluster-cancelled-feature-engineering.ipynb по разработке функций для отмененных пользователей.
  • Блокнот Sparkify-cluster-downgrade-feature-engineering.ipynb по разработке функций для пользователей с пониженной версией.
  • Скрипт Sparkify-cluster-cancelled-bestmodel.py, который использовался для подбора лучшей модели для отмененных пользователей.
  • Скрипт Sparkify-cluster-downgrade-bestmodel.py, который использовался для подбора лучшей модели для пользователей с пониженной версией.
  • Заключительное упражнение: мини-набор данных, одно начальное число, единый метод машинного обучения (GBTClassifier), настройка гиперпараметров с перекрестной проверкой. Выполняется на завершающем этапе написания этой статьи.

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

  • функция для разделения данных на подмножество обучения и тестирования
  • функция для создания объекта конвейера
  • функция для подгонки модели
  • функция для расчета показателей
  • функция для графического отображения важности признаков
  • функция для соответствия модели перекрестной проверки
  • функция для извлечения результатов перекрестной проверки

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

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

Пример (мини) набора данных

Мы предоставим 6 моделей, по 2 на каждый тип метода обучения, а также 2 модели перекрестной проверки:

Модель № 01

  • функций: 28
  • начальное значение: 0
  • метод: GBTClassifier
  • гиперпараметры: по умолчанию
  • Оценка F1: 0,878788

Перекрестная проверка на основе модели № 01

  • функций: 28
  • начальное значение: 0
  • метод: GBTClassifier
  • гиперпараметры:
  • — maxIter: [10, 20, 50, 200]
  • — максимальная глубина: [2, 5]
  • — maxBins: [32]
  • баллы:

Модель № 02 — лучшая модель CV GBTClassifier

  • функций: 28
  • начальное значение: 0
  • метод: GBTClassifier
  • гиперпараметры:
  • — макситер: 10
  • — максимальная глубина: 2
  • — maxBins: 32
  • Оценка F1: 0,907345

Модель № 03 — лучшая модель в целом

  • функции:17
  • начальное значение: 5
  • метод: случайный лес
  • гиперпараметры: по умолчанию
  • Оценка F1: 0,928398

Перекрестная проверка классификатора Random Forest

  • функции: 29
  • начальное значение: 0
  • метод: случайный лес
  • гиперпараметры:
  • — numTrees: [10, 20, 50]
  • — maxDepth: [4, 5, 6]
  • баллы:

Модель № 04 — лучшая CV-модель Random Forest

  • функции:29
  • начальное значение: 0
  • метод: случайный лес
  • гиперпараметры:
  • — количество деревьев: 20
  • — максимальная глубина: 6
  • Оценка F1: 0,912889

Модель № 05

  • функции:8
  • начальное значение: 5
  • метод: логистическая регрессия
  • гиперпараметры: по умолчанию
  • Оценка F1: 0,856190

Перекрестная проверка — на основе модели № 05

  • функции: 8
  • начальное значение: 0
  • метод: случайный лес
  • гиперпараметры:
  • — maxIter: [10, 20]
  • — regParam: [0.0, 0.1]
  • — elasticNetParam: [0,0, 0,5]
  • баллы:

Модель №06 — лучшая модель CV логистической регрессии

  • функции:8
  • начальное значение: 0
  • метод: случайный лес
  • гиперпараметры:
  • — макситер: 10
  • — regParam: 0,1
  • — elasticNetParam: 0.0
  • Оценка F1: 0,896016

Исходные результаты

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

Наш образец набора данных представляет только 1/100 данных из исходного набора данных, что является очень небольшой частью. Таким образом, каждое разбиение случайных данных генерирует данные для начального числа, где выбросы сильно влияют на модель и приводят к тому, что результаты существенно меняются при изменении начального значения. Хорошим примером является GBTClassifier с 19 функциями и гиперпараметрами по умолчанию, чья оценка F1 менялась на интервале [0,7572, 0,8960] при разных начальных значениях.

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

Дополнительная подгонка №1: попытка улучшить результаты лучшей модели с помощью корреляционного анализа

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

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

Зеленые зоны представляют собой положительную корреляцию: чем интенсивнее зеленый цвет, тем сильнее положительная корреляция между переменными. Точно так же красные зоны представляют отрицательную корреляцию: чем интенсивнее красный цвет, тем сильнее отрицательная корреляция между переменными. Ярко-серые цвета обозначают зоны с слабой корреляцией.

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

  • Понижение в час сеанса
  • SettingsPerSessionHour
  • Час выхода из сеанса
  • ThumbsDownPerHour
  • Роллобъявления в день

Мы можем найти две переменные с одинаковыми коэффициентами корреляции:

  • Количество журналов
  • NonSongCount

Эти две переменные имеют очень сильную связь друг с другом. Их коэффициент 0,99и коэффициенты с другими переменными очень похожи. Их сильное сходство также подтверждается средним значением коэффициента (среднее значение всех коэффициентов для данной переменной) — 0,442314 против 0,439024. Очевидно, что они являются зависимыми переменными. Нам не нужно использовать их оба — достаточно одного. И мы выбираем LogCount, так как он имеет немного более высокое среднее значение корреляции, в то время как выбор NonSongCount снимается.

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

Результаты F1 на посев:

  • начальное число 0: 0,90734
  • исходное число 5: 0,85365
  • начальное число 47: 0,89268
  • начальное число 99: 0,888966

Хотя мы не улучшили лучший результат модели (0,9284), нам удалось увеличить начальное среднее с 0,8794 (Случайный лес, 29 функций) до 0,8857 (11 функций). Мы также улучшили стандартное отклонение исходных результатов между обеими моделями: 0,0197 (11 функций) по сравнению с 0,0207 (29 функций). ).

Дополнительный вариант 2. Использование одной премиум-функции (AvgSessionGap)

Следующий тест дополнительной подгонки был проведен только с одной функцией — AvgSessionGap — с использованием метода случайного леса для всех исходных значений. Результат продемонстрировал важность премиального предиктора для типа оттока отмененных пользователей. Мы достигли среднего балла F1 при перекрестном отборе 0,878877 и в лучшем случае 0,919977 (посев 99)!

Этот результат можно сравнить с другим важным предиктором — RollAdvertCount, где мы получили 0,717864 (seed 99). Разница более чем в 0,2 балла F1 между предикторами на одном и том же семени очень показательна.

Сводка по образцу набора данных

  • Первоначальный выбор всех функций был сделан с использованием общего статистического метода, как описано выше. При предварительном тестировании некоторые признаки, подтвержденные общим статистическим методом, были отброшены и заменены признаками, значение дельты которых было ниже порога дельты.
  • Мы опробовали моделирование с несколькими подмножествами признаков с различным количеством и выбором (8, 17, 19, 20, 28, 29). Обычно следующее подмножество признаков выбиралось в соответствии с результатами оценки предыдущего подмножества признаков (важность признаков).
  • Были использованы три метода машинного обучения:
  • — Случайный лес
  • — GBTClassifier
  • — Логистическая регрессия
  • Лучшая модель получила оценку F1 0,9284 при использовании метода обучения Random Forest с гиперпараметрами по умолчанию.
  • Лучшие 3 функции:
  • — AvgSessionGap (лидирует во всех результатах с показателем важности более 0,20 в качестве нашей премиальной функции)
  • — ThumbsDownPerHour (отображается во всех списках пяти основных функций)
  • — RollAdvertPerHour

В заключительной части мы сделали две дополнительные примерки:

  • Попытка улучшить наши оценки с помощью корреляционного анализа. Хотя мы не улучшили результат лучшей модели, нам удалось увеличить начальное среднее значение с 0,8794 до 0,8857.
  • Перекрестные тесты с одной функцией (AvgSessionGap и RollAdvertCount) продемонстрировали важность премиального предиктора AvgSessionGap для типа оттока отмененных пользователей. в лучшем случае с 0,919977.

Полный набор данных в кластере

  • Произведен пересмотр значений дельты (повторная проверка данных). В то время как порог дельты для выборочного набора данных был установлен на 0,20 в кластере, мы установили его на 0,10. С более высоким порогом мы бы собрали слишком мало признаков.
  • Добавлены новые функции (переработка функций).
  • Включены оба типа оттока: отмененные и пониженные пользователи.
  • Существует очевидная разница между выбранными функциями для обоих типов оттока.

Тип оттока A: Отмененные пользователи

(Исходный блокнот: Sparkify-cluster-cancelled-feature-engineering.ipynb)

Выбранные функции (22 функции)

Модели в кластере

  • 14 моделей
  • 3 метода обучения: логистическая регрессия, случайный лес, GBTClassifier
  • Логистическая регрессия показала худшие результаты, чем два других метода: 0,774113 — лучший показатель F1 (с функциями выборочного набора данных). Мы решили отказаться от этого метода после второй подгонки с признаками большого набора данных, которые были не очень многообещающими: 0,750514.
  • Технически перекрестная проверка в кластере не проводилась, тем не менее, мы попробовали несколько гиперпараметров при подборе моделей.
  • Были протестированы различные подмножества функций.
  • В кластере использовалось только одно начальное число.

Показатели лучшей модели

  • Модель №10
  • F1: 0.899433
  • функций: 22
  • метод: GBTClassifier
  • гиперпараметры:
  • — макс.: 200
  • — maxDepth: 5

Важность функций лучшей модели

Дополнительная подгонка

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

Сводка по исключенным пользователям

Тремя наиболее важными функциями являются AvgSessionGap (Δ=-0,3078, важность=0,1149), NonSongCount (Δ=-0,1239, важность=0,0649), SessionCount. сильный> (Δ=-0,2989, важность=0,0608). Все 3 функции соответствуют дельта-порогу 0,10 в кластере.

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

Отток типа Б: пользователи с пониженной версией

(Исходный блокнот: Sparkify-cluster-downgrade-feature-engineering.ipynb)

Выбранные функции (28 функций)

Модели в кластере

  • 10 моделей
  • 2 метода обучения: случайный лес, GBTClassifier
  • Все два метода работали одинаково, достигая наилучшего значения показателя F1 более чем 0,82. Несколько лучшие результаты были получены при использовании метода Random Forest.
  • Перекрестная проверка в кластере не выполнялась.
  • Мы попробовали несколько значений гиперпараметров вместе с различными подмножествами функций.
  • В кластере использовалось только одно начальное число.

Показатели лучшей модели

  • Модель № 24
  • F1: 0.826829
  • функции: 15
  • метод: случайный лес
  • гиперпараметры:
  • — numTrees: 50
  • — maxDepth: 6

Сводка по пользователям с пониженной версией

Три наиболее важные функции: RollAdvertCount (Δ=-0,3726, важность = 0,1958), HomeCount (Δ=0,1708, важность = 0,1735), NonSongCount (Δ=0,3170, важность=0,1563). Все 3 функции соответствуют дельта-порогу 0,10 в кластере.

  • События страницы с наибольшим прогнозируемым весом: Прокручивать рекламу, Главная, Выйти, Мне нравится.
  • Что в наибольшей степени способствует прогнозированию пониженного пользователя:
  • — подверженность большему количеству рекламных событий в абсолютном значении, но меньшему количеству показов в час и за час сеанса
  • больше взаимодействий с главной страницей
  • больше действий, не связанных с песнями (действия, не связанные напрямую с потоковой передачей музыки)

Пожалуйста, проверьте блокнот Sparkify-cluster-results.ipynb для получения результатов по кластеру.

Окончательный вывод

Самое главное: мы достигли цели нашего проекта — достигли F1-score 0,9. Если быть точным, 0,8994 для кластера и 0,9284 для образца набора данных, только для отмененных пользователей.

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

Работа на кластере была отдельным миром по сравнению с тем, что мы делали на локальной машине. Мы пересмотрели выбор признаков из выборочного набора данных, чтобы использовать признаки, которые лучше всего подходят для данных в кластере. Подгонка кластера шла очень медленно, в среднем более 5 часов на модель. И все же это стоило сделать. Мы узнали, что достижение определенного уровня результата, такого как 0,85 от F1-оценки, не было слишком сложным, если функции были спроектированы и выбраны правильно, однако переход от 0,85 к >0,90 было намного сложнее. У нас сложилось впечатление, что чем больше мы приближались к желаемому результату, тем труднее было делать малейшие шаги вперед.

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

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

Если мы сравним 10 основных функций обоих типов оттока, мы заметим только 3 функции, общие для обоих типов: NonSongCount, RollAdvertCount, RollAdvertPerHour. Эти 3 функции составляют около 17 % важности для целевого пользователя, отказавшегося от подписки, и около 44 % важности для целевого пользователя, перешедшего на более раннюю версию. Средняя оценка F1 для отмененных пользователей составляет 0,8574 и 0,8189 для пользователей с более низким рейтингом, что делает классификацию первой цели немного лучше, чем классификацию второй. У нас нет четкого объяснения, откуда взялась эта разница. Причина в том, что цель удаленных пользователей отличается лучше от цели пользователей с более низким рейтингом — «это что-то в наших данных?» — или это потому, что мы упустили некоторые функции с большим весом, чтобы лучше отображать пользователей с пониженной версией?

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

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

Что можно улучшить

  1. Поскольку нам посчастливилось обнаружить премиум-функцию для отмененных пользователей, мы вполне могли не заметить некоторые функции аналогичной важности, которые остались нераскрытыми (или невыбранными). В частности, у пользователей с пониженным рейтингом отсутствуют некоторые предикторы, которые могли бы увеличить показатель F1 выше 0,85. Дельта-анализ предоставил нам функции, которые не все были включены в предварительные упражнения по моделированию, такие как SongCountPerDayOfWeek и SongCountPerHourOfDay из-за избытка функций, которые были изначально собраны. Мы могли бы потратить больше времени на предварительные тесты и уделить больше внимания окончательному выбору функций.
  2. Мы видели, как далеко может нас завести небольшое хорошо отобранное подмножество функций. С одним предиктором премиум-класса мы достигли 0,919977 в выборочном наборе данных и 0,869747 с 3 функциями в кластере. И для этих трех функций — AvgSessionGap, SessionCount, LogoutPerHour — мы не можем сказать, что это был оптимальный выбор. SessionCount — третья по важности функция, а LogoutPerHour — 11-я в лучшей модели кластера. Если бы мы использовали корреляционный анализ раньше, при разработке признаков, а не после того, как моделирование уже было выполнено, это могло бы помочь нам уменьшить количество признаков и найти менее качественные признаки, которые могли бы улучшить наши результаты.

Подробнее о проекте смотрите на моем github.