Заметки про Machine Learning, Data Science и Analytics Engineering

Когортный анализ в Python

Когортный анализ
Когортный анализ

Что такое когортный анализ?

Когортный анализ заключается в исследовании характеристик когорт/винтажей/поколений, объединенных по общим временным признакам.

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

Почему это ценно?

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

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

Для этой задачи используем публичный датасет: https://www.kaggle.com/olistbr/brazilian-ecommerce и файлы olist_orders_dataset.csv и olist_order_payments_dataset.csv. Соединить их можно по order_id.

Ответьте на два вопроса:

  • Сколько в среднем заказов и на какую сумму делают все когорты за первый год
  • Сравните две любые когорты по прибыле и количеству заказов

Реализация когортного анализа на Python

import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings("ignore")
import seaborn as sns
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker
import matplotlib as mpl
pd.set_option('max_columns', 50)
mpl.rcParams['lines.linewidth'] = 2
%matplotlib inline
sns.set_context(
     "notebook", 
     font_scale = 1.5,       
     rc = { 
         "figure.figsize" : (30, 30), 
         "axes.titlesize" : 18 
     }
)
df_orders = pd.read_csv('data/olist_orders_dataset.csv')
df_payments = pd.read_csv('data/olist_order_payments_dataset.csv')

Импортируем все необходимые библиотеки и считаем файлы.

Когорты мы будем строить на дату покупки (order_purchase_timestamp), поэтому преобразуем её в datetime64. Создадим индекс order_id и соединим наши датасеты по нему.

df_orders['order_purchase_timestamp'] = pd.to_datetime(df_orders['order_purchase_timestamp'])
df_payments = df_payments.set_index('order_id')
df_orders = df_orders.set_index('order_id')
order_payment = df_orders.join(df_payments)

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

order_payment.reset_index(inplace=True)
order_payment['Period'] = order_payment.order_purchase_timestamp.dt.strftime('%Y-%m')

Создадим новый столбец CohortGroup, который является годом и месяцем, когда произошла первая доставка заказа клиенту.

order_payment.set_index('customer_id', inplace=True)
order_payment['CohortGroup'] = order_payment.groupby(level=0)['order_purchase_timestamp'].min().dt.strftime('%Y-%m')#.dt.apply(lambda x: x.strftime('%Y-%m'))
order_payment.reset_index(inplace=True)

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

grouped = order_payment.groupby(['CohortGroup', 'Period'])
cohorts = grouped.agg({'customer_id': pd.Series.nunique,
                        'payment_value': 'sum',
                        'order_id': 'count'})
cohorts.rename(columns={'customer_id': 'TotalClients',
                         'order_id': 'TotalOrders'}, inplace=True)

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

def cohort_period(df):
     df['CohortPeriod'] = np.arange(len(df)) + 1
     return df
cohorts = cohorts.groupby(level=0).apply(cohort_period)
print(cohorts.head(10))
print(cohorts.tail(12))
Когортный анализ в Python
Когорты

К сожалению в этом датасете есть только первый месяц когорты. По этим результатам мы уже можем сравнивать когорты. Например когорту 2018-06 и 2018-07: Общее количество клиентов и покупок выросло. Но, давайте посчитаем покупки на клиента:

  • 2018-06 — 6419/6167 = 1.04
  • 2018-07 — 6507/6292 = 1.03

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

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

cohorts = cohorts.reset_index()
cohorts['CohortGroupYear'] = cohorts['CohortGroup'].apply(lambda x: x.split('-')[0])
tt = cohorts.groupby('CohortGroupYear').agg({'payment_value': 'mean','TotalOrders':'mean','TotalClients':'mean'})
tt['ratio'] = tt['TotalOrders'] / tt['TotalClients']
print(tt)
Когорты по годам

За 2016 год у нас к сожалению только 3 месяца с очень странными значениями, а за 2018 только 10 месяцев. Мы уже видим рост в 2018 году по сравнению к 2017, но покупки на клиента снижаются.

Заключение

Разобрали когортный анализ. Он позволяет нам сравнивать разные группы клиентов объеденных по какому-то принаку по времени и понимать как разные версии продукта влияют на него.

Share it

Если вам понравилась заметка - подписывайтесь на мой канал в телеграме https://t.me/renat_alimbekov или вы можете поддержать меня Become a Patron!


Интересные записи в этой рубрике: