Все материалы
Продуктовая аналитикаматериалстарт

Когортный анализ: что это, как построить и читать таблицу

Когортный анализ простыми словами: как построить когортную таблицу в SQL, pandas и Excel, читать её по строкам, столбцам и диагоналям и что делать с незрелыми когортами.

КейсПрактика2 октября 2026 г.18 мин

Когортный анализ — это способ смотреть на метрику по группам пользователей, которые начали в один период, и сравнивать эти группы на одинаковом сроке жизни. Его результат — когортная таблица: строка — когорта, столбец — возраст, в клетке — удержание, выручка или доля оплативших. Ниже метод целиком на учебной базе симулятора SQL-аналитика: как построить таблицу в SQL, pandas и Excel, как читать её по строкам, столбцам и диагоналям, что делать с незрелыми когортами и каких выводов из неё делать нельзя.

Как выглядит когортная таблица и что в ней написано?

Когорта — группа людей с общим стартовым событием в одном периоде: например, все, кто зарегистрировался с 20 по 26 июля. Состав когорты не меняется. Само понятие разобрано в статье «Когорта: что это простыми словами», здесь речь о методе.

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

Читается она так. Из 377 человек, пришедших 20–26 июля, на второй неделе заходили 71,6%, на пятой — 44,3%. У двух следующих когорт вторая и третья недели почти такие же: 70,0 и 72,8%, 56,7 и 56,3%. Прочерк — срок, до которого когорта ещё не дожила: выгрузка кончается 30 августа.

Доля когорты, заходившей в продукт на неделе жизни N, %

Учебная база симулятора SQL-аналитика. Когорта — неделя регистрации, под ней размер. Первой недели нет: в день регистрации заходил каждый, там всегда 100%. Шкала цвета — от 40 до 80%.

20–26 июл
377 человек
Неделя 2
71.6%
Неделя 3
56.2%
Неделя 4
55.7%
Неделя 5
44.3%
27 июл – 2 авг
404 человека
Неделя 2
70%
Неделя 3
56.7%
Неделя 4
51.7%
Неделя 5
—
3–9 авг
430 человек
Неделя 2
72.8%
Неделя 3
56.3%
Неделя 4
—
Неделя 5
—
  • Строка — одна когорта во времени, столбец — один срок жизни у разных когорт, диагональ — один календарный период.
  • Когорты сравнивают на одинаковом и уже закрытом сроке жизни; недожитые клетки остаются пустыми.
  • Рядом с процентом стоит размер когорты, рядом с разницей — интервал.
  • Упавший столбец сначала проверяют на состав: в учебной базе июльские когорты слабее июньских из-за нового канала.

Как построить когортную таблицу: три решения и один запрос

До запроса решают три вещи. Что считать стартом и каким периодом резать когорты: здесь это регистрация и календарная неделя. Как мерить возраст. И что стоит в клетке.

Возраст считают двумя способами. Календарный — «следующая неделя после недели регистрации»: диагональ таблицы тогда ровно одна календарная неделя, но у пришедшего в воскресенье нулевая неделя длится день. Второй способ — окна от даты регистрации: дни 0–6, 7–13, 14–20. Срок у всех одинаковый, зато диагональ размывается на две календарные недели. В этой статье окна от регистрации, недели считаются с единицы (дни 0–6 — неделя 1), а заход — событие app_open.

В статье о когорте та же база посчитана иначе: недели календарные и нумеруются с нуля, так что тамошней «неделе 1» здесь соответствует «неделя 2». Числа всё равно расходятся: у когорт 6 июля – 10 августа там 76,1–80,5%, здесь 69,6–72,8%. Календарная неделя начинается в среднем на два-три дня жизни раньше, а в первые дни возвращаются чаще. Событие возврата почти ни при чём: всё, кроме app_open, случается в первые три дня.

Запрос помечает каждого пользователя флагами «заходил на неделе N» и считает долю по когорте. Условие cohort_week + 19 <= DATE '2026-08-29' оставляет клетку пустой, пока её окно не закрылось у пришедшего в последний день когорты: 6 дней до конца недели регистрации и ещё 13 дней жизни. 29 августа — последний полный день событий. Приём с флагами, дневные окна и три определения удержания разобраны в статье «Когорты и retention в SQL».

В ноутбуке ту же таблицу собирает pivot_table из длинной выгрузки «когорта, неделя, число заходивших». Строк для незрелых клеток в выгрузке нет, и pandas ставит там NaN.

Удержание по неделям жизни для трёх недельных когорт; незрелые клетки остаются пустыми
WITH flags AS (                       -- зерно: один пользователь
  SELECT
    u.user_id,
    CAST(date_trunc('week', u.signup_date) AS date) AS cohort_week,
    MAX(CASE WHEN CAST(e.event_time AS date) - u.signup_date BETWEEN 7 AND 13 THEN 1 ELSE 0 END) AS w2,
    MAX(CASE WHEN CAST(e.event_time AS date) - u.signup_date BETWEEN 14 AND 20 THEN 1 ELSE 0 END) AS w3,
    MAX(CASE WHEN CAST(e.event_time AS date) - u.signup_date BETWEEN 21 AND 27 THEN 1 ELSE 0 END) AS w4,
    MAX(CASE WHEN CAST(e.event_time AS date) - u.signup_date BETWEEN 28 AND 34 THEN 1 ELSE 0 END) AS w5
  FROM users u
  LEFT JOIN events e ON e.user_id = u.user_id AND e.event_name = 'app_open'
  WHERE u.signup_date >= DATE '2026-07-20' AND u.signup_date < DATE '2026-08-10'
  GROUP BY u.user_id, u.signup_date
)
SELECT
  cohort_week,
  COUNT(*) AS cohort_size,
  CASE WHEN cohort_week + 19 <= DATE '2026-08-29' THEN ROUND(100.0 * SUM(w2) / COUNT(*), 1) END AS week_2,
  CASE WHEN cohort_week + 26 <= DATE '2026-08-29' THEN ROUND(100.0 * SUM(w3) / COUNT(*), 1) END AS week_3,
  CASE WHEN cohort_week + 33 <= DATE '2026-08-29' THEN ROUND(100.0 * SUM(w4) / COUNT(*), 1) END AS week_4,
  CASE WHEN cohort_week + 40 <= DATE '2026-08-29' THEN ROUND(100.0 * SUM(w5) / COUNT(*), 1) END AS week_5
FROM flags
GROUP BY cohort_week
ORDER BY cohort_week;
pythonpandas: та же таблица через pivot_table из длинной выгрузки
import pandas as pd

# длинная выгрузка из SQL: когорта, неделя жизни, заходили, размер когорты — только зрелые клетки
long = pd.DataFrame(
    [('2026-07-20', 2, 270, 377), ('2026-07-20', 3, 212, 377), ('2026-07-20', 4, 210, 377), ('2026-07-20', 5, 167, 377),
     ('2026-07-27', 2, 283, 404), ('2026-07-27', 3, 229, 404), ('2026-07-27', 4, 209, 404),
     ('2026-08-03', 2, 313, 430), ('2026-08-03', 3, 242, 430)],
    columns=['cohort_week', 'week_no', 'active_users', 'cohort_size'],
)
long['retention_pct'] = (100 * long.active_users / long.cohort_size).round(1)

table = long.pivot_table(index=['cohort_week', 'cohort_size'], columns='week_no', values='retention_pct')
print(table)

Какие бывают когорты и чем опасны поведенческие?

Когорту задаёт стартовое событие или признак, известный на старте. От выбора зависит вопрос, на который ответит таблица.

Каналы и поведение в таблице посчитаны по регистрациям с 1 июля по 2 августа: платный поиск запущен 1 июля, а четвёртая неделя закрыта у пришедших по 2 августа включительно. Тарифы — по 502 первым оплатам по 31 июля включительно: срок продления у них уже наступил.

