Привет! Меня зовут Гриша Крюков, я аналитик в команде доверия и безопасности Авито. Я провёл чемпионат среди четырёх популярных моделей для оценки индивидуальных эффектов: S-learner, T-learner, X-learner и Causal Forest. В статье расскажу, как проходили испытания и какая из моделей забрала золото после всех испытаний. 

Материал будет полезен тем, кто интересуется uplift-моделированием: новичкам, чтобы узнать об этом методе, профессионалам — посмотреть на сравнение моделей в формате турнира. Не каждый же день такое устраивают!

Что такое uplift-моделирование и как всё это связано с ЧМ по футболу

Статью я написал ещё до того, как был известен победитель, поэтому некоторые факты могут показаться устаревшими сейчас, когда ЧМ уже закончился. Но это никак не влияет на содержание материала.

С 11 июня по 19 июля 2026 года в США, Мексике и Канаде проходил чемпионат мира по футболу. Впервые в истории за главный трофей боролись целых 48 сборных, и неопределённости в исходе было больше, чем обычно. 

Перед стартом турнира суперкомпьютер Opta провёл 25 тысяч симуляций и оценил шансы на победу главного фаворита, сборной Испании, всего в 16.1%, Франции — 13%, а Англии — 11.2%. То есть даже у фаворита вероятность поднять трофей меньше, чем получить шестёрку за бросок игрального кубика.

Нечто похожее мы наблюдаем в uplift-моделировании. Нет универсальной «серебряной пули», которая будет лучше других моделей во всех задачах. И тем интереснее сравнить основные модели в честной борьбе!

Мы устроим четырём моделям свой чемпионат мира. Будут: групповой этап, жеребьёвка плей-офф, полуфиналы и финал, синтетические данные, чтобы честно измерить качество, и полусинтетические, чтобы приблизиться к реальным задачам. После каждого матча мы будем разбирать, почему конкретная модель выиграла или проиграла именно здесь. Таким образом, через игровой формат узнаем про uplift-модели больше.

Весь код доступен на GitHub — можно воспроизвести, при желании поменять данные, ввести в игру дополнительные модели и устроить свой чемпионат 🙂

Что такое uplift-моделирование. Объясню на примере. Представьте, что вы главный скаут футбольного клуба. Перед вами 10 тысяч молодых игроков, и у вас есть программа интенсивных тренировок: дорогая, но эффективная. Денег хватит, чтобы отправить на программу только тысячу человек. Вопрос: кого выбрать?

Напрашивается ответ «самых талантливых». Но он неверный.

Среди молодых игроков можно выделить следующие условные типы:

— Будущие звёзды. Они всё схватывают на лету даже при обычном формате тренировок, им не нужна дополнительная дорогая программа.

— Средние игроки. Они не выйдут на высокий уровень ни с программой, ни без. Опять зря потраченные деньги.

— Чувствительные к тренировкам. Без программы они останутся середнячками, но с программой раскроют потенциал. Вот это ваша целевая группа!

👀 Если вы просто отправите на программу самых талантливых, половина окажется будущими звёздами, которым программа не нужна, а среди тех, кто действительно вырастет благодаря ей, многие останутся за бортом. Деньги потрачены, эффект не такой большой, какой мог бы быть.

Чтобы решить задачу правильно, нужно для каждого игрока оценить разницу между тем, что с ним будет с программой и без. Эту разницу называют индивидуальным каузальным эффектом — Individual Treatment Effect — или аплифтом. Задача uplift-моделирования — научить ML-модель предсказывать эту разницу для каждого нового игрока.

Главная проблема: для одного игрока мы никогда не знаем обе ситуации одновременно. Либо мы отправили его на программу и видим результат, либо не отправили и видим результат. И второй вариант — параллельная вселенная, она нам недоступна. 

Эту неустранимую недосказанность называют фундаментальной проблемой каузального вывода, и именно она отличает uplift-моделирование от обычной регрессии: в привычном ML мы предсказываем то, что можно увидеть в данных, а в uplift — разницу, одна половина которой никогда не наблюдается. 

Решение — учиться оценивать эффект не для конкретного игрока, а в среднем по группе похожих: сравнивая тех, кого на программу отправили, с теми, кого нет.

Тут еще больше контента

Как измеряем качество

В обычной регрессии мы берём истинный ответ и предсказанный, считаем ошибку, и всё готово. В uplift-моделировании истинная разница, то есть «результат с программой - результат без программы» для конкретного игрока не наблюдается. Есть два пути: 

Реальные данные, ранжирующие метрики. Qini, AUUC, uplift@k — они оценивают, насколько хорошо модель ранжирует игроков по силе эффекта, не требуя знать истинную разницу для каждого. Это то, чем вы будете пользоваться в проде. 

✍️ Подробнее про метрики в статье: Evaluating Uplift Modeling under Structural Biases: Insights into Metric Stability and Model Robustness

Синтетические данные, отклонение от истины. Если мы сами сгенерировали данные по известной формуле, то истинный эффект для каждого игрока нам известен по построению. Тогда можно посчитать честную ошибку — Precision in Estimation of Heterogeneous Effect (PEHE) по формуле ↓

\begin{array}{c} PEHE~=~\sqrt{\frac{1}{n}~\displaystyle\sum_{i=1}^{n}~\left(\overset{\wedge}{τ}\left(x_{i}\right)-τ(x_{i})\right)^{2}}\end{array}

Где:

n — количество игроков в тестовой выборке;

xᵢ — характеристики i-го игрока (возраст, скорость, выносливость и т. д.);

τ( xᵢ ) — истинная разница «с программой минус без программы» для этого игрока (известна, потому что данные синтетические);

τ̂( xᵢ ) — предсказание модели для этой же разницы;

разность под корнем — ошибка модели на одном игроке.

По сути, PEHE — это RMSE, но не по обычной целевой переменной, а по индивидуальному каузальному эффекту. Чем меньше PEHE, тем точнее модель угадывает индивидуальный эффект. 

У нас будут синтетические и полусинтетические данные, поэтому PEHE нам идеально подходит. Кроме того, название метрики созвучно с именем одного из лучших игроков в истории футбола — Пеле, а потому выбор метрики нашего чемпионата предопределён 🙂

👀 PEHE можно посчитать, только когда мы сами сгенерировали данные. В реальных задачах истинного эффекта для каждого пользователя у вас нет, и там придётся оценивать Qini, AUUC или другие метрики.

Представление участников

У нас четыре сборные, и, хотя на поле они решают одну и ту же задачу, внутри устроены по-разному. Различия не в «качестве игроков», а в тактической схеме: кто как располагается на поле, кто с кем общается и кто за что отвечает. В то время как базовый алгоритм у всех одинаковый: для турнира берём градиентный бустинг с дефолтными настройками.

Давайте разбираться.

Введём обозначение: 

✍️ T — флаг того, что мы применили воздействие. Например, игрока отправили на дорогую тренировочную программу.

✍️ Множество тех наблюдений, для которых T = 1 (применили воздействие), можем также называть тестовой группой. 

✍️ Множество тех наблюдений, для которых T = 0 (не применили воздействие), можем также называть контрольной группой.

S-learner — тотальный футбол

S-learner — это «голландская школа» футбола времён Кройфа. Никаких жёстких амплуа, никакого деления на «команду тех, кто получил воздействие» и «команду тех, кто не получил». Одна модель обучается на всех данных, а факт воздействия — получил пользователь скидку или нет — подаётся в неё как ещё один признак наравне со всеми остальными.

Чтобы получить uplift для конкретного игрока, S-learner просит свою единственную модель сделать два предсказания: «что будет с этим игроком, если T = 1» и «что будет, если T = 0». Разница — и есть оценка эффекта.

Схема работы модели S-learner. Источник: статья Causal Inference for The Brave and True на гитхабе, раздел 21 - Meta Learners

💪 Сильная сторона. Быстрая и дешёвая в подготовке. Одна модель — одно обучение.

☹️ Слабая сторона. Флаг воздействия может «потеряться» среди других признаков. Если у вас 100 фич, а T — одна из них, дерево может вообще не сплитить по T и выдавать почти нулевой uplift для всех.

T-learner — одна команда, два штаба

Представьте сборную, где главный тренер решил: защитники должны идеально читать атаку соперника, а нападающие идеально вскрывать оборону. 

Это слишком разные задачи, чтобы разучивать их вместе. Поэтому защитников он отдаёт одному штабу — они тренируются на матчах против сильных атак (наблюдения с T = 1). 

Нападающих — другому штабу: они отрабатывают против обороны (наблюдения с T = 0). 

Два штаба не общаются между собой, у каждого своя методичка.

Чтобы получить uplift, T-learner спрашивает обе модели: одна оценивает, что было бы с игроком с воздействием, вторая — что было бы без. Разница — оценка эффекта.

Схема работы модели T-learner. Источник: статья Causal Inference for The Brave and True на гитхабе, раздел 21 - Meta Learners

💪 Сильная сторона. Каждая модель учит свою задачу, не отвлекаясь на чужую. Если структуры поведения при воздействии и без воздействия принципиально разные — обе линии быстро схватят свой паттерн.

☹️ Слабая сторона. Уязвим к дисбалансу. Если в одной из групп игроков мало, её штаб тренируется на скудных данных, и вся команда страдает. Также может сказаться отсутствие обмена информации между моделями: даже если в данных с T = 1 и T = 0 есть общая структура, T-learner всё равно не будет её использовать.

X-learner — команда с креативным плеймейкером

Начинает там же, где T-learner: обучает две модели — одну на T = 0 (нет воздействия), другую на T = 1 (есть воздействие). 

На втором этапе X-learner спрашивает у первой модели: как бы повёл себя игрок из группы тех, на кого не действовали, если бы мы всё-таки применили воздействие. 

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

На этих псевдоэффектах обучаются ещё две модели — они и есть плеймейкеры, чья задача — предсказывать uplift напрямую.

Финальный шаг — propensity-модель. Это разводящий, отдельный игрок, который оценивает вероятность, что игрок получил воздействие (T = 0). По этой вероятности два плеймейкера усредняются: там, где данных по тестовой группе мало, больше вес у плеймейкера, обученного на контрольной группе, и наоборот.

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

Схема работы модели X-learner. Источник: статья Causal Inference for The Brave and True на гитхабе, раздел 21 - Meta Learners

💪 Сильная сторона. Архитектурно заточен под несимметричное распределение целевой переменной. Может вытягивать сложные матчи, где структура тестовой и контрольной групп разная, сложная, нелинейная.

☹️ Слабая сторона. Самая сложная архитектура из представленных uplift-моделей. Пять моделей внутри — больше точек, где можно ошибиться с настройками, и дольше ждать результатов обучения.

Causal Forest — техничный ансамбль

Causal Forest устроен по мотивам случайного леса, но с принципиальной разницей: каждое дерево в нём строит ветки не чтобы лучше предсказать целевую метрику, а чтобы максимально разнести подгруппы по силе эффекта воздействия. То есть само дерево уже думает в категориях «здесь воздействие работает сильнее, а здесь слабее» — и режет данные именно по этому критерию.

Вторая фишка: каждое дерево использует одну подвыборку, чтобы решить, где делать сплиты, а другую — чтобы оценить величину эффекта внутри листьев. Это как если бы тренер просматривал одни матчи команды, чтобы понять её тактику, а другие — чтобы оценить её реальную силу.

Финальная оценка аплифтов получается усреднением по всем деревьям.

💪 Сильная сторона. Универсальная команда. Стабильно хороша на широком классе задач. Хорошо переносит дисбаланс и сложные нелинейные эффекты за счёт гибкости деревьев.

☹️ Слабая сторона. Самая медленная и менее эффективная на маленьких выборках модель турнира, так как деревьям нужно много данных.

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

✍️ Текст про uplift-модели: Causal Inference for The Brave and True. 21 - Meta Learners

✍️ Статья про Causal Forest: Machine Learning Goes Causal II: Meet the Random Forest’s Causal Brother

Групповой этап — проверяем модели на синтетических данных

Четыре сборные знают друг друга. Базовый алгоритм — одинаковый. Тактические схемы — разные. Пора посмотреть, как это работает на поле!

Правила группового этапа. Групповой этап проходит на синтетических данных. Это значит, что мы сами генерируем выборку по заранее заданной формуле: придумываем, как устроен «контрольный мир», а как — «мир с воздействием», и какой именно эффект мы хотим заложить. Так мы можем честно посчитать PEHE и сказать, кто к истине ближе.

Три раунда. Каждый раунд — это отдельный сценарий с собственной структурой данных, заточенной так, чтобы подчеркнуть конкретную особенность задачи.

Все четыре сборные играют в каждом раунде. Никто не пропускает матчи.

Делаем по пять симуляций. Это страховка от везения: финальный PEHE— среднее по пяти прогонам.

Очки: 3 за первое место, 2 за второе, 1 за третье, 0 за четвёртое.

При равенстве очков смотрим суммарное время обучения по всем раундам. Кто быстрее, тот выше, что-то вроде жёлтых карточек за затяжку времени.

Размер выборки в каждом раунде — 5 тысяч наблюдений, 10 признаков. Обучение и контроль делятся в отношении 70/30.

Жми сюда!

Раунд 1. Дисбаланс групп

Стандартная ситуация в индустрии: контрольная группа большая, тестовая — маленькая. Так бывает, когда воздействие дорогое, например: рассылка с подарком, дорогая фича, индивидуальный звонок менеджера, и его получает только небольшой процент пользователей. 

Вопрос: какая модель не сломается, когда данных о воздействии в разы меньше, чем о его отсутствии?

Как сгенерированы данные. На входе — 5 000 наблюдений, у каждого 10 независимых признаков, распределённых нормально (среднее 0, дисперсия 1). Дальше:

— Вероятность попасть в тестовую группу: 10% для всех. То есть в среднем только каждый десятый получает воздействие, остальные — контроль.

— Эффект воздействия зависит от первого признака:

 τ(X) = 1 + X₁. Чем выше X₁, тем сильнее uplift

— Контрольная группа (что было бы без воздействия) описывается формулой:

 μ₀(X) = X₃ + 0.5 · X₄ — линейная зависимость от двух других признаков

Итоговая целевая метрика: 

Y = μ₀(X) + T · τ(X) + ε, где ε — стандартный гауссов шум (среднее 0, дисперсия 1)

Результаты раунда. Causal Forest выиграл уверенно. Игроки из каузального леса оказались совсем не деревянными, а очень гибкими: лес сам решает, где делать сплиты, опираясь на максимизацию различия в эффекте, и не выделяет подгрупп, где данных по воздействию слишком мало. 

T-learner же сталкивается с той проблемой, которую мы подняли при представлении команд: его «штаб тестовой группы» обучается всего на 500 наблюдениях против 4 500 у штаба контроля, и качество предсказаний явно проседает.

Значения PEHE по каждой модели после первого раунда
Значения PEHE по каждой модели после первого раунда

Место

Uplift-модель

PEHE

Время, сек

1

Causal Forest

0.318

4.93

2

S-learner

0.410

1.59

3

X-learner

0.415

4.89

4

T-learner

0.521

1.59

Распределение моделей после первого раунда. Лидирует Causal Forest 
Распределение моделей после первого раунда. Лидирует Causal Forest 

Интересно, насколько близки команды S-learner и X-learner: всё решили тысячные доли, но победителем выходит S-learner.

Раунд 2. Слабый эффект

Прямая противоположность раунду 1: наблюдений в группах поровну, но воздействие почти ничего не делает. Так бывает, когда таргетинг изначально промахнулся: в среднем не работает, а локальные эффекты теряются в шуме. 

Главный вопрос: какая модель удержится от соблазна придумать эффект там, где его нет?

Как сгенерированы данные.

— Вероятность тестовой группы: 50%, идеальный баланс.

— Эффект:

 τ(X) = 0.05 · X₁ — в 20 раз слабее, чем в Раунде 1

— Контрольная группа: 

μ₀(X) = 2 · sin(X₁) + X₂² + X₃ — нелинейная функция, чтобы было сложнее

Итоговая целевая метрика: 

Y = μ₀(X) + T · τ(X) + ε, где ε — стандартный гауссов шум

Результаты раунда. Сенсация этапа: победа S-learner с разрывом почти в 10 раз против T-learner. И этот разрыв не случайность. 

У S-learner признак воздействия — всего лишь один из одиннадцати. И когда он мало что объясняет, общая модель просто перестаёт принимать по нему решения: предсказания для T = 1 и T = 0 оказываются почти одинаковыми, а значит, и предсказанный uplift близок к нулю, то есть к истине, в нашем случае. 

Более сложные модели могут начать придумывать эффекты там, где их нет.

Значения PEHE по каждой модели после второго раунда
Значения PEHE по каждой модели после второго раунда

Место

Uplift-модель

PEHE

Время, сек

1

S-learner

0.049

1.60

2

Causal Forest

0.101

4.74

3

X-learner

0.212

4.70

4

T-learner

0.473

1.57

Распределение моделей после второго раунда ↓

Лидируют Causal Forest и S-learner
Лидируют Causal Forest и S-learner

