Этот вызов является одним из финальных проектов курса Udacity Data Science Nano Degree.

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

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

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

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

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

Начнем с обзора данных и подготовки.

Есть три набора данных:

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

Портфолио

Набор данных содержит информацию о предложениях. Есть 10 различных предложений:

  • 4 BOGO (купи один, получи один бесплатно)
  • 4 Скидка
  • 2 Информационная

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

Профиль

Здесь у нас есть информация о доходах, возрасте, поле и дате создания учетной записи Starbuck клиентов. Всего 17 000 клиентов.

2 175 клиентов не имеют информации о своем поле и доходах. С возрастом они также имеют странное значение –118. Мы можем рассматривать их как особую группу клиентов и наблюдать за их поведением отдельно.

Без этой группы с отсутствующей информацией большинство клиентов составляют мужчины (57,2%). Женщины составляют 41,3%, а 1,43% относятся к категории «другие».

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

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

По возрасту:

Все три пола обычно распределяются с пиком около 55 лет. Есть некоторые отклонения для «женского» и, особенно, для «мужского» пола в начале 20-летнего возраста.

По доходу:

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

Расшифровка

Этот набор данных содержит информацию о различных действиях клиентов, например: полученное предложение, просмотренное предложение, завершенное предложение и транзакция. Каждая запись имеет время (в часах от 0 до 714, что эквивалентно 30 дням), уникальный клиент и идентификатор предложения (для записей статуса предложения). Для «предложения выполнено» у нас также есть информация о «вознаграждении» — сумме, которую клиент дал за выполнение предложения. Для транзакций есть только информация о сумме. Здесь нет пропущенных значений.

Я преобразовал поле «время» в формат DateTime с начальной точкой «01.01.2019 00:00:00». К сожалению, у нас нет информации о точной дате и времени начала кампании. С помощью этой информации мы могли бы получить дополнительную информацию о времени суток и днях недели, используемых различными группами клиентов.

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

Количество строк в этом наборе данных выглядит разумным. Наибольшее количество строк — транзакции — 138’953. Следующим идет «предложение получено» — 76 277 записей, когда клиент получил предложение в своем приложении. Меньшее число — «предложение просмотрено» — 57 725 записей, так как не все полученные предложения были просмотрены покупателями. Наименьшее число — 33 579 — «предложение завершено», потому что не все просмотренные предложения были завершены.

Чтобы проанализировать поведение клиентов в целом, я суммировал транзакции на человека и добавил общую сумму, количество транзакций, среднюю транзакцию и количество посещений (уникальных дней). Эту информацию я добавил к информации о клиентах в наборе данных Pofile_cleaned.

Преобразование данных

Выделяют 3 основных этапа жизненного цикла предложения:

1) Предложение получено

2) Предложить вид

3) Предложение завершено

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

1) Предложение получено, но не просмотрено и не завершено.

2) Предложение получено, не просмотрено, а выполнено.

3) Предложение получено, просмотрено, но не выполнено.

4) Предложение получено, просмотрено и завершено.

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

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

When_viewed():

- Для каждой записи в наборе данных offer_recieved он проверяет соответствующие записи с одной и той же парой человек/предложение в наборе данных offer_viewed, выбирает только записи, просмотренные между временем получения и истекшим временем предложения, и выбирает среди них самые ранние. Если за выбранный период нет записей, возвращается pd.NaT как указание на то, что предложение не было просмотрено вовремя.

Когда_completed():

- Для каждой записи в наборе данных offer_recieved он проверяет соответствующие записи с одной и той же парой человек/предложение в наборе данных offer_completed, выбирает только записи, завершенные между последним из полученных или просмотренных и истекшим временем предложения, и выбирает среди них самые ранние. Если за выбранный период нет записей, возвращается pd.NaT как указание на то, что предложение не было завершено вовремя.

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

