В своем проекте Udacity Data Scientist Capstone я использовал смоделированные данные из приложения вознаграждений Starbucks, чтобы предсказать склонность пользователя принять предложение.

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

В моем завершающем проекте я стремлюсь ответить на два основных бизнес-вопроса:

  1. Каковы основные факторы эффективного предложения в приложении Starbucks?
  2. Могут ли предоставленные данные, а именно характеристики предложений и демографические данные пользователей, предсказать, воспользуется ли пользователь предложением?

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

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

В этом завершающем проекте используются данные, предоставленные Udacity в рамках курса Data Scientist Nanodegree. Он содержит смоделированные данные, которые имитируют поведение клиентов в мобильном приложении Starbucks Rewards.

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

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

Как указано выше, формулировка проблемы, на которую я пытаюсь ответить, состоит в том, чтобы (1) обнаружить основные факторы эффективности предложения и (2) изучить, можем ли мы предсказать, примет ли пользователь предложение.

Представленные данные состоят из 3 наборов данных:

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

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

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

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

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

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

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

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

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

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

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

При этом я объясню свой проект в следующих разделах:

  1. Исследование данных: я изучаю атрибуты предоставленных данных и выбираю подход к предварительной обработке данных для моделирования.
  2. Предварительная обработка данных. В этом разделе я проделал сложную очистку данных и разработку функций, чтобы подготовить данные для моделирования.
  3. Реализация модели. Я реализовал свои 3 модели и усовершенствовал реализацию модели, учитывая производительность модели в каждой версии и выбирая лучшую модель на основе результатов.
  4. Побочное исследование — после реализации модели я изучил некоторые альтернативные подходы к моделированию данных с некоторыми дополнительными моделями, как указано выше. Я также провел дополнительный исследовательский анализ данных, чтобы извлечь дополнительные сведения из предоставленных данных.
  5. Заключение — мои последние мысли о проекте и некоторые размышления о том, как я мог бы улучшить анализ данных и реализацию моделирования.

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

Часть 1. Исследование данных

а. Данные портфеля предложений

Согласно информации, предоставленной Udacity, схема выглядит следующим образом:

portfolio.json

  • id (string) — id оффера
  • offer_type (string) — тип предложения т.е. BOGO, скидка, информационное
  • трудность (целое число) — минимальные затраты, необходимые для выполнения предложения.
  • вознаграждение (int) — вознаграждение за выполнение предложения
  • продолжительность (интервал) -
  • каналы (список строк)

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

  • BOGO — купи один, получи один бесплатно
  • Скидка — скидка при покупке
  • Информационная — предоставляет информацию о продуктах

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

Сделав снимок данных, я отметил некоторые ключевые элементы для очистки данных на этапе предварительной обработки. Из их:

  • Разверните столбец channel позже во время предварительной обработки, чтобы он стал категориальными переменными в моем наборе данных.
  • Масштабирование функций — масштаб каждого из них различен, например, difficulty в долларах, а duration в днях.
  • Без нулевых значений мы можем оставить все как есть.

б. Демографические данные

Демографические данные для клиентов представлены в наборе данных profile. Схема и переменные следующие:

profile.json

  • age (int) — возраст клиента
  • стал_member_on (целое число) — дата, когда клиент создал учетную запись приложения.
  • гендер (str) — пол клиента (обратите внимание, что некоторые записи содержат «O» вместо M или F)
  • id (str) — идентификатор клиента
  • доход (float) — доход клиента

Это также относительно просто, так как содержит демографический профиль клиента.

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

  • Нулевые значения в столбцах gender и income — их нужно отбросить, если они не занимают значительную часть набора данных.

в. Транзакционные записи

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

транскрипт.json

  • event (str) — описание записи (т. е. транзакция, полученное предложение, просмотренное предложение и т. д.)
  • person (str) — идентификатор клиента
  • time (int) — время в часах. Данные начинаются в момент времени t=0
  • value — (dict of strings) — либо идентификатор предложения, либо сумма транзакции в зависимости от записи

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

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

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

д. Определение подхода к предварительной обработке данных для модели

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

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

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

Мы знаем, что существует 4 типа событий: offer completed, offer received, offer viewed и transaction. Но наши данные показывают, что у нас нет никакого offer_id, связанного с transactions, потому что они не записаны в данных расшифровки событий. Таким образом, первая цель предварительной обработки данных — определить методологию присвоения offer_id конкретным транзакциям.

Кроме того, мы также знаем, что BOGO и предложения скидок имеют событие offer completed, когда предложения завершены. Однако в информационных предложениях это событие не связано. Таким образом, мы также уточняем подход к определению эффективного предложения следующим образом:

Для BOGO и предложения со скидкой эффективное предложение будет определено, если следующие события будут записаны в правильной последовательности во времени:

offer received -> offer viewed -> transaction -> offer completed

Между тем, для информационного предложения, поскольку с ним связано offer completed событие, мне придется определить транзакции как конверсию в эффективное предложение:

offer received -> offer viewed -> transaction

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

а. Назначение идентификаторов предложений транзакциям

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

  1. Люди, которые находятся под влиянием и успешно конвертируются — эффективные предложения:
  • предложение получено-> предложение просмотрено-> транзакция-> предложение завершено (BOGO/предложения со скидками)
  • предложение получено -› предложение просмотрено -› транзакция (информационные предложения — должно быть в пределах срока действия предложения)

2. Люди, которые получили и просмотрели предложение, но не конвертировали его — неэффективные предложения:

  • предложение получено -> предложение просмотрено

3. Люди, которые покупают/заполняют предложения независимо от того, знают ли они о каких-либо предложениях:

  • сделка
  • предложение получено -› транзакция -› предложение завершено -› предложение просмотрено
  • транзакция -> предложение получено -> предложение завершено -> предложение просмотрено
  • предложение получено -› транзакция -› предложение просмотрено -› предложение завершено
  • полученное предложение -› транзакция (информационные предложения)
  • полученное предложение -> транзакция -> просмотренное предложение (информационные предложения)

4. Люди, которые получили предложения, но не предприняли никаких действий:

  • предложение получено

Для людей из группы 2 мне нужно было бы проверить, есть ли события, где есть событие offer received и offer viewed, но нет события-конверсии, т.е. offer completed или transaction - это случаи неэффективных предложений.

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

Разделение конверсий для эффективных предложений (группа 1) и людей, которые покупают/совершают предложения независимо от осведомленности о каких-либо предложениях (группа 3), особенно сложно. Для людей из группы 3 конверсия считается недействительной (то есть не успешной конверсией из предложения), если offer completed или transactionпроисходит до offer viewed. Также могут быть сценарии, когда offer completed происходит после просмотра предложения, но транзакция была совершена до просмотра предложения. В этом случае предложение может быть завершено, но это также недействительная конверсия.

Определение целевой переменной effective offer:

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

Мы знаем, что нашей целевой переменной effective_offer=1 будут клиенты из группы 1, но существует множество неэффективных определений предложений для групп 2–4.

Так что же мы определяем как неэффективное предложение? Как уже было сказано выше, группа 2 подпадает под наше определение неэффективного предложения; когда пользователь знает о предложении, но предложение неэффективно, поскольку не превращает пользователя в покупателя. Таким образом, группу 2 можно определить как нашу целевую переменную effective_offer=0.

А как насчет группы 3 и группы 4? Группа 3 состоит из пользователей, которые, возможно, получали предложения, но все равно совершили бы покупку. С точки зрения бизнеса, мы не хотели бы отправлять им какие-либо предложения.

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

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

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

Таким образом, любой уникальный person-offer_id, принадлежащий к группе 1, может рассматриваться в нашей целевой переменной effective_offer=1 group.

Между тем, группа 2 находится в нашей целевой переменной effective_offer=0 group. Для клиентов в группах 3 и 4 я отменяю их приоритет для реализации модели, но проведу некоторый исследовательский анализ позже в части 4.

Таким образом, я создал набор данных для каждого типа предложения, состоящий как из эффективных, так и из неэффективных предложений, добавив вместе наборы данных клиентов группы 1 и группы 2, и успешно подготовил целевые переменные для наших наборов данных BOGO и скидок.

Между тем, в частности, для информационных предложений, прежде чем мы сможем пометить колонку эффективных предложений, есть дополнительное соображение — действительность предложения. Это связано с тем, что событие конверсии является не offer completedсобытием, а transaction.

Для информационных предложений duration предложения можно рассматривать как продолжительность влияния. Следовательно, мы можем сделать предположение, что предложение следует считать эффективным только в том случае, если оно находится в пределах duration предложения.

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

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

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

д.и. became_member_on столбец, который нужно спроектировать

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

Таким образом, я извлек срок членства каждого человека в днях из столбца became_member_on, используя 2018 год в качестве текущего года.

d.ii. Количество полученных предложений

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

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

d.ii. Разделение поведения пользователей по транзакциям

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

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

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

Логика состоит в том, чтобы задаться вопросом, есть ли какой-то базовый уровень расходов для пользователей, на которых сильно влияют определенные предложения (в группе 1) и группе 2, и есть ли у этого базового уровня «недействительных транзакций» некоторая предсказательная сила, которая может прогнозировать склонность пользователя принять предложение.

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

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

Из-за разреженности вопрос о целесообразности включения этого столбца amount_invalid в модель является спорным. Поскольку он настолько «разреженный», в конце концов, в нем может быть не так много информации. Я планирую снова оценить эту функцию позже, на этапе реализации модели. На данный момент я решил заполнить отсутствующий столбец amount_invalid 0, так как это может означать, что только 4% от общего числа пользователей склонны совершать покупки без предложений; остальные 96% купят, только зная о текущем предложении.

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

д. III. Время, прошедшее между полученными предложениями

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

Часть 3: Реализация

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

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

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

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

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

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

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

а. Реализация модели

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

Я выполнил обычные необходимые шаги для моделирования:

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

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

Я использовал классификатор DecisionTree в качестве базовой модели и классификатор случайного леса со случайно назначенными параметрами для сравнения производительности.

и.и. BOGO предлагает модель

Точность модели случайного лесного классификатора (RF) фактически немного превосходит модель классификатора дерева решений (DT), но в целом производительность обеих моделей примерно одинакова (82,14% против 81,77% соответственно с точки зрения точности). Точность для первой попытки неплохая, более 80%. Я постараюсь настроить модель дальше, чтобы получить лучшую точность.

Однако с точки зрения оценки F1 обе модели ниже 80%, при этом модель случайного леса работает хуже по сравнению с классификатором дерева решений: 75,91% против 79,63%. Чтобы проанализировать это, мы должны обратиться к формуле для точности, отзыва и оценки F1:

Отзыв, или чувствительность, или TPR (истинно положительный показатель):

Согласно документации sklearn, отзыв — это интуитивно способность классификатора находить все положительные образцы.

Количество элементов, правильно идентифицированных как положительные, из общего числа истинно положительных результатов: Истинные положительные результаты / (Истинно положительные результаты + Ложноотрицательные результаты)

Точность:

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

Количество элементов, правильно идентифицированных как положительные, из общего числа элементов, идентифицированных как положительные: истинно положительные / (истинно положительные + ложноположительные)

Оценка F1:

Поскольку моя оценка F-бета равна F1 с бета = 1, я придаю весу полноту и точность как одинаково важные.

Формула задается гармоническим средним значением точности и полноты: F1 = 2*точность*отзыв/(точность + отзыв)

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

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

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

Учитывая этот случай, я все равно выберу модель RF.

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

a.ii. Модель предложения скидок

Я повторяю те же шаги, что и выше, но с набором данных offer_discounts.

На этот раз модель классификатора случайного леса также имеет лучшую производительность по сравнению с классификатором дерева решений с точки зрения точности (87,23% против 86,72%), а показатель F1 также ниже (81,43% против 82,87%).

Оценка F1 для этих моделей в целом ниже по сравнению с оценкой точности. Это может указывать на то, что в некоторых случаях обе модели ошибочно классифицируют отрицательные случаи (efficient_offer = 0). Опять же, меня это не слишком беспокоит, так как меня больше интересует модель, точно предсказывающая положительные случаи, поэтому я бы предпочел использовать модель с более высокой точностью, где показатель F1 для случаев effective_offer=1 выше, для которых наш классификатор RF имеет лучшую производительность (0,9317). против 0,9280).

а.iii. Модель информационных предложений

Повторяя описанные выше шаги для набора данных offers_info:

Производительность этих моделей хуже по сравнению с двумя другими наборами данных с точностью ниже 80% для обеих моделей, но модель RF по-прежнему работает лучше. Оценка F1 также хуже: 67,54% RF Classifier, хуже, чем у модели DT (68,66%).

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

б. Уточнение

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

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

Я решил провести GridSearch, чтобы определить оптимальные параметры модели.

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

Для БОГО:

Когда я перезапустил модель для набора данных BOGO с оптимальными параметрами, я получил следующие результаты:

Сравнение с первой моделью:

Точность модели RF немного увеличилась — с 82,14 % до 82,51 %, а показатель F1 увеличился с 75,91 % до 77,64 %. Это хорошее увеличение производительности, но минимальное, что указывает на то, что, возможно, мало что можно сделать для повышения производительности модели с настройкой параметров.

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

Для скидки:

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

Реализация модели с этими параметрами позволила получить следующие результаты:

Точность модели немного увеличилась, с 87,23% до 87,47%, а показатель F1 улучшился с 81,43% до 82,06%. Хорошо, что теперь и точность, и оценка F1 для модели RF лучше, чем для модели DT.

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

Для информационных предложений:

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

Снова мы видим некоторое улучшение точности модели RF с 75,09% до 75,30% и небольшое увеличение оценки F1 с 67,54% до 67,78%. Это улучшение минимально, поэтому мы стараемся улучшить выбор функций модели.

b.ii Удаление разреженных функций, например. amount_invalid

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

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

Точность модели и оценка F1 действительно улучшились, поэтому я не буду использовать функцию amount_invalid в своей модели.

Точность модели фактически увеличилась, а модель F1 осталась прежней. В этом случае я также удалю функцию amount_invalid для модели скидок.

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

б. III. Удаление одного уровня фиктивных переменных/горячее кодирование

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

Тем не менее, есть некоторые споры о том, следует ли это делать или нет. Согласно некоторым статьям (например, здесь ), обычно не рекомендуется кодировать категориальные переменные, поскольку они будут генерировать разреженные матрицы, что приведет к:

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

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

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

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

Я пока оставлю в стороне модели BOGO и дисконт, так как остался доволен работой модели.

б. IV. Использование полиномиальных функций

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

Мы видим, что производительность модели RF немного снизилась. Поэтому, возможно, было бы лучше оставить модель как есть. Для информационных предложений приемлема максимальная точность 75,30%, хотя она не так высока, как BOGO или предложения со скидками. В конце концов, мы уже включили некоторые предположения о «влиянии» предложения на основе продолжительности.

Построение графика обучения и точности тестирования для информационных моделей RF на данный момент дает следующую диаграмму:

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

Я могу еще больше повысить точность и производительность информационной модели, используя информационную модель RF 5, но добавляя больше данных, как мы уже отмечали, набор данных для набора данных offers_info вдвое меньше, чем наборы данных BOGO и Discount. Следовательно, в конечном счете, с большим количеством данных и с настройкой производительности, удалением ненужных переменных и преобразованием функций, с большим количеством данных я мог бы в конечном итоге получить производительность модели, возможно, выше 80%.

b.iv. Обсуждение лучших моделей и важности функций

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

#get best model overall for bogo,discount and info offers
best_model('bogo').append([best_model('discount'),best_model('info')]).transpose()

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

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

Для модели BOGO:

Для дисконтной модели:

Для информационной модели:

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

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

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

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

Часть 4: Побочное исследование

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

Ранее мы определили тех, кто входит в группы 3 и 4, как людей, которые совершат покупку независимо от просмотра каких-либо предложений. Теперь мы можем провести предварительный анализ, чтобы увидеть, из какой демографической группы состоит эта группа пользователей.

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

Было бы интересно посмотреть, как люди в группах 3 и 4 отличаются от людей в группах 1 и 2, поэтому я решил сравнить все 3.

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

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

Сравнивая размеры трех групп, мы видим, что группа 1 является самой большой, а группа 2 — самой маленькой, что неудивительно, поскольку мы видели, что классы в наших наборах данных были несбалансированы в пользу положительных классов (т.е. effective_offers=1). Между тем для людей в группах 3 и 4 также имеется довольно значительное количество людей, большее, чем количество людей во 2 группе.

a.ii. Изучение демографических характеристик

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

Во-первых, мы можем исследовать распределение доходов между тремя группами.

В трех сегментах большинство людей попадают в средний диапазон доходов (50–100 тысяч). Распределение доходов между тремя сегментами относительно одинаково.

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

Группа 2 — это люди, которые вообще не тратили, так как предложения для них оказались неэффективными, поэтому их нет на графике. Но для групп 1 и 3+4 мы видим, что сумма расходов относительно одинакова, за исключением того, что люди из группы 1 тратят немного больше. Этого следовало ожидать, поскольку мы могли ожидать, что предложения стимулировали их покупать больше, следовательно, их общие расходы увеличились.