Неужели самая простая тактика приведёт к успеху? Давайте дождёмся результатов третьего раунда.

Раунд 3. Несимметричный эффект

Самый каверзный раунд группового этапа. Здесь мир без воздействия и мир с воздействием устроены принципиально по-разному: в контрольной группе всё гладко и линейно, а в тестовой — нелинейные эффекты. В жизни так бывает, когда воздействие не просто двигает метрику, а меняет характер поведения пользователя: контрольные пользователи ведут себя предсказуемо, а у тестовых появляется новая модель поведения.

Как сгенерированы данные.

— Баланс групп: 50/50.

— Контрольная группа: 

μ₀(X) = X₁ + X₂ — простая линейная функция

— Тестовая группа: 

μ₁(X) = X₁ + X₂ + 2 · sin(2 · X₃) + X₄² — та же линейная база, плюс нелинейные добавки

— Истинный эффект:

 τ(X) = μ₁(X) − μ₀(X) = 2 · sin(2 · X₃) + X₄²

Итоговая целевая метрика: 

Y = μ₀(X) + T · τ(X) + ε, где ε — стандартный гауссов шум

Результаты раунда. X-learner и T-learner хорошо проявили себя в той задаче, под которую создавались. X-learner забрался повыше за счёт более тонкой настройки на разницы предсказаний. 

Когда поведение пользователей при воздействии и без воздействия принципиально разные, одной модели недостаточно, и потому S-learner набирает 0 очков по итогам испытания.

Значения PEHE по каждой модели после третьего раунда
Значения PEHE по каждой модели после третьего раунда

Место

Uplift-модель

PEHE

Время, сек

1

X-learner

0.438

4.76

2

T-learner

0.563

1.54

3

Causal Forest

0.734

4.82

4

S-learner

0.947

1.60

Распределение моделей после третьего раунда. Лидирует X-learner
Распределение моделей после третьего раунда. Лидирует X-learner

Итоги группового этапа

Causal Forest набирает наибольшее количество очков, показывая стабильно неплохие результаты в разных испытаниях, и заслуженно выходит из группы первым. 

Между S-learner и X-равенство по очкам, но S-learner идёт вторым в нашей таблице: он оказался в три раза быстрее своего оппонента. 

T-learner занимает четвёртое место, набрав свои первые очки лишь в третьем раунде, и его путь в плей-офф обещает быть непростым.

Место

Uplift-модель

Очки

Суммарное время, сек

1

Causal Forest

6

72.4

2

S-learner

5

23.9

3

X-learner

5

71.8

4

T-learner

2

23.5

Плей-офф

Групповой этап закончился, и мы переходим к самой интересной части турнира. В плей-офф всё иначе: вместо чистой синтетики — полусинтетические данные, вместо абстрактных X₁, X₂, X₃ — характеристики реальных пользователей и футболистов.

На групповом этапе я сам генерировал и признаки, и целевую метрику — это давало полный контроль и возможность честно посчитать PEHE. Но у такого подхода есть слабое место: реальные данные никогда не выглядят как X ~ N(0, I) с независимыми гауссовыми признаками. Полусинтетика — компромисс. 

Мы берём настоящие признаки X из публичного датасета (характеристики реальных людей), а вот целевую метрику Y генерируем сами — по формуле, в которую заложен известный нам индивидуальный эффект τ(X). Получаем лучшее из двух миров: реалистичная структура признаков, плюс возможность честно посчитать PEHE.

Правила полуфиналов и финала. Три матча: два полуфинала и финал. По итогам группы сетка такая:

— Полуфинал 1: первое место группы vs четвёртое (Causal Forest ⚔️ T-learner).

 — Полуфинал 2: второе место группы vs третье (S-learner ⚔️ X-learner).

— Финал: победители полуфиналов.

5 симуляций в каждом матче, итоговый PEHE — среднее.

Победитель — модель с меньшим PEHE. Никаких очков, дуэль на вылет.

Полуфиналы провожу на данных Hillstrom MineThatData, классическом e-commerce A/B-датасете на 64 тыс. клиентов интернет-магазина. Обучение и контроль делится 70/30.

Финал проходит на данных FIFA 21, открытом датасете на ~10 тыс. футболистов с их игровыми характеристиками.

Полуфинал 1. Causal Forest ⚔️ T-learner