С поведенческими когортами нужна осторожность. Человек попадает в них по событию после входа, и отбирает себя сам. Разница 57,0 против 48,2% (по неокруглённым долям 8,7 ± 4,7 процентного пункта, п. п.; после ± здесь и дальше — половина 95%-го доверительного интервала) похожа на эффект: создал пространство — остался. Но пространство чаще создают пришедшие из сильных каналов: платный поиск — это 43,1% не создавших и 18,2% создавших. Внутри каналов разница — от 0,2 до 4,8 п. п. при интервалах ± 8–12, а взвешенная по каналам — 2,8 ± 4,9 п. п.: втрое меньше исходной и неотличима от нуля. В учебной базе ответ известен точно: шанс возврата задан каналом и днём жизни, создание пространства на него не влияет.

Поведенческая когорта описывает, кто остаётся, но не доказывает, что действие удерживает. Здесь работает смешивающая переменная: канал влияет и на создание пространства, и на возврат. Как делить такую разницу на состав и уровень — в статье о парадоксе Симпсона; причинные гипотезы проверяют экспериментом.

Четыре вида когорт на учебной базе
КогортаКак собранаЧто показала
По дате первого действиямесяц регистрациииюньская регистрация принесла 6,64 доллара за 30 дней, июльская — 5,47
По каналупериод регистрации и канална четвёртой неделе заходили 64,6% пришедших по рекомендации и 38,1% из платного поиска
По тарифу или продуктупервая оплата и тарифчерез 30 дней продлили 57,3% на basic, 58,2% на pro, 58,9% на team
Поведенческаядействие в первые днисоздавшие рабочее пространство: 57,0% на четвёртой неделе против 48,2% у остальных

Метрики когортного анализа: что ставить в клетки?

Удержание отвечает на вопрос «возвращаются ли». Классическое считает тех, кто заходил хотя бы раз за неделю N (в статье о retention в SQL это bracket). Вариант «на неделе N или позже» растёт, пока когорта живёт, и для сравнения когорт не годится. У когорт 15 июня, 20 и 27 июля классическая четвёртая неделя — 57,8, 55,7 и 51,7%. «Четвёртая или позже» — 97,2, 82,0 и 67,1%. Когорта 15 июня при том же сроке наблюдения, что у когорты 27 июля, показала бы 69,9%: из тридцати пунктов разницы двадцать семь дал срок.

Доля оплативших и выручка на человека считаются накопленным итогом: в клетке всё, что случилось с начала жизни до конца периода. Такая строка только растёт. Выручка накопленным итогом на одного зарегистрированного — это исторический LTV когорты к этому сроку (возвратов в учебной базе нет, поэтому выручка равна чистой); как его считать и продлевать, разобрано в статье про LTV по когортам.

В учебной базе первая оплата приходит на 3–20-й день после регистрации, поэтому доля оплативших набирается за три недели и дальше не меняется.

Знаменатель у всех трёх метрик один — размер когорты на старте. Он должен стоять рядом с процентом: 24% от 429 человек и 24% от 40 — числа разной надёжности.

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

Что ставить в клетку
МетрикаНа какой вопрос отвечаетКак ведёт себя строка
Удержание на неделе Nвозвращаются ли на этом срокепадает и выравнивается, местами подрастает
Удержание «N или позже»ушёл ли человек совсемс возрастом не растёт; каждая клетка дорастает, пока когорту наблюдают
Доля оплатившихдоходят ли до первой оплатырастёт до потолка
Выручка на человека, LTV к срокусколько денег приносит регистрациярастёт, пока идут продления
Доля когорты, оплатившей к концу недели жизни N, % (накопленным итогом)

Учебная база симулятора SQL-аналитика. Клетка заполнена, если срок закрыт у всех участников когорты.

13–19 июл
429 человек
Неделя 1
4.9%
Неделя 2
15.4%
Неделя 3
24%
20–26 июл
377 человек
Неделя 1
3.4%
Неделя 2
11.7%
Неделя 3
23.1%
27 июл – 2 авг
404 человека
Неделя 1
3.7%
Неделя 2
12.6%
Неделя 3
19.8%
3–9 авг
430 человек
Неделя 1
5.6%
Неделя 2
14%
Неделя 3
21.2%
10–16 авг
454 человека
Неделя 1
5.7%
Неделя 2
15.4%
Неделя 3
—
17–23 авг
481 человек
Неделя 1
4.6%
Неделя 2
—
Неделя 3
—

Как читать когортную таблицу: строка, столбец, диагональ

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

Три ступенчатые таблицы: в первой закрашена строка, во второй столбец, в третьей диагональ
Строка отвечает на вопрос о когорте, столбец — о сроке жизни, диагональ — о календарном периоде.
Удержание недельных когорт: доля заходивших на неделе жизни N, %

Учебная база симулятора SQL-аналитика. Когорта — неделя регистрации, начинается в указанный понедельник. Платный поиск запущен 1 июля: в когорте 29 июня его 59 человек из 300, в следующих — 26–31%. Шкала цвета — от 40 до 80%, шаг 6,7 п. п.: примерно полуширина 95%-го интервала одной клетки (± 4–7 п. п.).

1 июня
196 человек
Неделя 2
76.5%
Неделя 3
67.3%
Неделя 4
59.2%
Неделя 5
50%
Неделя 6
50.5%
8 июня
223 человека
Неделя 2
77.1%
Неделя 3
73.1%
Неделя 4
60.1%
Неделя 5
47.5%
Неделя 6
48.4%
15 июня
249 человек
Неделя 2
76.3%
Неделя 3
62.7%
Неделя 4
57.8%
Неделя 5
50.6%
Неделя 6
51.4%
22 июня
273 человека
Неделя 2
73.3%
Неделя 3
70.3%
Неделя 4
59%
Неделя 5
55.3%
Неделя 6
53.5%
29 июня
300 человек
Неделя 2
68%
Неделя 3
62.3%
Неделя 4
53%
Неделя 5
55.3%
Неделя 6
47.3%
6 июля
326 человек
Неделя 2
69.6%
Неделя 3
60.4%
Неделя 4
51.2%
Неделя 5
49.4%
Неделя 6
51.2%
13 июля
429 человек
Неделя 2
71.3%
Неделя 3
58.7%
Неделя 4
54.1%
Неделя 5
43.4%
Неделя 6
41.5%
20 июля
377 человек
Неделя 2
71.6%
Неделя 3
56.2%
Неделя 4
55.7%
Неделя 5
44.3%
Неделя 6
—
27 июля
404 человека
Неделя 2
70%
Неделя 3
56.7%
Неделя 4
51.7%
Неделя 5
—
Неделя 6
—
3 августа
430 человек
Неделя 2
72.8%
Неделя 3
56.3%
Неделя 4
—
Неделя 5
—
Неделя 6
—
10 августа
454 человека
Неделя 2
70.3%
Неделя 3
—
Неделя 4
—
Неделя 5
—
Неделя 6
—

Что видно по строке, столбцу и диагонали

Строка — одна когорта во времени. Когорта 22 июня: 73,3% на второй неделе, 59,0% на четвёртой, 53,5% на шестой. По строке видно, как быстро люди уходят и где кривая выравнивается.

Столбец — один возраст у разных когорт. Это главное сравнение: стали ли новые пользователи вести себя иначе. В столбце «Неделя 4» у четырёх июньских когорт 57,8–60,1%, у четырёх июльских — 51,2–55,7%: каждая июльская ниже каждой июньской. В сумме 59,0% (555 из 941) против 53,3% (818 из 1 536), разница −5,7 ± 4,0 п. п.

Диагональ — одни и те же календарные дни. Последние заполненные клетки строк — шестая неделя у когорты 13 июля, пятая у 20 июля и так до второй у 10 августа — приходятся на 17–29 августа. Сбой или релиз задевает все когорты сразу и ложится полосой по диагонали.

В учебной базе на диагонали лежит край данных. События обрываются 30 августа в 12:59, и без проверки зрелости в первых пустых клетках четырёх последних строк стояли бы 40,5, 30,9, 31,4 и 27,6% — на 12–20 пунктов ниже худшего зрелого значения в своём столбце. Похоже на аварию в конце августа, а это недожитые недели.

Есть здесь и провал по столбцу. На девятой неделе у июньских когорт 19,7–29,1% после 39,0–50,2% на восьмой. Причина — в данных: в учебной базе у каждого пользователя есть события только за дни 0–59 после регистрации — так она сгенерирована. От девятой недели, дней 56–62, осталось четыре дня из семи. Провал, привязанный к возрасту, ищут в продукте или, как здесь, в том, как собраны данные.

Пример когортного анализа: почему июльские когорты слабее июньских?

Тот же разрыв виден в деньгах. За первые 30 дней июньская регистрация принесла 6,64 доллара на человека, июльская — 5,47; разница по неокруглённым средним 1,16 ± 0,87. Сравнение честное: срок одинаковый и закрыт у обеих когорт.

Столбец «за всё время» так сравнивать нельзя: 11,81, 7,22 и 3,29 — это три разных срока жизни. Августовская когорта не втрое хуже июньской, ей меньше месяца.

Причина разрыва — состав. С 1 июля в базе появился платный поиск, это 28,8% июльских регистраций, и его пользователи приносят 2,59 доллара за 30 дней. Июльская когорта без платного поиска — 6,64, ровно как июньская. С удержанием то же: без платного поиска четвёртая неделя июльских когорт — 58,9% против 59,0% у июньских (разница 0,0 ± 4,3 п. п.), у самого платного поиска — 39,3%.

Отсюда решение: причину в продукте не искать — у прежних каналов ничего не изменилось. Канал оценить отдельно: окупают ли 2,59 доллара за 30 дней цену привлечения. Расходов в учебной базе нет, и дальше она не отвечает. Таблица показала, что столбец упал; почему он упал, показал разрез когорты по каналам.

Выручка на одного зарегистрированного накопленным итогом, доллары
Месяц регистрацииРазмер когортыЗа 14 днейЗа 30 днейЗа 60 днейЗа всё время
июнь1 0423,896,6410,6411,81
июль1 6763,315,47—7,22
август1 895———3,29
Выручка на зарегистрированного по месячным когортам; срок считается, если он закрыт у пришедшего в последний день месяца
WITH revenue AS (                     -- зерно: один пользователь
  SELECT
    u.user_id,
    CAST(date_trunc('month', u.signup_date) AS date) AS cohort_month,
    CAST(date_trunc('month', u.signup_date) + INTERVAL '1 month' AS date) - 1 AS month_end,
    COALESCE(SUM(CASE WHEN p.paid_at - u.signup_date < 14 THEN p.amount END), 0) AS rev_14,
    COALESCE(SUM(CASE WHEN p.paid_at - u.signup_date < 30 THEN p.amount END), 0) AS rev_30,
    COALESCE(SUM(CASE WHEN p.paid_at - u.signup_date < 60 THEN p.amount END), 0) AS rev_60,
    COALESCE(SUM(p.amount), 0) AS rev_all
  FROM users u
  LEFT JOIN payments p ON p.user_id = u.user_id
  GROUP BY u.user_id, u.signup_date
)
SELECT
  cohort_month,
  COUNT(*) AS cohort_size,
  CASE WHEN month_end + 13 <= DATE '2026-08-29' THEN ROUND(SUM(rev_14) / COUNT(*), 2) END AS per_user_14d,
  CASE WHEN month_end + 29 <= DATE '2026-08-29' THEN ROUND(SUM(rev_30) / COUNT(*), 2) END AS per_user_30d,
  CASE WHEN month_end + 59 <= DATE '2026-08-29' THEN ROUND(SUM(rev_60) / COUNT(*), 2) END AS per_user_60d,
  ROUND(SUM(rev_all) / COUNT(*), 2) AS per_user_all_time
FROM revenue
GROUP BY cohort_month, month_end
ORDER BY cohort_month;

Что делать с незрелыми когортами?

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