Распределение срока членства также выглядит схожим между 3 сегментами: у большинства людей срок пребывания в должности составляет от 0 до 700 дней. Похоже, что различий в демографических характеристиках между тремя группами не так много, по крайней мере, в представленных текущих данных.

б. Потенциальная универсальная модель

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

После инициализации и запуска модели я проверил производительность всех трех ранее созданных моделей по сравнению с моделью «все в одном».

Сравнивая производительность 3 лучших моделей для каждого типа предложения с моделью «все в одном», мы видим, что модель «все в одном» не так хороша, как модели RF bogo и модели скидок, и немного лучше, чем информационная модель. . Вероятно, это связано с тем, что информационная модель снижает производительность, что приводит к снижению точности модели «все в одном». Я подозреваю, что если бы мы разбили производительность модели «все-в-одном» только на ее способность прогнозировать эффективность типов информационных предложений, она также была бы хуже, чем ее производительность, прогнозирующая два других типа.

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

Следовательно, я бы предположил, что 3 отдельные модели более полезны.

в. Учитывая эффективное предложение, можем ли мы предсказать, сколько кто-то потратит?

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

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

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

Часть 5: Заключение

В целом, этот проект показался мне сложным, в основном из-за структуры данных в наборе данных transcript. Я начал с двух бизнес-вопросов:

  1. Каковы основные факторы эффективного предложения в приложении Starbucks?
  2. Могут ли предоставленные данные, а именно характеристики предложений и демографические данные пользователей, предсказать, воспользуется ли пользователь предложением?

а. Отражение

и.и. Результаты ответа на вопрос 1

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

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

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

a.ii. Результаты ответа на вопрос 2

Мое решение использовать 3 отдельные модели для прогнозирования эффективности каждого типа предложений оказалось с хорошей точностью для моделей BOGO и моделей скидок (82,83% для BOGO и 87,35% для скидок), но чуть менее точно для информационных предложений (75,3%). . Тем не менее, я бы счел 75% приемлемыми в бизнес-среде, что касается информационных предложений, для информирования пользователей о продукте не требуется никаких затрат.

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

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

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

б.и. Платформа атрибуции для назначения offer_id для транзакций

Чтобы ответить на вопрос 1, мне нужно было сначала определить, что означает «эффективное предложение», используя записи о транзакциях. Это оказалось самой сложной частью проекта. Мне нужно было определить воронку того, как будет выглядеть эффективная конверсия, поскольку у нас были данные как об эффективных, так и о неэффективных конверсиях. Таким образом, я разработал модель атрибуции для событий конверсии (события offer completed и transaction) на основе событий, которые произошли ранее для каждого человека.

В итоге мне пришлось разделить пользователей на 4 разных пула в зависимости от их действий в данных расшифровки:

  • Группа 1: Люди, на которых повлияли предложения и, таким образом, покупают/завершают предложение (успешная/эффективная конверсия предложения).
  • Группа 2: люди, которые получают предложение, но не подвергаются влиянию и, следовательно, не совершают конверсии (неэффективная конверсия предложения).
  • Группа 3: люди, у которых есть конверсионные события, но на которые на самом деле не повлияло предложение.
  • Группа 4: люди, которые получают предложения, но не просматривают и не предпринимают никаких действий.

Даже после разделения групп было сложно выделить людей в группу 3 на основе данных о транзакциях. Мне нужно было определить пространство событий, в котором будет происходить правильная последовательность событий, прежде чем я смогу назначить идентификатор предложения для транзакций (у которых не было offer_id), по сути, спроектировав окно атрибуции на основе события/последовательности.

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

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

Я решил заняться базовым проектированием функций, так как обнаружил, что при моей первой попытке в этом проекте модель немного не подошла, поэтому позже я добавил раздел проектирования функций. Это немного улучшило производительность модели, а функция member_tenure, которую я разработал на основе столбца became_member_on, оказалась наиболее важной переменной-предиктором.

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

б.iii. Решения по внедрению модели

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

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

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

b.iv. Изучение демографических данных различных групп клиентов

Мне было любопытно узнать, каковы характеристики групп 3 и 4, то есть клиентов, на которых предложение вообще не влияет. Однако, сравнив их характеристики с группами 1 и 2, я не увидел существенных различий в их демографии.

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

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

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

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

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

в. Последние мысли

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

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

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

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

https://github.com/esridhar126/Data-scientist-capstone-project