Для битвы фаворита и аутсайдера я выбрал стандартную историю: вы делаете email-рассылку, в которой письма чаще получают активные клиенты, которые недавно покупали. Звучит логично, но создаёт огромную проблему для оценки эффекта: вы видите, что получатели рассылки покупают больше, но ведь они и так купили бы больше, потому что изначально активнее.

Происходит смешение эффекта воздействия с эффектом самих характеристик пользователя. Не всегда получается проводить рандомизированные A/B-тесты, и часто приходится иметь дело с такими смещёнными выборками.

Как сгенерированы данные. Берём 64 000 реальных клиентов Hillstrom — для каждого известны: давность последней покупки (recency), история трат (history), сегмент покупательской истории, ZIP-код, канал привлечения. После бинарного кодирования категорий получаем 15 признаков.

— Целевая метрика Y — дополнительные траты клиента после рассылки в долларах.

— Вероятность получить рассылку (тестовая группа) растёт с активностью клиента:

e(X) = clip(0.4 + 0.25 · recency_z, 0.1, 0.85) 

Активные получают письма чаще пассивных — вот он, confounding.

— «Контрольный мир» (что потратил бы клиент без рассылки):

μ₀(X) = 10 + 3 · recency_z + 1.5 · history_z

Активные с историей и так тратят больше — заметьте, что те же самые признаки, по которым выбирали, кому слать письмо, влияют и на базовый уровень трат. Это и есть механика смещения из-за спутывающих переменных.

— Эффект рассылки:

τ(X) = 4 + 3 · tanh(history_z) − 1.5 · segment_z

Нелинейная функция: рассылка помогает всем, но клиентам с богатой историей покупок — особенно сильно, а клиентам из определённых сегментов — слабее.

— Итоговая целевая метрика:

Y = μ₀(X) + T · τ(X) + ε, где ε — гауссов шум с дисперсией 9

Результаты первого полуфинала. Главная сенсация плей-офф уже здесь, в полуфинале: чемпион группы вылетает. 

T-learner реабилитировался благодаря объёму информации. На групповом этапе ему всё время не хватало данных в тестовой группе: 500 наблюдений в раунде 1, шумная выборка в раунде 2. Здесь же — 64 000 клиентов, из них рассылку получили около 26 000. Этого с запасом хватает обеим моделям T-learner, чтобы каждый уверенно выучил свою форму поведения покупателей. Слабость «нет обмена информацией между моделями» перестаёт быть критичной, когда у каждой модели и без чужой помощи достаточно данных.

Causal Forest споткнулся на реальных данных. На синтетике группового этапа признаки были чистые и независимые — деревьям было куда сплитить. Реальные данные Hillstrom устроены иначе: после кодирования категориальных признаков в нулях и единицах получается разреженная структура, в которой каждый отдельный признак даёт слишком грубое разделение. Деревьям сложнее находить хорошие сплиты, и встроенный механизм борьбы со смещением не успевает компенсировать архитектурный проигрыш.

Значения PEHE в первом полуфинале. T-learner: 0.406, Causal Forest: 0.626
Значения PEHE в первом полуфинале. T-learner: 0.406, Causal Forest: 0.626

💡 Урок матча: место в групповой таблице — не приговор. На синтетике побеждает универсальность, а на реальных данных начинают играть роль детали структуры признаков, которые в чистом эксперименте не видны.

Полуфинал 2. S-learner ⚔️ X-learner

Матч равных соперников без явного фаворита: обе модели набрали по 5 очков в группе. 

Бизнес-история — классическая сегментация клиентов по их реакции на рассылку. Среди 64 000 клиентов есть четыре чётко различимые группы:

💁 Активные с богатой историей (persuadables): рассылка приводит к большим дополнительным тратам (+8$ в среднем).

💁 Активные, но без истории (neutrals): рассылка работает умеренно (+3$).

💁 Пассивные с историей (sleepers ): почти не реагируют (+0.5$).

💁 Пассивные без истории (do-not-disturb): рассылка их раздражает и снижает траты (−2$).

Это идеальный сценарий для uplift-моделирования в его классическом понимании: задача модели — не предсказать, кто купит, а предсказать, кому имеет смысл слать рассылку, а кому — категорически нет.

Как сгенерированы данные. Берём те же 64 000 клиентов Hillstrom и используем реальный treatment: получил / не получил сообщение.

— Целевая метрика Y — дополнительные траты в долларах.

— «Контрольный мир»:

μ₀(X) = 10 + 3 · history_z + segment_z

