Продуктовая аналитика

AARRR-воронка, когортный анализ, LTV и retention — инструменты продуктового аналитика с SQL и Python.

AARRR — воронка пирата

~8 мин

Acquisition, Activation, Retention, Referral, Revenue — фреймворк для понимания жизненного цикла пользователя.

AARRR (Pirate Metrics) — Dave McClure, 2007

Acquisition (Привлечение):
  Откуда приходят пользователи?
  Метрики: CPC, CPA, CAC, CTR, трафик по каналам

Activation (Активация):
  Получил ли пользователь «первую ценность»?
  Метрики: % зарегистрировавшихся, % выполнивших первое действие
  Aha Moment: «момент когда пользователь понял ценность»
  Пример для Slack: отправка 2000 сообщений → пользователь остаётся

Retention (Удержание):
  Возвращается ли пользователь?
  Метрики: D1/D7/D30 retention, Weekly/Monthly Active Users
  Churn rate = 1 - Retention rate

Referral (Рекомендации):
  Приводит ли пользователь других?
  Метрика: NPS, viral coefficient, K-factor
  K = (инвайты от 1 пользователя) * (conversion rate инвайта)
  K > 1 → вирусный рост

Revenue (Выручка):
  Сколько пользователь платит?
  Метрики: ARPU, ARPPU, LTV, MRR, ARR

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

~10 мин

Как сегментировать пользователей по дате первого события и отслеживать их поведение во времени.

Когорта = группа пользователей объединённых общим событием в одно время.
Обычно: дата регистрации, дата первого заказа.

SQL:
WITH cohorts AS (
  SELECT
    user_id,
    DATE_TRUNC('month', MIN(created_at)) AS cohort_month
  FROM orders
  GROUP BY user_id
),
activity AS (
  SELECT
    c.user_id,
    c.cohort_month,
    DATE_TRUNC('month', o.created_at) AS activity_month,
    DATEDIFF('month', c.cohort_month, DATE_TRUNC('month', o.created_at)) AS month_number
  FROM cohorts c
  JOIN orders o USING (user_id)
)
SELECT
  cohort_month,
  month_number,
  COUNT(DISTINCT user_id) AS users
FROM activity
GROUP BY 1, 2
ORDER BY 1, 2;

Затем делим на размер когорты → таблица retention:

Когорта     M+0   M+1   M+2   M+3
Янв 2024   100%   45%   32%   28%
Фев 2024   100%   48%   35%   —

Pandas:
cohort_pivot = activity.pivot_table(
  index='cohort_month', columns='month_number',
  values='users', aggfunc='nunique'
)
retention = cohort_pivot.divide(cohort_pivot[0], axis=0)

LTV — Lifetime Value

~9 мин

Три способа считать LTV: простая формула, когортный подход и предиктивные модели.

LTV (Customer Lifetime Value) — сколько денег принесёт пользователь за всё время.

1. Простая формула:
   LTV = ARPU * Average Lifetime
   ARPU = Revenue / Active Users
   Lifetime = 1 / Churn Rate

   Пример: ARPU = 5000₸/мес, Churn = 10%/мес
   LTV = 5000 * (1/0.10) = 50 000₸

2. Когортный LTV (точнее):
   Суммируем выручку по когорте за N месяцев / размер когорты

   SQL:
   SELECT
     cohort_month,
     SUM(amount) / COUNT(DISTINCT user_id) AS ltv_12m
   FROM (
     SELECT u.cohort_month, o.amount, o.user_id
     FROM cohorts u
     JOIN orders o USING (user_id)
     WHERE o.created_at <= cohort_month + INTERVAL '12 months'
   ) t
   GROUP BY cohort_month;

3. Предиктивный (ML):
   Модели: BG/NBD + Gamma-Gamma (библиотека lifetimes в Python)

   from lifetimes import BetaGeoFitter

import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: 'Продуктовая аналитика',
  description: 'AARRR, когорты, LTV, retention, воронки — метрики продуктового аналитика.',
  openGraph: { title: 'Продуктовая аналитика', description: 'AARRR, когорты, LTV, retention, воронки — метрики продуктового аналитика.' },
};

   bgf = BetaGeoFitter()
   bgf.fit(rfm['frequency'], rfm['recency'], rfm['T'])
   rfm['predicted_purchases'] = bgf.predict(52, ...)

Правило: LTV / CAC > 3 → устойчивый бизнес

Retention — метрики и способы улучшения

~8 мин

D1, D7, D30 retention, Churn rate, Stickiness — как считать и что делает продукт «липким».

Retention Day N:
  % пользователей зарегистрировавшихся в день 0,
  которые вернулись в день N (±1 день окно).

  SQL (Day 7 retention):
  SELECT
    COUNT(DISTINCT CASE WHEN days_since_reg BETWEEN 6 AND 8
          THEN user_id END) * 1.0
    / COUNT(DISTINCT CASE WHEN days_since_reg = 0
          THEN user_id END) AS d7_retention
  FROM (
    SELECT
      user_id,
      DATEDIFF('day', MIN(date) OVER (PARTITION BY user_id), date) AS days_since_reg
    FROM sessions
  ) t;

Бенчмарки (мобильные приложения):
  D1:  40% — хорошо, 25% — средне, < 15% — плохо
  D7:  20% — хорошо, 10% — средне
  D30:  8% — хорошо,  4% — средне

Stickiness = DAU / MAU
  Показывает насколько «привычным» стал продукт
  > 20% — хорошо (Facebook ~65%, Twitter ~25%)

Churn Rate:
  Churn = (Users_start - Users_end) / Users_start * 100%
  MRR Churn = (Lost MRR) / (Starting MRR) * 100%

Leaky Bucket: новые пользователи не компенсируют отток.
Исправить: сначала починить retention, потом лить в acquisition.

Воронки и конверсия

~7 мин

Построение воронок, расчёт конверсии по шагам, поиск узких мест.

Воронка = последовательность шагов к целевому действию.
Пример: Главная → Каталог → Карточка → Корзина → Оплата

SQL (конверсия по шагам):
SELECT
  COUNT(DISTINCT session_id)                           AS step1_main,
  COUNT(DISTINCT CASE WHEN page='catalog'   THEN session_id END) AS step2_catalog,
  COUNT(DISTINCT CASE WHEN page='product'   THEN session_id END) AS step3_product,
  COUNT(DISTINCT CASE WHEN page='cart'      THEN session_id END) AS step4_cart,
  COUNT(DISTINCT CASE WHEN page='checkout'  THEN session_id END) AS step5_checkout,
  COUNT(DISTINCT CASE WHEN event='purchase' THEN session_id END) AS step6_purchase
FROM events
WHERE date >= '2024-01-01';

Конверсия step i → step i+1:
  CR_i = step(i+1) / step(i) * 100%

Общая конверсия воронки:
  CR_total = step6 / step1 * 100%

Метод: найти шаг с наибольшим DROP-OFF → оптимизировать.

Когортная воронка: разбить по источнику трафика, стране, дате.
  Нередко органика конвертирует в 3-5× лучше платного трафика.

Pandas (pivot воронки):
events.groupby('step')['user_id'].nunique().reset_index()