Hazard ratio простыми словами

Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.

Короткое объяснение

Hazard ratio (HR) — отношение рисков «события» (например, churn) для двух групп в каждый момент времени.

  • HR = 1: риски одинаковые
  • HR > 1: в тестовой группе событие чаще / быстрее
  • HR < 1: в тестовой группе реже

Центральная метрика survival analysis — анализа времени до события.

Откуда пришло

Метод из медицины. Survival analysis изучает, сколько пациенты выживают после лечения. Событие = смерть / рецидив / выздоровление.

В продуктовой аналитике то же самое, но событие = churn / upgrade / первая покупка.

Пример: churn analysis

У двух когорт пользователей разные retention:

  • Group A: выживают дольше (средний lifetime 12 мес)
  • Group B: выживают меньше (8 мес)

Hazard ratio B vs A = 1.5 (примерно).

«В group B риск churn в 1.5 раза выше в каждый момент времени».

Survival analysis — основные концепции

Survival function S(t)

Доля, которая ещё «жива» (не зачерн-илась) в момент t.

S(t) = P(T > t)

Пример: S(30) = 0.8 — 80% пользователей retention-ятся через 30 дней.

Hazard function h(t)

Мгновенная «ставка» события в момент t (при условии, что ещё живы).

Как «смертность» на возрасте X.

Hazard ratio (HR)

Отношение hazard двух групп:

HR = h_B(t) / h_A(t)

Предполагается constant во времени (proportional hazards).

Kaplan-Meier кривая

Стандартная визуализация:

S(t)
 1 |\__
   |   \__
   |      \__
   |         \__      group A
   |            \________
   |
   |\
   | \__
   |    \___
   |        \___    group B
   |            \_____
   0+------------------->  t

Если кривые расходятся → разница в retention.

В Python (lifelines)

from lifelines import KaplanMeierFitter, CoxPHFitter
import pandas as pd

# данные: user_id, duration (сколько прожил в app), event (ушёл ли: 1=churn, 0=still active)
df = pd.DataFrame({
    'duration': [30, 45, 60, 20, 15, ...],
    'event':    [1,  0,  1,  1,  0, ...],
    'group':    ['A','A','B','B','A',...]
})

# Kaplan-Meier для каждой группы
kmf = KaplanMeierFitter()
for group in df['group'].unique():
    mask = df['group'] == group
    kmf.fit(df[mask]['duration'], df[mask]['event'], label=group)
    kmf.plot_survival_function()

# Cox regression для hazard ratio
cph = CoxPHFitter()
cph.fit(df, duration_col='duration', event_col='event')
print(cph.summary)
# колонка exp(coef) — это HR для каждой переменной

Censoring — ключевая концепция

Censored observation: пользователь ещё не churn-ился к моменту анализа. Не знаем, когда (и churn-нется ли).

Survival analysis учитывает такие наблюдения, в отличие от простой mean(lifetime).

Это главное преимущество — не теряете информацию о still-active users.

Применение в продукте

1. Churn analysis

Сравнить retention двух когорт / групп A/B-теста.

2. Time to first purchase

Сколько времени от signup до первого платежа. Разное у разных сегментов.

3. Subscription retention

В SaaS — когда люди продлевают / не продлевают.

4. Activation time

Сколько времени до aha moment.

5. Feature adoption

Когда пользователи начинают использовать новую фичу.

Преимущества vs обычный retention

  • Учитывает censoring
  • Вероятностный вывод (с ДИ)
  • Controlling для ковариат (Cox regression)
  • Не привязан к фиксированным окнам (D1, D7)

Ограничения

Proportional hazards assumption

HR предполагается constant во времени. Если на самом деле HR меняется — модель неправильная.

Тестируется graphically / statistically.

Сложность интерпретации

«HR 1.5» сложнее объяснить stakeholder, чем «retention на 10 п.п. ниже».

Требует достаточно событий

Если мало churn — статистика нестабильная.

На собесе

«Что такое hazard ratio?» Отношение рисков события в двух группах.

«Зачем survival analysis?» Анализ времени до события (churn, conversion) с учётом censored данных.

«HR = 2 — как интерпретировать?» В одной группе событие случается в 2 раза чаще.

«Censored data — что это?» Наблюдения, где событие ещё не случилось. Учитываются в analysis.

Связанные темы

FAQ

HR и retention — это одно?

Связанные, но разные. Retention — S(t) в конкретный момент. HR — отношение hazard.

Python или R для survival?

В Python — lifelines. В R — survival package. Оба хороши.

HR выше или ниже — что лучше?

Для churn: HR < 1 — лучше (меньше churn). Для conversion: HR > 1 — лучше.

Нужно ли proportional hazards?

Для Cox regression — да. Если нарушено — модели без этого предположения (AFT, stratified Cox).


Тренируйте статистику — откройте тренажёр с 1500+ вопросами для собесов.