В этой статье хочу рассказать про очень важный метод анализа данных, которым очень часто пользуюсь на работе — когортный анализ. Это метод изучения поведения пользователей, объединённых в группы (когорты/винтажи). Чаще всего когорты формируются по дате первого взаимодействия с продуктом или услугой.
Когортный анализ помогает ответить на важные вопросы:
- Как меняется удержание пользователей со временем?
- Какие когорты показывают лучшие результаты?
- Окупаются ли затраты на привлечение клиентов? И так далее.
Давайте попробуем формализовать этапы проведения когортного анализа:
Шаг 1. Определите цель анализа
Сформулируйте чёткий вопрос, на который хотите получить ответ. Например, улучшилось ли удержание после редизайна приложения?
Шаг 2. Выберите критерий формирования когорт
Определите признак, по которому будете объединять юзеров когорты, исходя из целей анализа, например:
➖ Дата регистрации (наиболее распространённый вариант);
➖ Источник трафика;
➖ Географическое положение.
Шаг 3. Определите временные интервалы для анализа
Выберите период для анализа — в зависимости от специфики бизнеса это могут быть дни, недели, месяцы или комбинированный вариант.
Шаг 4. Решите, какое поведение будете измерять (на какую метрику смотреть)
- Возвращение в приложение (DAU, WAU, MAU, retention rate);
- Совершение покупки;
- Использование ключевой функции;
- Средний чек или выручка.
Шаг 5. Соберите данные и постройте когортную таблицу
По желанию — визуализируйте. На выходе у вас должно получиться что-то похожее:

Шаг 6. Интерпретируйте результаты (вы же аналитик 😉)
Обратите внимание на:
- Горизонтальные паттерны: если одна когорта значительно отличается от других, ищите внешние факторы (маркетинговые кампании, изменения в продукте);
- Вертикальные паттерны: если все когорты показывают падение в определённый период, возможно, есть проблема с onboarding или ключевой функцией;
- Диагональные паттерны: если показатели улучшаются для более поздних когорт, это может говорить об улучшении продукта.
Пример SQL-кода, которым можно собрать похожую таблицу:
WITH cohorts AS (
-- объединяем юзеров в когорты
SELECT
user_id,
DATE_TRUNC('month', registration_date) AS cohort_month,
registration_date
FROM users
),
cohort_activity AS (
-- посчитаем сколько у нас всего юзеров в каждой когорте и сколько дожило до определенного момента
SELECT
c.cohort_month,
COUNT(DISTINCT c.user_id) AS cohort_size,
-- Week 2: вернулся в дни 8-14 (после первой недели)
COUNT(DISTINCT CASE
WHEN s.session_date BETWEEN c.registration_date + 8 AND c.registration_date + 14
THEN c.user_id END) AS week_2,
-- Week 3-4: вернулся в дни 15-30
COUNT(DISTINCT CASE
WHEN s.session_date BETWEEN c.registration_date + 15 AND c.registration_date + 30
THEN c.user_id END) AS week_3_4,
-- Month 2: вернулся в дни 31-60
COUNT(DISTINCT CASE
WHEN s.session_date BETWEEN c.registration_date + 31 AND c.registration_date + 60
THEN c.user_id END) AS month_2
FROM cohorts c
LEFT JOIN user_sessions s
ON c.user_id = s.user_id
LEFT JOIN orders o
ON c.user_id = o.user_id
AND o.status = 'completed'
GROUP BY c.cohort_month
)
-- финально считаем метрики
SELECT
TO_CHAR(cohort_month, 'YYYY-MM') AS cohort,
cohort_size,
ROUND((week_2::decimal / cohort_size * 100), 2) AS week_2_retention,
ROUND((week_3_4::decimal / cohort_size * 100), 2) AS week_3_4_retention,
ROUND((month_2::decimal / cohort_size * 100), 2) AS month_2_retention
FROM cohort_activity
ORDER BY cohort_month