Чтобы учесть такие предложения, я использовал последнее из полученных или просмотренных как начало периода в функции when_completed. Кроме того, я добавил новое логическое поле 'viewed_on_time', где True означает, что предложение было просмотрено между датой получения и выполнением предложения.

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

  • "используется" — логическое поле, указывает, использовалось ли предложение в течение срока действия
  • ‘time_to_view’ — время (в часах), в течение которого человек может просмотреть предложение
  • ‘time_to_complete’– время (в часах) для человека, чтобы завершить предложение
  • ‘total_avg_bill’ — средний чек клиента
  • member_since — год, когда клиент создал аккаунт приложения.
  • ‘offer_transaction’ – сумма транзакции, по которой предложение было выполнено.

Кластеризация

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

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

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

  • 'average_bill' — средний чек клиента.
  • median_bill’ — средний чек клиента
  • посещения — количество посещений (уникальных дней)
  • viewed_ratio’ – отношение просмотренных предложений к общему количеству полученных предложений.
  • response_ratio’ — отношение использованных предложений к общему количеству полученных предложений
  • cost_ratio — отношение вознаграждения к общей сумме расходов.
  • offers_to_visits’ – отношение использованных предложений к количеству посещений.

В качестве алгоритма кластеризации я использовал K-Means. Данные для K-Means должны быть подготовлены, т.е. нормализованы. В качестве подхода к нормализации я использовал MinMaxScaler().

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

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

Результаты кластеризации

Итак, давайте рассмотрим профиль клиентов Starbucks с 5 кластерами.

Количество клиентов почти поровну распределено по кластерам. Второй и третий кластеры представляют 50% клиентов. Самый низкий - 4-й кластер с 13,3%.

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

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

Глядя на количество посещений, мы можем понять, что группа является постоянными клиентами Starbucks.

График выше также подтверждает, что Кластер 3 действительно важен. Они посещают Starbucks регулярно, тогда как клиенты из кластера 0 и 4 не столь частые гости.

Теперь давайте посмотрим на сюжеты, связанные с предложением:

  1. Коэффициент просмотров по кластерам. На графике показан процент просмотренных предложений от общего количества полученных предложений:

Опять же, лидером здесь является Кластер 3 с коэффициентом просмотров 94,7%. Кластер 1, второй по выручке, имеет коэффициент всего 53,2%. Это означает, что они (вместе с кластером 4) не пользуются приложением Starbucks на постоянной основе.

2. Коэффициент ответов по кластерам. Эта метрика представляет собой отношение выполненных предложений к общему количеству полученных предложений.

Постоянные клиенты из Кластера 3 очень часто пользуются предложениями, а Кластер 0 практически их игнорирует.
Интересным открытием здесь является поведение кластеров 1 и 2. Кластер 2 имеет более низкий коэффициент ответов (около 40%), но высокий коэффициент просмотров (86,8%). Это противоположно Кластеру 1, где коэффициент ответов высок, но коэффициент просмотров низок. Это означает, что типичный покупатель Кластера 2 просматривает почти все предложения, но на самом деле ими не пользуется. В то время как клиент из Кластера 1 действительно не проверяет предложения, а использует.

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

Здесь все три основных кластера (1, 2 и 3) имеют почти одинаковое соотношение затрат и только для кластера 0 около нуля, но это потому, что они не используют предложения.
В целом, мы можем сказать, что Кластер 3 является основным ядром для Starbucks, и они должны поддерживать его со скидками или предложениями BOGO. Стратегия для других Кластеров может варьироваться в зависимости от стратегии компании. Вероятно, было бы не так рискованно повышать активность (рассылать офферы чаще) для Кластера 2, поскольку они не так часто используют офферы. Кластер 1 имеет самый высокий коэффициент затрат, поэтому здесь следует быть осторожным.

Вывод

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

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

Спасибо за внимание!

Этот проект на GitHub с кодом: https://github.com/DMazykin/Starbucks-Capstone.git