← Назад к вопросам

Что такое survivorship bias и как он влияет на аналитические выводы?

1.7 Middle🔥 211 комментариев
#Работа с продуктом и бизнесом#Статистика и математика

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Survivorship Bias в аналитике

Survivorship bias (смещение выжившего) — один из наиболее опасных когнитивных предубеждений в аналитике, которое приводит к неправильным выводам. Рассказываю про механику и как его избежать.

Что такое survivorship bias

Survivorship bias — это смещение, когда мы анализируем только "успешные" или "сохранившиеся" объекты, игнорируя те, что "погибли" или исчезли. Мы видим выжившие случаи и экстраполируем выводы на всё население, забывая про невидимых.

Классический пример — боевые самолёты (WWII):

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

НЕПРАВИЛЬНО! Самолёты с повреждениями в фюзеляже не вернулись — они упали. Поэтому выжившие самолёты имеют много повреждений именно в крыльях — потому что крылья могут пережить повреждения, а фюзеляж — нет.

Правильное решение: усилить фюзеляж, потому что повреждение фюзеляжа = гибель самолёта.

Примеры в продуктовой аналитике

Пример 1: Анализ "лучших" пользователей

Неправильный вывод:

Выводы: Пользователи, которые используют фичу X, имеют 40% выше retention.
Рекомендация: Нужно заставить всех использовать фичу X!

На самом деле: Пользователи, которые нашли и используют фичу X, — это уже мотивированные, вовлечённые люди. Они выше retention не потому, что фича X хороша, а потому что это люди, которые остаются по природе.

Невидимые данные: пользователи, которые уже ушли, никогда не видели фичу X. Или видели, но сочли её скучной. Мы их не видим в данных.

Правильный вывод: нужен A/B тест, где мы случайно показываем фичу X одним пользователям и не показываем другим.

Пример 2: Анализ "успешных" стартапов

Неправильный вывод:

Анализ 100 успешных стартапов показал, что:
- Все имели харизматичного CEO
- Все собрали $5M на seed раунде
- Все были в технологии
Вывод: успех требует этих факторов!

На самом деле: Мы анализируем только выжившие стартапы. Но существуют:

  • 1000 стартапов с харизматичным CEO, которые упали
  • 100 стартапов без харизматичного CEO, которые выжили
  • Множество стартапов, которые собрали $1M и выжили

Вывод: нужно сравнить успешные стартапы с неуспешными, а не просто искать паттерны в успешных.

Пример 3: Анализ DAU/MAU пользователей

Неправильный вывод:

DAU/MAU ratio = 50% (половина месячных пользователей активны ежедневно)
Вывод: наш продукт очень вовлекает!

На самом деле: Мы смотрим на пользователей, которые не ушли в этом месяце. Но:

  • Чёрн пользователей ушёл в начале месяца (они не считаются в MAU)
  • Новые пользователи, которые придут позже, ещё не в данных

Правильная метрика: посмотри когорты.

Как识别 survivorship bias в данных

Контрольный список:

  1. Есть ли в моих данных "исчезнувшие" объекты?

    • Пользователи, которые отписались
    • Компании, которые разорились
    • Заказы, которые отменили
    • Если их нет в данных — это красный флаг
  2. Выборка репрезентативна?

    • Если смотрю только на активных пользователей, я пропускаю неактивных
    • Если смотрю только на платящих, пропускаю free tier
  3. Логично ли сравнивать эти группы?

    • Сравниваю выживших с условиями выживания?
    • Или сравниваю разные временные периоды?
  4. Есть ли обратная причина?

    • Может быть, вывод верен, но причинность противоположна?

Примеры из реальной жизни

Кейс 1: Retention анализ на Spotify

Ошибка:

SELECT AVG(playlist_count), AVG(listen_hours), retention_6m
FROM users
WHERE status = 'active'
GROUP BY country

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

Правильно:

SELECT 
  COALESCE(u.country, u_cohort.country) as country,
  COUNT(CASE WHEN u.status = 'active' THEN 1 END) * 100.0 / COUNT(*) as retention_6m,
  AVG(COALESCE(u.playlist_count, 0)) as avg_playlist_active,
  AVG(COALESCE(u_cohort.playlist_count, 0)) as avg_playlist_all
FROM users_cohort u_cohort
LEFT JOIN users u ON u_cohort.id = u.id AND u.status = 'active'
WHERE u_cohort.signup_date BETWEEN '2024-01-01' AND '2024-02-01'
GROUP BY country

Теперь сравниваем активных с ВСЕ пользователей этой когорты, включая ушедших.

Кейс 2: Анализ "требует ли успех высокой цены"

Неправильный анализ:

Смотрю топ 100 самых дорогих SaaS сервисов.
Вывод: дорогие продукты более успешны!

Проблема: дешёвые продукты, которые упали, не видны. Мы видим только дешёвые продукты, которые выжили (несмотря на цену).

Правильный анализ:

SELECT 
  price_tier,
  COUNT(*) as total_products,
  SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active_products,
  SUM(CASE WHEN status = 'shutdown' THEN 1 ELSE 0 END) as shutdown_products,
  100.0 * SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) / COUNT(*) as success_rate
FROM saas_products
GROUP BY price_tier

Теперь видим: может быть, дешёвые продукты имеют даже ВЫШЕ success rate, но мы их не видели?

Как избежать survivorship bias

1. Всегда анализируй погибшие объекты

SELECT 
  cohort_month,
  SUM(CASE WHEN status = 'active' THEN revenue ELSE 0 END) as active_revenue,
  SUM(CASE WHEN status = 'churned' THEN revenue ELSE 0 END) as churned_revenue,
  COUNT(*) as total_users
FROM users
GROUP BY cohort_month

Сравнивай активных и ушедших, а не только активных.

2. Используй когортный анализ

Группируй пользователей по дате входа, смотри, как меняется процент выживших.

3. FULL OUTER JOIN в анализе

Когда сравниваешь две группы, используй FULL JOIN, чтобы не потерять никого.

4. Задавай вопрос: а где остальные?

"Платящие пользователи имеют выше engagement" "А где бесплатные, которые ушли?"

"Дорогие продукты успешнее" "А где дешёвые, которые провалились?"

5. Используй A/B тесты

Вместо анализа существующих групп, случайно распредели пользователей и смотри различия.

Практический пример: Исправление анализа

Было (неправильно):

SELECT 
  signup_source,
  AVG(revenue),
  COUNT(*) as user_count
FROM users
WHERE status = 'paying'

Стало (правильно):

SELECT 
  signup_source,
  COUNT(*) as total_users,
  SUM(CASE WHEN status = 'paying' THEN 1 ELSE 0 END) as paying_users,
  100.0 * SUM(CASE WHEN status = 'paying' THEN 1 ELSE 0 END) / COUNT(*) as conversion_rate,
  SUM(CASE WHEN status = 'paying' THEN revenue ELSE 0 END) as total_revenue,
  SUM(CASE WHEN status = 'paying' THEN revenue ELSE 0 END) * 1.0 / COUNT(*) as avg_revenue_per_user_all
FROM users
WHERE signup_date >= DATE_SUB(NOW(), INTERVAL 1 YEAR)
GROUP BY signup_source

Теперь видим:

  • Сколько пришло всего из каждого источника
  • Сколько конвертилось в платящих
  • Средний доход на пользователя (включая тех, кто не платил)

Итог

Survivorship bias — это невидимая ошибка. Мы видим только "выжившие" данные и легко экстраполируем на всё население.

Защита:

  • Всегда включай "мёртвые" данные (ушедшие пользователи, упавшие компании)
  • Анализируй когорты, а не срезы
  • Задавай вопрос "а где остальные?"
  • Используй A/B тесты для проверки причинности
  • Помни про боевые самолёты