К списку метрик
CONVERSION

Conversion Rate (CR)

Conversion Rate

Доля юзеров прошедших целевое действие из всех попавших в этап.

ФОРМУЛА

$$\text{CR}{step} = \frac{\text{users_completed}{step}}{\text{users_started}_{step}}$$

ОПИСАНИЕ

Что измеряет: эффективность шага/воронки.

Типы CR:

  1. Step CR — переход между двумя соседними шагами воронки (например cart → address)
  2. End-to-end CR — конверсия от первого шага до финала (visit → purchase)
  3. Cohort CR — конверсия по дате когорты (могла растянуться на недели)

Бенчмарки:

ПродуктEnd-to-end CR
Ecommerce visitors → buyers2-4%
Cart → completed checkout60-70%
Free trial → paid SaaS15-25%
App install → D7 active25-35%
Lead form → SQL (sales qualified)10-20%

Pitfalls:

  1. Knapsack effect: «10% CR» — а от чего считать знаменатель? Уникальные сессии? уникальные юзеры? Все клики? Уточняй definition
  2. Cohort vs same-period: CR=20% от мая может означать: «20% юзеров кто пришёл в мае купили в мае» (правильно) ИЛИ «20% from May purchases / May visits» (cross-cohort lie)
  3. Conversion window: для долгого decision cycle (B2B, недвижимость) CR за неделю — мусор; нужно 30-90 дней

Когда не использовать:

  • Если основная ценность не в одной транзакции (например соцсеть — не measure через CR в подписку)
  • Если воронка нелинейная (юзер может вернуться на предыдущий шаг)
SQL ПРИМЕР
-- Funnel CR step by step
WITH stages AS (
  SELECT user_id,
    MAX(stage = 'visited') AS visited,
    MAX(stage = 'cart_added') AS carted,
    MAX(stage = 'checkout_started') AS started,
    MAX(stage = 'completed') AS completed
  FROM events
  WHERE event_time >= '2026-05-01'
  GROUP BY user_id
)
SELECT
  COUNT(*) FILTER (WHERE visited) AS visits,
  COUNT(*) FILTER (WHERE carted)::float / NULLIF(COUNT(*) FILTER (WHERE visited), 0) AS visit_to_cart,
  COUNT(*) FILTER (WHERE started)::float / NULLIF(COUNT(*) FILTER (WHERE carted), 0) AS cart_to_checkout,
  COUNT(*) FILTER (WHERE completed)::float / NULLIF(COUNT(*) FILTER (WHERE started), 0) AS checkout_to_done,
  COUNT(*) FILTER (WHERE completed)::float / NULLIF(COUNT(*) FILTER (WHERE visited), 0) AS end_to_end_cr
FROM stages;
PYTHON ПРИМЕР
funnel = ["visited", "cart_added", "checkout_started", "completed"]
counts = {stage: events[events["stage"] == stage]["user_id"].nunique() for stage in funnel}
df = pd.DataFrame({"stage": funnel, "users": list(counts.values())})
df["cr_step"] = df["users"] / df["users"].shift(1)
df["cr_overall"] = df["users"] / df["users"].iloc[0]