— Эффект рассылки определяется сегментом по двум признакам — recency и history:

  • recency > 0 и history > 0 → τ = +8$ (persuadables)

  • recency > 0 и history ≤ 0 → τ = +3$ (neutrals)

  • recency ≤ 0 и history > 0 → τ = +0.5$ (sleepers)

  • recency ≤ 0 и history ≤ 0 → τ = −2$ (do—not—disturb)

— Итоговая целевая метрика:

Y = μ₀(X) + T · τ(X) + ε, где ε — гауссов шум с дисперсией 9

Результаты второго полуфинала. X-learner побеждаем с разгромным счётом. 

S-learner провалился, потому что у него одна общая модель, в которую факт рассылки подаётся как ещё один признак — наравне с recency, history, ZIP-кодом и всем остальным. Внутри модели есть конкуренция: по какому признаку принимать решение в первую очередь? 

И почти всегда побеждает не факт рассылки, а recency или history — потому что они влияют не только на эффект, но и на базовый уровень трат. В итоге модель в основном учитывает эти фичи, а сам факт рассылки используется редко и поверхностно. Модель учитывает общий уровень трат хорошо, а вот разницу между «с рассылкой» и «без» почти не учитывает.

X-learner побеждает за счёт архитектуры: модель обучается предсказывать напрямую разницу между мирами, а не общий уровень, поэтому быстро находит границы между сегментами. На втором этапе обе внутренние модели обучаются предсказывать именно разницу между мирами «с воздействием» и «без», а не общий уровень. 

Когда задача — поймать четыре чётких уровня эффекта, такая модель приходит к ним напрямую: она не отвлекается на базовый уровень трат, а сразу ищет, где проходит граница сегментов. Плюс модель вероятности попасть в рассылку помогает аккуратно соединить оценки с обеих сторон.

Значения PEHE во втором полуфинале. X-learner: 0.215, S-learner: 0.747
Значения PEHE во втором полуфинале. X-learner: 0.215, S-learner: 0.747

💡 Урок матча: когда задача — поймать резкие переходы между сегментами, важно не общее качество модели, а то, на что именно она настроена смотреть. S-learner учитывает «всё сразу», X-learner именно разницу. Здесь это решило исход в три с половиной раза.

Кликни здесь и узнаешь

Финал. T-learner ⚔️ X-learner

Финал переезжает с e-commerce в спорт. Бизнес-история: футбольный клуб запустил дорогую программу интенсивных тренировок и хочет понять, кому из 10 000 молодых игроков она реально поможет, а кого может даже сломать. Здесь возвращается тот самый скаут из нашего примера — но теперь с реальными данными FIFA 21.

Как сгенерированы данные. Берём ~10 000 реальных футболистов из FIFA 21. Для каждого известны 26 числовых атрибутов: возраст, рост, вес, потенциал, скорость, точность ударов, выносливость, точность пасов, дриблинг, реакция и так далее.

— Целевая метрика Y — будущий overall rating игрока. Его игровой рейтинг от 47 до 93 баллов.

— Назначение на программу T: случайное, 50/50. Идеальная рандомизация, как в чистом A/B-тесте.

— «Контрольный мир» (рейтинг без программы):

μ₀(X) = текущий overall − 0.5 · max(0, age_z)

Молодые сохраняют рейтинг, возрастные слегка проседают.

— Эффект программы — главное в этом сценарии:

τ(X) = 3 − 2 · age_z + 1.5 · stamina_z + 1.0 · acceleration_z + 0.8 · potential_z − 1.2 · max(0, age_z) · max(0, −stamina_z)

Учитываем взаимодействие: возрастные игроки с низкой выносливостью получают дополнительный штраф. Программа их перегружает.

— Финальное ограничение: τ обрезается до диапазона [−8, +12] баллов, чтобы исключить нереалистичные выбросы. Например, сорокалетние вратари с экстремально низкой выносливостью, которым алгебра дала бы −50 баллов.

— Итоговая целевая метрика:

Y = μ₀(X) + T · τ(X) + ε, где ε — гауссов шум с дисперсией 2.25

Результаты финала. X-learner выиграл с двукратным запасом! Чтобы понять, как это произошло, надо посмотреть, чем эта задача отличалась от полуфинальной.

