Задачи на когортный анализ на собеседовании
Зачем на собесе спрашивают когорты
Когортный анализ — главный инструмент продуктовой аналитики. Среднее врёт, когорты — нет. Если вы не умеете построить когортную таблицу в SQL / pandas — для продуктовой команды это дисквалификация.
Базовые понятия
- Cohort — группа пользователей с общим началом (неделя регистрации, месяц первой покупки).
- Cohort size — количество пользователей в когорте.
- Cohort index / period — сколько времени прошло с когортного дня.
- Retention table — матрица: строки — когорты, столбцы — периоды, значения — % удержанных.
Задача 1. Определение когорты
Как бы вы определили когорту для SaaS / e-commerce / игры?
- SaaS: месяц первого платежа или неделя активации trial.
- E-commerce: неделя первой покупки.
- Игра: день регистрации (обычно короткий жизненный цикл).
На собесе: «когорта — это группировка по точке начала жизненного цикла. Выбор зависит от продукта».
Задача 2. Построить когортную таблицу retention в SQL
WITH cohort AS (
SELECT user_id,
DATE_TRUNC('month', MIN(event_time))::DATE AS cohort_month
FROM events
GROUP BY user_id
),
activity AS (
SELECT c.user_id, c.cohort_month,
DATE_TRUNC('month', e.event_time)::DATE AS active_month
FROM cohort c
JOIN events e USING (user_id)
),
labeled AS (
SELECT cohort_month, active_month, user_id,
EXTRACT(MONTH FROM AGE(active_month, cohort_month))::int AS period_num
FROM activity
)
SELECT cohort_month, period_num, COUNT(DISTINCT user_id) AS active
FROM labeled
GROUP BY 1, 2
ORDER BY 1, 2;Получаем long-format. Pivot на столбцы — через pandas или приложение.
Задача 3. Pandas-версия когортной таблицы
df['cohort'] = df.groupby('user_id')['date'].transform('min').dt.to_period('M')
df['period'] = df['date'].dt.to_period('M')
df['period_num'] = (df['period'] - df['cohort']).apply(lambda x: x.n)
cohort_pivot = (
df.groupby(['cohort', 'period_num'])['user_id']
.nunique()
.unstack()
)
retention = cohort_pivot.divide(cohort_pivot[0], axis=0)Получаем матрицу с retention в %.
Прокачать тему на реальных задачах удобно в боте @kariernik_bot — база вопросов собрана с собеседований в Яндексе, Авито, Ozon, Тинькофф.
Задача 4. LTV по когортам
WITH cohort AS (
SELECT user_id, DATE_TRUNC('month', MIN(order_time))::DATE AS cohort_month
FROM orders GROUP BY user_id
),
revenue AS (
SELECT c.cohort_month,
DATE_TRUNC('month', o.order_time)::DATE AS period_month,
SUM(o.amount) AS rev,
COUNT(DISTINCT c.user_id) OVER (PARTITION BY c.cohort_month) AS cohort_size
FROM cohort c
JOIN orders o USING (user_id)
GROUP BY 1, 2, c.user_id
)
SELECT cohort_month,
EXTRACT(MONTH FROM AGE(period_month, cohort_month))::int AS m,
SUM(SUM(rev)) OVER (PARTITION BY cohort_month ORDER BY period_month) / MAX(cohort_size) AS ltv
FROM revenue
GROUP BY cohort_month, period_month;Задача 5. Сравнение когорт до и после релиза
В марте 2026 выкатили редизайн онбординга. Сравните retention когорт до и после.
cohort_before = df[df['cohort'] < '2026-03-01']
cohort_after = df[df['cohort'] >= '2026-03-01']
for c in [cohort_before, cohort_after]:
retention = calc_retention(c)
print(retention.mean(axis=0)) # среднее по когортамНа собесе интерпретируют: «если retention D7 у новых когорт выше на 5 п.п. — релиз сработал».
Задача 6. Weekly cohorts vs Monthly cohorts
Для молодого продукта (3 месяца) лучше weekly — больше детализации. Для зрелого (2+ года) — monthly или quarterly, чтобы не шуметь.
Задача 7. Тепловая карта когорт
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 8))
sns.heatmap(retention, annot=True, fmt='.0%', cmap='YlGnBu')
plt.title('Cohort Retention')
plt.show()На собесе просят: «как визуализировать?» Ответ — тепловая карта.
Задача 8. Когорты по каналу привлечения
SELECT channel, period_num, AVG(retention) AS avg_retention
FROM cohort_table
GROUP BY channel, period_num
ORDER BY channel, period_num;Сразу видно — Organic обычно удерживает лучше, Performance — хуже.
На собесе такие штуки часто спрашивают. Быстрый способ довести до автоматизма — тренажёр в Telegram с задачами из реальных интервью.
Задача 9. Диагональ в когортной таблице
Если retention ухудшается по диагонали (одинаковая позиция в разных когортах) — это внешний эффект (сезонность, событие, кризис). Если только определённые когорты — это связанный с когортой триггер (например, рекламная кампания плохого качества).
Задача 10. Когорты для A/B
# Разделим пользователей на A/B по дате регистрации ИЛИ по назначению
df['group'] = df['user_id'].apply(assign_group) # 'A' или 'B'
for g in ['A', 'B']:
cohort_ret = calc_retention(df[df['group'] == g])
print(f"Group {g} D7: {cohort_ret[7].mean():.1%}")Как тренироваться
Когортный анализ — на собесе любимая тема. Его спрашивают в Авито, Яндексе, Ozon, Wildberries. Нужно уметь построить и интерпретировать.
Тренажёр Карьерник содержит задачи на когорты: построение, сравнение, LTV по когортам, интерпретация. Каждая с разбором типичных ошибок.
Совет: всегда проговаривайте вслух «когорта у меня — месяц первой покупки» или другое. Это страхует от главной ошибки — неправильного определения когорты.
Читайте также
- Когортный анализ: гайд
- Когортный анализ в SQL
- Retention: как считать
- Задачи на retention на собеседовании
FAQ
Когорты по регистрации или по первой покупке?
Зависит от продукта. Для e-commerce обычно первая покупка (важен именно платёжный лайф-сайкл). Для freemium-SaaS — регистрация или активация trial. Главное — зафиксировать один тип и придерживаться.
Weekly или monthly cohorts?
Weekly для молодых продуктов (первые 1-2 года). Monthly для зрелых. Weekly даёт больше данных, monthly — стабильнее.
Сколько месяцев смотреть?
Хотя бы 3-6 месяцев для SaaS/e-commerce. Для игр обычно достаточно D1-D30. Чем длиннее временной горизонт, тем больше доверия к retention curve.
Как визуализировать когорты?
Тепловая карта — стандарт. Линии retention по когортам — альтернатива. На собесе ответ «heatmap with cohorts as rows» — правильный.