Как предсказать поведение клиентов в отношении ваших промо-акций: пример промо-акций Starbucks

В этом посте обсуждается набор данных Starbucks о смоделированном поведении клиентов. Этот пост будет разделен следующим образом:

  • Постановка проблемы. В этом разделе я расскажу об основной проблеме, затронутой в этой записи блога.
  • Метрики. В этом разделе я расскажу об основной метрике, на основе которой будет оцениваться эффективность прогностических моделей.
  • Исследовательский анализ данных (EDA). В этом разделе я укажу различные наборы данных, с которыми буду иметь дело. После этого я собираюсь обсудить каждый из них в отдельности, более подробно.
  • Моделирование данных. В этом разделе я создам модели машинного обучения на основе анализа, описанного в разделе EDA. Также в этом разделе будет обсуждаться, как повысить точность одной из моделей.
  • Заключение

И. Постановка проблемы

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

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

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

II. Метрики

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

III. Исследовательский анализ данных (EDA)

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

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

Вот полное описание их атрибутов

портфолио

- id (string) - offer id
- offer_type (string) - type of offer ie BOGO, discount, informational
- difficulty (int) - minimum required spend to complete an offer
- reward (int) - reward given for completing an offer
- duration (int) - time for offer to be open, in days
- channels (list of strings)

Профиль

- age (int) - age of the customer 
- became_member_on (int) - date when customer created an app account
- gender (str) - gender of the customer (note some entries contain 'O' for other rather than M or F)
- id (str) - customer id
- income (float) - customer's income.

Стенограмма

- event (str) - record description (ie transaction, offer received, offer viewed, etc.)
- person (str) - customer id
- time (int) - time in hours since start of test. The data begins at time t=0
- value - (dict of strings) - either an offer id or transaction amount depending on the record

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

III.I. Набор данных портфолио

Давайте сначала проверим набор данных.

portfolio.head()

Фрейм данных портфеля содержит 10 строк и 6 столбцов. Давайте проверим, есть ли у него NaN или нет.

portfolio.isna().sum()
==== OUTPUT ====
channels      0
difficulty    0
duration      0
id            0
offer_type    0
reward        0

Похоже, что в этом фрейме данных нет NaN. Это хорошее начало :) .

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

  • Переименуйте столбец id в offer_id.
  • Измените единицу измерения столбца «длительность» с дней на часы.
  • Переименуйте столбец «duration» в «duration_h», чтобы отразить новый характер столбца.
  • Нормализуйте функции «сложности» и «вознаграждения» с помощью MinMaxScaler.
  • Создайте фиктивные переменные из столбца «каналы».
  • Нормализуйте столбцы difficulty и reward.
  • Преобразуйте столбец offer_id в более читаемый идентификатор (например, числа: 1,2 и т. д.).
  • Замените offer type соответствующими целочисленными значениями следующим образом:
bogo == 1 
discount == 2 
informational == 3

После того, как я выполню соответствующую функцию (код будет доступен на GitHub в конце сообщения в блоге), вот краткий обзор фрейма данных:

III.II. Кадр данных профиля

Давайте сначала посмотрим на фрейм данных.

profile.head()

Фрейм данных профиля содержит 17000 строк и 5 столбцов. Давайте проверим NaN.

profile.isna().sum()
==== OUTPUT ==== 
age                    0
became_member_on       0
gender              2175
id                     0
income              2175

Построим распределение по возрасту:

Вот список настроек, которые нам нужно сделать:

  • Обработка столбца id.
  • Обработка столбца age.
  • Обработка столбца income.
  • Обработка столбца gender.
  • Обработка столбца became_member_on.

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

Также не забудьте удалить все NaN.

cleaned_profile_df.dropna(inplace=True)

III.III. Стенограмма кадра данных

Давайте посмотрим на фрейм данных.

transcript.head()

Фрейм данных стенограммы имеет 306534 строки и 4 столбца. Поскольку количество строк относительно велико, это намекает на долгое время выполнения при очистке данных (что было со мной). Давайте проверим NaN:

transcript.isna().sum()
==== OUTPUT ====
event     0
person    0
time      0
value     0

Это означает, что данные не содержат NaN.

Построим распределение всех типов предложений.

Вот список шагов обработки:

  • Предварительно обработать столбец person
  • Переименуйте столбец time
  • Предварительно обработайте столбец value
  • Предварительно обработайте столбец event
  • Предварительно обработайте столбец offer_id

Вот кадр данных после его обработки.

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

Вот посмотрите на окончательную форму final_df

Давайте проверим NaN

