# Парадокс Симпсона: почему агрегат врёт (пример и как ловить)
Коротко: парадокс Симпсона (Simpson's paradox) — это ситуация, когда тренд, который есть в каждой отдельной группе данных, разворачивается в противоположную сторону, если группы объединить. Вариант A может выигрывать у варианта B в каждом сегменте по отдельности, но проигрывать ему в общем агрегате. Причина почти всегда одна: скрытая переменная (confounder) по-разному распределена между группами. Это распределение и называют mix-shift — сдвиг в структуре выборки. Формально:
Изa1/b1 > c1/d1иa2/b2 > c2/d2НЕ следует, что(a1+a2)/(b1+b2) > (c1+c2)/(d1+d2).
Дроби так не складываются. Именно поэтому «средняя конверсия по больнице» — самый опасный агрегат в аналитике. Ниже — числовой пример со сходящимися цифрами, объяснение mix-shift, SQL-разбивка по сегментам и чек-лист, как парадокс ловить до того, как вы примете неверное решение.
Что такое парадокс Симпсона простыми словами?
Представьте, что вы сравниваете два лендинга — новый (A) и старый (B) — по конверсии в регистрацию. Трафик приходит из двух источников: органика (высокий intent, конвертит хорошо) и платная реклама (низкий intent, конвертит плохо).
Вы смотрите на итог и видите: старый лендинг B побеждает с разгромным счётом. Логичный вывод — откатить новый дизайн. Но стоит разбить данные по источнику трафика, как картина переворачивается: новый лендинг A выигрывает и в органике, и в платке. Оба вывода сделаны на одних и тех же данных. Один из них — ложный.
Ложный — тот, что построен на агрегате. И вот почему.
Числовой пример: конверсия по сегментам против общей
Возьмём конкретные цифры. Всего по 1100 визитов на каждый вариант, конверсия в регистрацию:
| Сегмент | Вариант A | Вариант B |
|---|---|---|
| Органика | 90 / 100 = 90% | 800 / 1000 = 80% |
| Платный трафик | 200 / 1000 = 20% | 10 / 100 = 10% |
| Итого | 290 / 1100 = 26.4% | 810 / 1100 = 73.6% |
Читаем таблицу построчно:
- В органике A выигрывает: 90% против 80%.
- В платном трафике A выигрывает: 20% против 10%.
- В итоге A разгромно проигрывает: 26.4% против 73.6%.
Это и есть парадокс Симпсона в чистом виде. A лучше в каждом из двух сегментов, но хуже в сумме почти в три раза. Никакой ошибки в арифметике здесь нет — это математически корректный результат сложения дробей с разными знаменателями.
Почему так получается? Механика mix-shift
Секрет — в структуре трафика, а не в качестве лендинга. Посмотрите, куда попал трафик:
- Вариант A: 100 органических + 1000 платных → 91% визитов пришлись на «плохой» низкоконвертящий сегмент.
- Вариант B: 1000 органических + 100 платных → 91% визитов пришлись на «хороший» высококонвертящий сегмент.
Итоговая конверсия варианта — это средневзвешенное по сегментам, где веса — доли трафика. Вариант B «купается» в органике, где конверсия высокая сама по себе, независимо от дизайна. Вариант A тащит на себе платный трафик, который конвертит плохо у обоих. Общий агрегат измеряет не качество лендинга, а микс источников. Это и есть mix-shift: сравнивая итоги, вы сравниваете структуру трафика, а не то, что хотели измерить.
Источник трафика здесь — confounder (искажающая переменная): он одновременно влияет и на выбор варианта (через кривой сплит), и на исход (конверсию). Пока confounder не сбалансирован, любой агрегат смешивает два эффекта в одно число и врёт.
Как обнаружить парадокс Симпсона: сегментация в SQL
Первый и главный приём — никогда не доверять одному агрегату, всегда резать по ключевым измерениям. Сравните наивный запрос и разбивку.
-- Наивный агрегат: A проигрывает (26.4% против 73.6%)
SELECT variant,
SUM(conversions) AS conv,
SUM(visits) AS visits,
ROUND(100.0 * SUM(conversions) / SUM(visits), 1) AS cr
FROM ab_results
GROUP BY variant;
-- Разбивка по сегменту: A выигрывает в каждом
SELECT segment,
variant,
ROUND(100.0 * SUM(conversions) / SUM(visits), 1) AS cr
FROM ab_results
GROUP BY segment, variant
ORDER BY segment, variant;
Если направление вывода из первого запроса не совпадает с направлением из второго — у вас парадокс Симпсона, и верить нужно разбивке (при условии, что вы резали по правильной переменной). Практическое правило: смотрите не только на конверсию по сегментам, но и на размеры сегментов у каждого варианта. Резкий перекос в знаменателях (100 против 1000) — красный флаг mix-shift.
Потренировать такие разбивки с GROUP BY и оконными функциями можно в SQL-тренажёре, а собрать полноценную сегментную воронку — в разделе тестовых заданий.
Как исправить: взвешивание и стандартизация
Обнаружить мало — нужно получить честное сравнение. Способ, который работает, называется прямая стандартизация (direct standardization): считаем конверсию каждого варианта так, как будто у обоих одинаковая, общая структура сегментов.
В нашем примере суммарно по обоим вариантам: органика — 100 + 1000 = 1100 визитов, платка — 1000 + 100 = 1100 визитов. То есть общая структура ровно 50/50. Применяем эти веса к посегментной конверсии каждого варианта:
CR_adjusted = w_органика × CR_сегмента + w_платка × CR_сегмента
- Вариант A: 0.5 × 90% + 0.5 × 20% = 55%
- Вариант B: 0.5 × 80% + 0.5 × 10% = 45%
После выравнивания структуры трафика A выигрывает: 55% против 45%. Именно этот вывод — правильный, потому что он убрал влияние confounder-а. Тот же расчёт на SQL:
-- Стандартизация: приводим оба варианта к общей структуре сегментов
WITH seg AS (
SELECT segment,
variant,
1.0 * SUM(conversions) / SUM(visits) AS cr
FROM ab_results
GROUP BY segment, variant
),
weights AS ( -- общий вес сегмента по всей выборке
SELECT segment, SUM(visits) AS seg_visits
FROM ab_results
GROUP BY segment
)
SELECT s.variant,
ROUND(100.0 * SUM(s.cr * w.seg_visits)
/ SUM(w.seg_visits), 1) AS cr_adjusted
FROM seg s
JOIN weights w USING (segment)
GROUP BY s.variant;
Запрос вернёт 55.0 для A и 45.0 для B — тот же ответ, что и в ручном расчёте. Логику взвешенного среднего удобно перепроверить и в Python — соберите её из pandas groupby в Python-тренажёре.
Как парадокс Симпсона ломает A/B-тесты?
В корректно проведённом A/B-тесте парадокса Симпсона быть не должно — и это ключевая мысль. Рандомизация именно для того и нужна: она балансирует все confounder-ы (и известные, и неизвестные) между группами. Если пользователи распределяются по вариантам случайно, доля органики и платки в A и B будет одинаковой, mix-shift не возникнет, и агрегат не соврёт.
Парадокс всплывает, когда рандомизация нарушена. Типичные причины:
- Кривой сплит по трафику. Вариант A раскатали в основном на платную рекламную кампанию, B — на органический трафик. Классика нашего примера.
- Sample Ratio Mismatch (SRM). Из-за бага в бакетировании в группы попали разные доли устройств, платформ или регионов.
- Разное время экспозиции. Один вариант захватил распродажу или праздник, другой — обычные дни.
- Постфактум-срезы на неслучайных данных. Вы сравниваете не A/B, а «пользователей фичи» с «непользователями» — они самоотобрались.
Отсюда практический вывод: перед тем как радоваться результату теста, проверьте баланс ковариат между группами и отсутствие SRM. Если по итогу A лучше, а в разбивке по устройству/региону/источнику — хуже, тест невалиден, и его нельзя катить. Подробный разбор корректной проверки значимости — в статье A/B-тесты на Python и scipy.stats.
Где ещё прячется парадокс Симпсона в аналитике?
Это не редкая экзотика из учебника, а рутинная ловушка продуктовой аналитики:
- Динамика конверсии во времени. Общая конверсия сайта упала, хотя в каждом сегменте выросла — просто вырос трафик из дешёвого низкоконвертящего канала. Классический mix-shift по каналам.
- Retention когорт. Средний retention просел не потому, что продукт стал хуже, а потому что в выборку влилась большая молодая когорта с ещё низким retention. Резать retention нужно по когортам — см. когортный анализ retention в SQL.
- Средний чек и ARPU. Общий ARPU растёт, хотя в каждом гео падает — сдвинулась доля пользователей в сторону дорогого рынка.
- Найм и зарплаты. Средняя зарплата в компании выросла, хотя в каждом грейде не менялась — изменилась структура: наняли больше сеньоров.
Общий паттерн один: как только вы видите, что «средняя метрика» движется не так, как ожидаете, первый вопрос — не изменилась ли структура выборки под этой средней.
Чек-лист: как не попасться на агрегат
| Шаг | Действие |
|---|---|
| 1. Не верьте одному числу | Любой итоговый агрегат режьте по 2-3 ключевым измерениям (источник, устройство, гео, когорта). |
| 2. Смотрите знаменатели | Резкий перекос в размерах сегментов между группами — сигнал mix-shift. |
| 3. Ищите confounder | Спросите: какая переменная влияет и на группировку, и на метрику одновременно? |
| 4. Взвешивайте | Приводите группы к общей структуре сегментов (прямая стандартизация). |
| 5. В A/B — проверьте рандомизацию | SRM-тест и баланс ковариат до того, как читать результат. |
Итог
Парадокс Симпсона — это не магия и не ошибка в данных, а прямое следствие того, что дроби с разными знаменателями складываются не так, как хочется интуиции. Агрегат врёт всякий раз, когда структура выборки (mix) у сравниваемых групп различается, а под средним прячется confounder. Защита проста и всегда одна: режьте данные по сегментам, смотрите на размеры сегментов и взвешивайте к общей структуре. В корректном A/B-тесте рандомизация делает это за вас — но только если сплит действительно случайный.
Хотите набить руку на реальных разбивках GROUP BY, оконных функциях и сегментных воронках, на которых аналитики ловят такие парадоксы? В SQL-тренажёре и Python-тренажёре 425 SQL- и 402 Python-задачи с настоящим движком в браузере. Pro открывает все задачи, кейсы и метрики, плюс безлимитный AI мок-собес — где вопрос про парадокс Симпсона задают чаще, чем кажется.