Модель обучена, метрики посчитаны, клиенты отсортированы по скору. Осталось выбрать аудиторию и запустить промокампанию. И тут появляется вопрос: сколько дополнительных денег принесёт именно этот отбор?
На собеседовании по CVM — управлению ценностью клиентской базы — такой вопрос легко превращает разговор о машинном обучении в разговор о причинности и экономике. Можно знать S‑learner, T‑learner и устройство продакшен‑пайплайна, но споткнуться о переход от «модель хорошо ранжирует» к «кампания заработает».
Эта статья выросла из разбора такого собеседования. Без имён, компаний и внутренних результатов: только постановка задачи, несколько типичных ловушек и расчёт, который можно проверить на листе бумаги.
Иллюстрация сгенерирована с помощью ИИ. Все численные примеры ниже синтетические, а схемы построены отдельно по формулам.
Разберём цепочку из четырёх шагов: что предсказывает модель, как перевести прогноз в прибыль, с чем сравнивать новую политику и что делать, если история коммуникаций ещё не накоплена.
Три вопроса, которые часто принимают за один
Пусть мы решаем, кому отправить предложение со скидкой. Нас интересуют три разные вещи:
-
Купит ли клиент, если получит предложение?
-
Насколько предложение изменит его вероятность покупки?
-
Останутся ли после этого дополнительные деньги?
На первый вопрос отвечает прогноз отклика. На второй — оценка эффекта воздействия. На третий — экономическая модель. Хороший ответ на первый вопрос не заменяет остальные два.
Схема 1. Числа относятся к одному учебному примеру, но измеряют разные величины.
Зафиксируем аудиторию, конкретное предложение и горизонт — например, покупку в течение 14 дней. Обозначим:
p1(x) = P(Y(1) = 1 | X = x)
p0(x) = P(Y(0) = 1 | X = x)
tau(x) = p1(x) − p0(x)
Y(1) — потенциальный исход при назначении предложения, Y(0) — без него. Для конкретного клиента одновременно наблюдать оба исхода нельзя. Поэтому модель оценивает условный средний эффект по признакам, а не узнаёт, что «на самом деле» произошло бы с этим же человеком в параллельном мире.
В T‑learner два потенциальных средних моделируются отдельно, в S‑learner используется одна модель с индикатором воздействия. Но название алгоритма само по себе не делает оценку причинной: нужны соответствующий дизайн данных и предпосылки идентификации. Для наблюдательных данных, в частности, нельзя игнорировать факторы, одновременно влияющие на назначение предложения и покупку. EconML: Meta‑Learners, предпосылки оценивания.
Если p0 = 0,10, а p1 = 0,18, абсолютный uplift равен 0,08, то есть 8 процентным пунктам. Относительный прирост — 80%. Фразу «модель даст 8%» лучше не оставлять без уточнения единиц.
Для выбранной аудитории S ожидаемое количество дополнительных покупок можно оценить так:
ΔQ(S) = Σ[i ∈ S] tau_hat_i
Это следует из линейности математического ожидания. Независимость покупок для самого суммирования не нужна, хотя зависимости между клиентами важны для оценки неопределённости. Предполагается также, что эффект предложения для клиента не меняется из‑за того, скольким другим клиентам его отправили: при дефиците товара или сетевых эффектах такую модель надо пересматривать.
Есть ещё одна оговорка: складывать как вероятности можно содержательные оценки абсолютного эффекта, а не произвольный ранжирующий скор.
Почему лучший покупатель может быть плохим получателем скидки
Представим два типа клиентов:
-
Первый и без предложения покупает с вероятностью 90%. С предложением — с вероятностью 91%.
-
Второй без предложения покупает с вероятностью 10%, с предложением — с вероятностью 18%.
Response‑модель предпочтет первого: 91% заметно выше 18%. Но ожидаемый прирост у него всего 1 п.п., у второго — 8 п.п.
Стимулировать человека, который и так собирался купить, бывает дорого. Однако и обратная эвристика «давайте скидку только тем, кто вряд ли купит» не является решением. Возможно, эти люди не купят и после скидки. Нам нужна разница между сценариями, а затем — стоимость этой разницы.
Формула, в которой нельзя забыть органических покупателей
Возьмём намеренно простой случай:
-
в выбранном горизонте учитывается не более одной покупки;
-
маржа с покупки до скидки равна
m; -
при каждой покупке с предложением клиент получает фиксированную скидку
d; -
назначение коммуникации стоит
cнезависимо от покупки; -
базовая маржа одинакова в двух сценариях, прочие эффекты пока не учитываем.
Тогда ожидаемый дополнительный результат на клиента:
g = p1 × (m − d) − p0 × m − c
= (p1 − p0) × m − p1 × d − c
= tau × m − p1 × d − c
Это не специальная «формула uplift»: мы просто вычли ожидаемую прибыль без воздействия из ожидаемой прибыли с воздействием.
Здесь самая важная деталь — p1 × d, а не tau × d. Мы оплачиваем скидку на всех покупках с предложением, включая те, которые состоялись бы и без него.
Скидка уменьшает маржу не только дополнительных покупок. Иллюстрация не показывает точные количества.
Проверим арифметику. Отобрали 10 000 клиентов. Для упрощения у всех одинаковые оценки: p0 = 0,10, p1 = 0,18, маржа до скидки — 300 ₽, скидка — 50 ₽, контакт — 2 ₽.
Дополнительные покупки: 10 000 × 0,08 = 800
Маржа от прироста: 800 × 300 = 240 000 ₽
Расход на скидки: 10 000 × 0,18 × 50 = 90 000 ₽
Коммуникации: 10 000 × 2 = 20 000 ₽
Дополнительная прибыль: 240 000 − 90 000 − 20 000 = 130 000 ₽
Схема 2. Это математическое ожидание в учебной модели, не результат A/B‑теста.
При скидке 150 ₽ и тех же вероятностях получится уже −50 000 ₽. Это арифметический стресс‑сценарий: в реальности изменение скидки, вероятно, изменит и поведение клиентов, поэтому нельзя использовать его как прогноз новой акции без переоценки p1.
Отрицательный итог при положительном uplift — не противоречие. Дополнительные покупки просто не покрыли все расходы.
В реальном проекте формулу придётся расширить. Если купон используют не все покупатели, нужен ожидаемый расход на его фактическое применение. Если маржа уже посчитана после скидки, нельзя вычитать её второй раз. Для повторных покупок, разных корзин и переноса спроса между периодами удобнее сразу оценивать чистую маржу за согласованный горизонт:
g_i = E[чистая маржа_i(1)] − E[чистая маржа_i(0)]
− дополнительные расходы, ещё не включённые в маржу
Следить стоит и за всей корзиной: скидка на один товар может вытеснить покупку другого, более маржинального. Горизонт «до конца акции» тоже способен спрятать перенос будущего спроса в настоящее.
От скоринга к политике: небольшой пример на Python
Даже среди клиентов с положительным uplift денежный результат может сильно различаться. Вот три условных клиента — или три однородных сегмента, если интерпретировать вероятности как средние по ним.
def incremental_profit(p0, p1, margin, discount, contact_cost):
return p1 * (margin - discount) - p0 * margin - contact_cost
clients = [
("A", 0.90, 0.91),
("B", 0.10, 0.18),
("C", 0.03, 0.06),
]
rows = []
for client, p0, p1 in clients:
profit = incremental_profit(p0, p1, 300, 50, 2)
rows.append((client, p1, p1 - p0, profit))
for client, response, uplift, profit in rows:
print(f"{client}: p1={response:.0%}, "
f"uplift={100 * uplift:.0f} pp, profit={profit:.2f}")
selected = [row[0] for row in sorted(rows, key=lambda r: r[3], reverse=True)
if row[3] > 0]
print("Select:", selected)
Результат:
A: p1=91%, uplift=1 pp, profit=-44.50
B: p1=18%, uplift=8 pp, profit=13.00
C: p1=6%, uplift=3 pp, profit=4.00
Select: ['B', 'C']
Здесь pp — процентные пункты, profit — рубли на клиента. Клиент A с максимальной вероятностью покупки оказывается убыточным получателем предложения.
При одинаковой стоимости контакта и ограничении на их количество можно взять верхние положительные g_i. Если стоимость контактов или стимулов различается, появляется задача бюджетной оптимизации. Дополнительно могут действовать ограничения по запасам, частоте контактов, каналу и доступности предложения.
Код выше демонстрирует правило решения при известных вероятностях. Он не оценивает причинный эффект по данным, не учитывает ошибку прогноза и сам по себе не доказывает оптимальность политики в реальной системе.
Как обосновать «раньше было 5 п.п., теперь будет 8 п.п.»
Нельзя получить новую цифру, просто добавив в рассуждение сезонность. Средний uplift выбранного сегмента действительно может оказаться выше, чем по всей аудитории: на этом и основан смысл персонализации. Но сегмент должен пройти независимую проверку.
Предположим, есть историческая рандомизированная кампания с одинаковой вероятностью назначения воздействия для всех клиентов. Обучаем модель и выбираем порог на одних данных. На отдельной кампании или отложенной части применяем замороженное правило отбора и к treatment, и к control. Внутри выбранного сегмента сравниваем конверсии.
Именно такой смысл имеет одна из реализаций uplift@k: разность конверсий treatment и control среди верхней части общего ранжированного списка. При неодинаковых вероятностях назначения простая разность может не подходить — оценивание должно учитывать дизайн. scikit‑uplift: uplift@k.
Для будущей кампании важны сопоставимость предложения, аудитории и условий, а не только высокий результат на старых данных. Вместе с точечной оценкой нужны диапазон неопределённости и проверка калибровки эффекта по сегментам. Не следует выбирать лучший порог на том же финальном тесте, по которому затем объявляется результат.
Qini и AUUC полезны для оценки ранжирования по эффекту. Но площадь под Qini‑кривой — не прибыль и не число дополнительных покупок конкретной кампании. Например, qini_auc_score в scikit‑uplift возвращает нормированный коэффициент. Чтобы говорить о рублях, нужно вернуть в расчёт охват, исходы, маржу и расходы. scikit‑uplift: Qini AUC.
Хорошая кампания и полезная модель — тоже не одно и то же
Предположим, после модельного отбора акция принесла дополнительные 130 тысяч рублей относительно отсутствия контакта. Отлично. Но существовавшее правило «выбрать клиентов с недавней покупкой в категории» могло принести 150 тысяч при сопоставимых условиях.
Тогда кампания полезна, а замена старой политики новой — нет.
Чтобы измерить добавленную ценность модели, нужна другая разность:
ΔValue(model) = Profit(new_policy) − Profit(current_policy)
− дополнительные расходы на использование модели
Корректный онлайн‑дизайн: сначала случайно назначить клиентов из общей допустимой аудитории в две политики, затем дать каждой политике выполнить свой отбор. Сравнивать чистый результат на всех назначенных клиентов, включая тех, кому соответствующая политика ничего не отправила. Сравнение только получателей смешивает эффект политики с различиями отобранных аудиторий.
Если общий бюджет ограничен, до старта нужно определить сопоставимые условия для веток. Для неравных размеров веток нельзя просто вычесть их сырые суммы прибыли: сравнивают результат на единицу рандомизации либо оценивают результат на общей популяции.
Зачем тогда глобальная контрольная группа
Глобальный holdout отвечает ещё на один вопрос: какой суммарный эффект даёт оговорённая CVM‑программа на выбранном горизонте? Контроль отдельной кампании отвечает за конкретное воздействие, а тест политик — за преимущество нового способа отбора. Эти конструкции нельзя незаметно подменять друг другом. Аналогичное различие между совокупным holdout и тестом отдельного изменения описано в документации экспериментальной платформы Statsig. Holdouts.
Схема 3. Один из возможных способов развести два исследовательских вопроса. Тест политик проводится вне глобального holdout.
Здесь возникает соблазн ежемесячно «освежать» контроль, чтобы его поведение снова стало похожим на поведение остальных клиентов. Но изменение поведения — не обязательно поломка эксперимента. Если коммуникации увеличивают частоту покупок, разница в частоте может быть искомым эффектом.
Возможный дизайн — заранее выбрать горизонт, стабильно назначить клиентов в группы и задать правила включения новых клиентов. Не переводить человека в другую ветку только потому, что у него изменился RFM‑сегмент. Не удалять из анализа всех переставших покупать: сам отток может зависеть от воздействий.
Это не означает, что контроль может жить бесконечно. Есть остаточные эффекты, потери наблюдений, нарушения назначения и ограничения бизнеса. Однако универсального «срока годности» по одному тесту распределений нет. Изменение контрольной группы между августом и сентябрём само по себе не доказывает, что сравнение treatment и control в сентябре стало некорректным.
Репрезентативность для целевой аудитории и сопоставимость веток — тоже не одно и то же. Две хорошо сбалансированные VIP‑группы могут дать аккуратную оценку для VIP, но не для всей базы.
И последнее: p‑value выше 0,05 не доказывает эквивалентность. Если используется пересэмплирование ради баланса, критерий задаётся заранее по предэкспериментальным данным; полученный дизайн нужно учитывать при выводах. Это осмысленная rerandomization, а не поиск удобного результата. Morgan & Rubin, Li, Ding & Rubin.
А если клиентов много, но истории коммуникаций нет?
Пусть в базе 100 тысяч клиентов с транзакциями, но нет истории нужного воздействия. Можно ли сразу обучить uplift скидки?
Сам размер базы не создаёт отсутствующий контрфактический сигнал. Можно прогнозировать наблюдаемое продуктовое действие — например, покупку в следующие 14 дней — если есть корректные признаки и целевая переменная. Но это прогноз естественной склонности, не оценка эффекта ещё не исследованной коммуникации.
Особенно странно в такой постановке обещать модель клика по ссылке: сначала придётся объяснить, откуда взялась метка клика по коммуникации, которой раньше не было.
Практический старт — простая политика и ограниченный эксперимент. Нужно фиксировать допустимость участия, назначение предложения, фактическую доставку, расходы и итоговое действие. Не смешивать назначение с фактом открытия сообщения: открытие уже зависит от поведения клиента.
При маленькой базе вопрос не сводится к «тысяча — мало, сто тысяч — достаточно». Важны число целевых событий, длительность наблюдения, сложность модели и минимальный эффект, который можно заметить. Если мощности не хватает, пилот остаётся исследовательским этапом. Это полезный результат, но не доказательство экономического преимущества.
Что стоит принести продакту вместо одного красивого uplift
Я бы свёл результат подготовки кампании к короткому паспорту:
|
Поле |
Что должно быть определено |
|---|---|
|
Решение |
Кому, какое предложение и по какому каналу назначаем |
|
Горизонт |
Когда считаем покупки, расходы и отложенный эффект |
|
Baseline |
Нет контакта, текущая политика или другая альтернатива |
|
Прогноз |
Охват, дополнительные покупки, расходы, чистая прибыль |
|
Неопределённость |
Насколько надёжны оценки и где модель экстраполирует |
|
Проверка |
Единица рандомизации, метрики, бюджет и критерий решения |
Вопрос «сколько денег даст модель?» не требует вспомнить редкий алгоритм. Он требует связать прогноз с действием, действие — с причинным эффектом, эффект — с расходами, а всё вместе — с корректным сравнением.
Пока эта цепочка не собрана, у нас есть модель. Когда собрана и проверена — появляется основание менять политику.
А что у вас чаще ломается на этом переходе: калибровка эффекта, расчёт маржи или экспериментальный дизайн?
Автор: O_oscar