Эффект программы тренировок — сложная формула, в которой каждый признак игрока добавляет свою долю: молодость, выносливость, ускорение, потенциал. И главное — есть взаимодействие: возрастные игроки с низкой выносливостью получают дополнительный штраф, которого нет ни у молодых, ни у возрастных с хорошей формой. Это нелинейная конструкция, которая требует от модели не только прибавить вклад от каждого признака, но и поймать, как два признака работают вместе.

Фатальным для T-learner стало то, что модели внутри работают независимо. В полуфинале у него было около 26 000 наблюдений в каждой группе — этого хватило, чтобы две независимые модели уверенно выучили каждая свою форму поведения. Здесь же ~5 000 на группу: достаточно, чтобы поймать прямые эффекты возраста и выносливости по отдельности, но мало, чтобы каждая из двух моделей с нуля выучила взаимодействие между ними. А поскольку две модели T-learner работают независимо и не делятся информацией, ни одна из них не «подсказывает» другой, что искать.

У X-learner сыграла архитектура — обе внутренние модели на втором этапе обучаются предсказывать именно разницу между мирами с программой и без. На такой задаче взаимодействие признаков становится видимым напрямую: модель ищет, где разница ведёт себя необычно, и быстро упирается в «возраст + низкая выносливость». Плюс обмен информацией между двумя внутренними моделями работает как раз на тех зонах, где данных мало.

Значения PEHE в финале. X-learner: 0.579, T-learner: 1.135
Значения PEHE в финале. X-learner: 0.579, T-learner: 1.135

💡 Урок матча: когда эффект — это не сумма независимых вкладов, а тонкое взаимодействие признаков, разница между моделями становится принципиальной. T-learner силён, когда задача делится на две независимые подзадачи. X-learner, когда подзадачи переплетены, и их нужно их связывать.

Чемпион определён, и это X-learner! 

Итоги всех этапов чемпионата
Итоги всех этапов чемпионата

Бронзовый призёр группы становится чемпионом — главный сюжет нашего турнира. Что это значит на практике — разберём в заключении.

Итоги и обсуждение всех моделей

Турнир закончен. X-learner поднимает кубок, T-learner — обладатель серебра за самый классный камбэк турнира, S-learner и Causal Forest были хороши в групповом этапе, но слишком рано оступились в плей-офф. А мы получили список полезных наблюдений, сравнивая модели.

🤓 S-learner — мастер слабых эффектов. Когда воздействие почти ничего не меняет, его общая модель честно говорит «здесь нет структуры» и оказывается ближе всех к истине. Но как только эффект становится сложным или несимметричным, у S-learner начинаются проблемы: он не может выделить воздействие среди других признаков.

🤓 T-learner — вполне хорош на больших данных. Когда в каждой группе достаточно наблюдений, две независимые модели уверенно выучивают свои формы. Но если задача требует поймать тонкие взаимодействия признаков, отсутствие обмена информацией между двумя моделями становится непреодолимым ограничением.

🤓 X-learner — специалист по сложной структуре эффекта. Когда эффект — это сложные нелинейные взаимодействия, архитектура работает по назначению: вместо общего уровня модель учится именно на разнице между мирами с воздействием и без. На простых задачах гибкость становится риском — модель может «придумать» структуру там, где её нет (что мы и видели в раунде 2). Цена универсальности — больше времени на обучение.

🤓 Causal Forest — стабильный универсал на чистых данных. Победитель группового этапа, но на реальных ковариатах с разреженной структурой деревьям тяжело: после кодирования категориальных признаков сложно находить хорошие сплиты, и преимущество над специализированными моделями исчезает. Вполне возможно, это особенность выбранного датасета, потому что обычно Causal Forest может проявлять себя хорошо на реальных данных.

И главный вывод — всё сильно зависит от данных, на которых проводим турнир. Например, если бы данные FIFA были в полуфинале, то Causal Forest одолел бы T-learner. 

Напоминает ситуацию, где при идеальных погодных условиях могут оказаться сильнее техничные команды, при плохом поле и дожде — более физически подготовленные. Так что в нашем чемпионате, как и во многих спортивных состязаниях, был важен фактор случайности.

Буду рад узнать, за какую модель вы болели в чемпионате и какие используете в работе, пишите комментарии 🙂


Кстати, если вам интересна работа в бигтехе —  Хабр совместно с ЭКОПСИ проводит большое исследование IT-брендов работодателей. В прошлом году в нём поучаствовали 34 000 специалистов. Если у вас есть опыт — он точно будет учтён.