Что будет, если правило нарушить, видно на столбце «Неделя 4». Сложить всех заходивших на четвёртой неделе и поделить на всех зарегистрированных — 36,1%. Усреднить клетки столбца, отбросив нули трёх последних когорт, но оставив недожитые 30,9% когорты 3 августа, — 53,3% (совпадение с 53,3% июльских когорт случайно). Простое среднее девяти зрелых клеток — 55,8%. По зрелым когортам через суммы, до 27 июля включительно, — 55,2%. Первая ошибка занижает удержание на 19 пунктов, вторая — на 2,5 против такого же среднего по зрелым клеткам. На шестой неделе первая ошибка даёт 23,2% вместо 48,5%. В статье о когорте та же ловушка показана на календарных неделях, поэтому числа там другие: 31,7% вместо 53,4%.

С деньгами так же. Выручка за 30 дней по всем 4 613 регистрациям — 4,84 доллара на человека, по зрелым июньской и июльской когортам — 5,92. Незрелый август занизил оценку на 18%.

Честное сравнение когорт держится на трёх условиях: одинаковый срок жизни, срок закрыт у всех участников обеих когорт, состав по каналам сопоставим. Средние по столбцу считайте по зрелым когортам и через суммы — заходивших делить на размер, — чтобы большая когорта весила больше маленькой.

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

Столбец «Неделя 4» четырьмя способами
Как посчитаноРасчётРезультат
Все регистрации; у молодых когорт недожитое считается нулём1 665 / 4 61336,1%
Простое среднее клеток вместе с недожитой клеткой 3 августадесять клеток53,3%
Простое среднее зрелых клетокдевять клеток55,8%
Зрелые когорты, через суммы1 532 / 2 77755,2%

Как сделать когортный анализ в Excel, SQL и BI?

В SQL когортная таблица — это флаги на пользователя и группировка, как в запросах выше. Выгружать удобнее длинный формат: когорта, возраст, размер, значение. Такую выгрузку возвращает запрос из статьи о когорте, только недели там календарные. Широкий вид с неделями в столбцах делают последним шагом: в SQL через CASE, в pandas через pivot_table, в Excel сводной таблицей.

В Excel вставьте выгрузку на лист и постройте сводную таблицу: когорту — в область «Строки», неделю жизни — в «Столбцы», долю — в «Значения». Строк для незрелых клеток в выгрузке быть не должно, тогда клетки останутся пустыми. Тепловую карту даёт «Главная» → «Условное форматирование» → «Цветовые шкалы»: по справке Microsoft, в Excel для Windows оно применяется и к отчёту сводной таблицы. Общие итоги отключите — на вкладке «Конструктор» в меню «Общие итоги»: сумма процентов по неделям ничего не значит, а цветовая шкала, захватив итоги, растянется на них. О самом инструменте — статья о сводных таблицах в Excel.

В Metabase сводная таблица, по документации, строится только для вопросов из конструктора запросов. Для вопроса на SQL верните широкую таблицу прямо из запроса и включите в настройках таблицы условное форматирование с цветовой шкалой (Conditional Formatting, правило Color range). В Yandex DataLens у чарта «Сводная таблица» есть секции «Строки», «Столбцы» и «Показатели», заливка ячеек градиентом настраивается у показателя; в QL-чартах этот тип не поддерживается.

Какие выводы делают по когортной таблице и где ошибаются?

Каждое направление чтения ведёт к своей проверке: слабая строка — к составу когорты, просевший столбец — к шагу продукта на этом сроке жизни, полоса по диагонали — к журналу релизов и полноте данных (пример на условных числах — в статье «Retention по когортам и каналам»). Ниже четыре частые ошибки на числах той же базы.

Общая метрика вместо когорт. Выручка по месяцу оплаты растёт: 3 983, 10 868, 15 788 долларов, вчетверо от июня к августу. Ценность новой регистрации за 30 дней при этом упала с 6,64 до 5,47. Календарный отчёт складывает когорты разного возраста и размера: выручка растёт, потому что платящих когорт стало три и старые продлевают подписку, а новая регистрация при этом подешевела.

Эффект возраста, принятый за календарный. Доля активных за неделю среди всех зарегистрированных упала с 90,5% на второй неделе июня до 45,9% на последней, неполной, неделе августа. В продукте ничего не сломалось: база стареет, старые когорты заходят реже, а у 853 человек, пришедших до 26 июня, записи о событиях к последней неделе закончились — без них было бы 56,3%. Обратная ошибка — принять полосу по диагонали за поведение когорт.