final_df.isna().sum()
==== OUTPUT ==== 
event                 0
customer_id           0
time_h                0
offer_id              0
amount                0
reward_x              0
difficulty            0
duration_h            0
offer_type            0
reward_y              0
channel_email         0
channel_mobile        0
channel_social        0
channel_web           0
gender             9587
age_group          9587
income_range       9587
membership_year    9587
member_type        9587

Итак, почистим.

final_df.dropna(how='any', axis=0, inplace=True)

Давайте ответим на три вопроса на основе приведенного выше анализа:

  • Каковы общие предложения для каждой возрастной группы?
  • Сколько клиентов присоединились к рекламной программе Starbucks?
  • Какой тип продвижения предпочтительнее для мужчин и женщин?

Вопрос 1. Каковы общие предложения для каждой возрастной группы?

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

Вопрос 2. Сколько клиентов присоединились к рекламной программе Starbucks?

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

Вопрос 3. Какой тип продвижения предпочтительнее гендерного?

Мы видим, что наиболее предпочтительным типом рекламных акций является BOGO.

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

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

В этом разделе мы создаем модели ML. Этот раздел разделен следующим образом:

  • Создайте training sets и testing sets, чтобы их можно было ввести в модели ML.
  • Создайте настоящие модели машинного обучения. Я выбрал следующие алгоритмы:
- Support Vector Machine (SVM)
- Logistic Regression
- Artificial Neural Networks (ANN)

IV.I. Создание Training Sets и Testing Sets

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

Переименуйте reward_x в obtained_reward

final_df.rename(columns ={'reward_x':'reward_obtained'}, inplace = True)

Давайте разделим final_df на матрицу X (т. е. матрицу признаков) и Y (т. е. целевую матрицу).

X = final_df[['time_h','offer_id','amount','reward_obtained','difficulty','duration_h','offer_type','gender','age_group','income_range', 'member_type']]
Y = final_df['event']

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

X_train, X_test, y_train, y_test = train_test_split(X, Y, random_state=40)

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

IV.II. Построение моделей машинного обучения

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

Я сделал 4 модели следующим образом:

  • SVM (ядро установлено на linear )
  • Логистическая регрессия
  • ИНС (неоптимизированная, имеет два скрытых слоя, каждый из которых содержит 1 нейрон)
  • ИНС (оптимизированная, имеет два скрытых слоя, каждый из которых содержит 7 нейронов)

Мы видим, что и SVM, и логистическая регрессия имеют точность 100% без какой-либо настройки. Однако неоптимизированная ИНС имеет плохую точность почти 60%. Однако, когда он был оптимизирован, он был частью как SVM, так и логистической регрессии.

Теперь давайте посмотрим на время строительства.

Мы можем сделать вывод, что хотя мы оптимизировали neural network, время его сборки исключительно больше, чем SVM и Logistic Regression. Таким образом, и Logistic Regression, и SVM могут быть хорошими кандидатами.

V. Заключение

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

В.И. Возможные подводные камни и как с ними бороться

Поскольку точность, полученная из training set, очень высока, мы можем столкнуться с проблемой переоснащения (т. е. когда модель не может обобщаться на популяцию и почти «запоминает» обучающую выборку). Один из возможных способов решить эту проблему — использовать regularization term, который помогает решить эту проблему.

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

В.II. Возможные улучшения

Вот список для оптимизации созданных моделей машинного обучения:

  • Мы можем использовать Regularization Term для решения проблемы переобучения.
  • Мы можем использовать Feature Engineering для оптимизации набора предикторов.
  • Мы можем использовать Ensemble Learning, например bagging, чтобы использовать не только алгоритмы обучения.

V.III. Размышления

Чтобы подойти к проблеме прогнозирования того, будет ли клиент только просматривать или завершать предложение, я использовал модели ML в качестве инструментов прогнозирования. Однако этому этапу предшествовала большая очистка и обработка данных, чтобы привести наборы данных в надлежащий вид. Мне понравилось работать над этим проектом (как и со всеми проектами Nano Degree).

Тем не менее, я обнаружил, что начало работы над ним немного сбивает с толку. Данные были в ОЧЕНЬ ПЛОХОЙ форме. Кроме того, поля не были ясны с первого взгляда. Однако в реальном мире такие наборы данных очень распространены, и моя работа как специалиста по данным (и инженера-программиста :) ) заключается в том, чтобы разобраться во всем этом.

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

V.IV. Заключительные мысли

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

VI. Подтверждение

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

Чтобы проверить код, нажмите здесь.