Маленькие когорты без интервалов. Недельная когорта 20 июля на второй неделе — 71,6% ± 4,6 п. п. Дневные когорты той же недели дают от 60,9% (64 человека, ± 12,0) до 80,3% (66 человек, ± 9,6), и оба интервала накрывают 71,6. Разброс в двадцать пунктов создан размером группы.

Охота за яркой клеткой. В таблице из 45 клеток пара соседей разойдётся и случайно: 73,1 и 62,7% на третьей неделе у когорт 8 и 15 июня, разница 10,4 ± 8,4 п. п. При этом возврат в учебной базе зависит только от канала и дня жизни, а каналы у обеих когорт одни и те же. Чем больше клеток сравнивают, тем чаще такие находки — см. множественные сравнения.

pythonPython: 95%-е интервалы для долей и разниц из статьи
import numpy as np

def share(x, n):
    p = x / n
    return p * 100, 1.96 * np.sqrt(p * (1 - p) / n) * 100

def diff(x1, n1, x2, n2):
    p1, p2 = x1 / n1, x2 / n2
    se = np.sqrt(p1 * (1 - p1) / n1 + p2 * (1 - p2) / n2)
    return (p2 - p1) * 100, 1.96 * se * 100

# заходили / размер когорты — из когортной таблицы
for name, (x, n) in {
    'неделя 2, когорта 20 июля': (270, 377),
    'неделя 2, пришли 21 июля':  (39, 64),
    'неделя 2, пришли 24 июля':  (53, 66),
}.items():
    p, half = share(x, n)
    print(f'{name}: {p:.1f}% ± {half:.1f} п. п.')

for name, args in {
    'неделя 4, июнь → июль':          (555, 941, 818, 1536),
    'то же без платного поиска':      (555, 941, 643, 1091),
    'неделя 3, когорты 8 и 15 июня':  (163, 223, 156, 249),
    'неделя 4, без пространства → с ним': (365, 757, 557, 978),
}.items():
    d, half = diff(*args)
    d = round(d, 1) + 0.0             # иначе −0,04 напечатается как «-0.0»
    print(f'{name}: {d:+.1f} ± {half:.1f} п. п.')

Частые вопросы

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

Зачем когортный анализ в маркетинге? Чтобы оценивать канал по тому, что стало с привлечёнными, а не по числу регистраций. Когорты по каналу и месяцу показывают, сколько денег закупка принесла к 30-му дню и когда она окупилась. В учебной базе платный поиск дал 28,8% июльских регистраций и 2,59 доллара на человека за 30 дней против 6,64 у остальных каналов.

Какие метрики смотрят в когортном анализе? Удержание, долю оплативших, выручку на человека накопленным итогом, число повторных покупок, отток. Подойдёт любая метрика, у которой знаменатель — размер когорты на старте.

Как связаны когортный анализ и LTV? LTV — это строка когортной таблицы с выручкой накопленным итогом: у июньской когорты 3,89 доллара к 14-му дню, 6,64 к 30-му, 10,64 к 60-му. Прогноз LTV продолжает эту строку за пределы прожитого срока.

Когда когортный анализ не нужен? Когда вопрос задан про текущее состояние: выручка месяца, нагрузка на поддержку, план продлений — тут хватит календарного отчёта. И когда когорты слишком малы: при десятках человек в строке интервалы шире любых различий, и когорты укрупняют до недели или месяца.

Что читать дальше

Запросы из статьи можно выполнить в песочнице симулятора SQL-аналитика: там та же учебная база.

Упражнение: соберите когорты по каналу для июльских регистраций и посчитайте выручку за 30 дней на человека. Должно получиться 7,83 доллара у referral, 6,70 у organic, 4,78 у partner и 2,59 у paid_search.

Продолжить чтение
Вся библиотека
Продуктовая аналитика24 сентября 2026 г.12 мин
Ступенчатая сетка из цветных клеток, которые бледнеют слева направо

Когорта: что это простыми словами, виды когорт и пример на данных

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

Читать материал