
Привет, Хабр! Меня зовут Ринат Валеев, я старший аналитик в R&D-команде VK Видео.
Команде любого видеосервиса важно оценивать, какой эффект видеоконтент оказывает на аудиторию. Это нужно, чтобы оптимизировать продукты, повышать вовлечённость пользователей, увеличивать конверсию и экономить ресурсы на производстве материалов. В рамках стратегии непрерывного развития сервиса такие задачи решаем и мы в VK Видео.
В этой статье покажу, как мы адаптировали метод propensity score под задачи видеосервиса, автоматизировали расчёты и собрали на их основе удобный self-service инструмент.
Начнём с задачи
Команда аналитики VK Видео работает на пересечении трёх областей: математики, машинного обучения и дата-инженерии. Многие задачи требуют одновременно понимать поведение пользователей, уметь строить ML-модели и использовать современные методы статистики для корректной интерпретации данных.
Один из типичных кейсов — оценить, как выход нового контента влияет на пользователей видеосервиса. Например, появился новый эпизод «Натальной карты» с Джиганом — и нам нужно понять, как он повлиял на конкретного пользователя. Стал ли он проводить больше времени в сервисе, начал ли смотреть другие эпизоды, увеличилась ли глубина потребления и как в целом изменилось его поведение после взаимодействия с видео?
У нас есть данные о пользователях до и после релиза, а также информация о самом контенте: кто, когда и что смотрел, как долго, на каких поверхностях (имеем в виду — где смотрят контент: например, «Рекомендации», «Тренды», «Главная»).

Кажется, что с этими данными проще оценить влияние эпизода на поведение пользователя. Однако способов сделать это корректно немного, и у каждого из них свои ограничения. Какие подходы могут быть релевантны для такой задачи:
Сравнение среднего «до» и среднего «после». Подход простой, но ошибочный. Такое сравнение не учитывает другие переменные, которые могли измениться вместе. К тому же есть фактор случайности и проблема временных рядов (сезонность, тренд).
А/B-эксперимент. Можно засемплировать случайную выборку пользователей, показать им эпизод «Натальной карты» с Джиганом и затем сравнить их метрику с метрикой аналогично сформированной контрольной группы, которая эпизод не видела.
Но здесь возникает несколько вопросов. Во-первых, VK Видео — это сервис, где любой пользователь может посмотреть любой ролик. Мы не ограничиваем контент, например, по регионам или каким-либо другим признакам. Поэтому невозможно провести классический рандомизированный эксперимент на уровне ролика как объекта воздействия: контрольной группы у нас просто нет.
Во-вторых, постфакт-эффект. Мы анализируем уже произошедшие события, а не будущее поведение, поэтому не можем контролировать воздействие и временные рамки, как в стандартном A/B-тесте.
Ухудшающий A/B-тест. Он предполагает намеренное ухудшение части пользовательского опыта (например, удаление контента), чтобы измерить влияние этого ухудшения на метрики. В нашем случае такой подход неприменим, потому что само воздействие — это факт просмотра эпизода. Когда пользователь уже посмотрел видео, отключить воздействие задним числом невозможно. Даже если мы удалим ролик, это не изменит того, что просмотр уже состоялся.
Кроме того, удаление эпизода вряд ли даст измеримый эффект: большинство пользователей смотрят такие ролики один раз и не возвращаются к ним. А те, кто всё же вернулся, ожидают, что смогут продолжить просмотр с места, на котором остановились. Если в этот момент ролика не окажется, это будет выглядеть как неконсистентное поведение сервиса и ощутимо ухудшит пользовательский опыт. Наконец, часть пользователей просто найдёт тот же эпизод через поиск.
Ни один из вариантов не подходил под наши задачи. Поэтому мы решили идти другим путём и обратились к доказательной лестнице.
Что нам даёт доказательная лестница
Доказательная лестница — иерархия методов, которая ранжирует методы оценки эффекта по степени надёжности выводов о причинно-с��едственных связях.
На нижних уровнях находятся простые описательные сравнения, где группы формируются естественным поведением пользователей и поэтому сильно смещены. Выше — методы, которые используют структуру данных и позволяют частично компенсировать это смещение. Ещё выше — алгоритмы, которые искусственно создают корректную контрольную группу и приближают данные наблюдений к A/B-тесту. На вершине лестницы — рандомизированные A/B-эксперименты, где распределение по группам определяется случайностью.

Мы остановились на алгоритме propensity score.
Propensity score и его возможности
Напомню: мы хотим понять, как повлияло событие, например просмотр видеоролика, на дальнейшее поведение пользователя. Но люди сами выбирают, как им взаимодействовать с платформой: кто-то смотрит часто, кто-то редко, кто-то любит этот жанр, кто-то нет. Из-за этого группы «Те, кто посмотрел» и «Те, кто не посмотрел» обычно сильно различаются, и прямое сравнение между ними даёт очень смещённый результат.
Чтобы получить корректную оценку, нам нужен механизм, который позволяет сформировать для каждого пользователя из тритмент-группы двойника. Это пользователь из контрольной группы, который по своим характеристикам с высокой вероятностью мог попасть в тритмент, но в итоге там не оказался. Такой механизм и даёт propensity score.
Propensity score (PS) — это числовая оценка вероятности попасть в тритмент-группу, рассчитанная на основе поведения пользователя до момента события.
По сути, PS сжимает множество наблюдаемых признаков — активность, аффинити, источники трафика, время использования, устройство и так далее — в одно число от 0 до 1. Пользователи с одинаковым PS считаются одинаково вероятными кандидатами в тритмент, даже если фактически один из них посмотрел видео, а другой нет.
Это даёт ключевое упрощение: мы контролируем не всех конфаундеров по отдельности, а только одно число — propensity score.
Если PS одинаков, то пользователи сопоставимы по всем наблюдаемым факторам, влияющим на назначение в тритмент.
Далее мы сравниваем пользователей именно по значениям PS, а не по множеству исходных признаков. Это можно сделать при помощи мэтчинга или через взвешивание.
В результате получаем две группы: тритмент (исходная) и контроль (сформированная на основе похожести propensity score). Они сбалансированы по наблюдаемым характеристикам и поэтому подходят для корректного сравнения.
Почему мы остановились на алгоритме propensity score и вывели его в инструмент self-service
Мы не рассматриваем propensity score как замену A/B-тестам, а используем его там, где эксперимент провести невозможно, потому что нельзя проконтролировать назначение тритмента. В VK Видео пользователь может свободно выбрать любое видео, поэтому мы не можем изолировать часть аудитории от тритмента и обеспечить рандомизацию. Это делает классические A/B-эксперименты неприменимыми, хотя потребность в причинно-корректной оценке эффекта остаётся.
Даже если бы мы могли запустить A/B-эксперимент на контенте, мы столкнулись бы с целым набором методологических трудностей, которые не всегда очевидны на первый взгляд. Главная из них — контентные продукты обладают выраженной сетевой природой: поведение одних пользователей напрямую зависит от поведения других. Стриминговые платформы сформировали у людей желание не только смотреть контент, но и делиться им, если он понравился.
И здесь возникает проблема: чем дольше идёт эксперимент, тем сильнее становится взаимное влияние между группами. Тритментная группа влияет на контрольную — это называется spillover-эффектом. Изменённые сигналы из одной группы начинают проникать в другую через user-to-user взаимодействия — так эффект перетекает между группами. А это нарушает валидность результата A/B-эксперимента.
Чтобы уменьшить этот эффект, эксперимент нужно искусственно ускорять. На стриминговых и видеоплатформах с персонализированной выдачей это можно сделать через модификацию ранжирования в выдаче. Но это приводит к новой проблеме: экспериментальные вмешательства могут вытеснять наиболее релевантные рекомендации с экрана. Это может ухудшить пользовательский опыт, если люди получат менее подходящий им контент.
В такой ситуации даже технически возможный A/B-эксперимент на контенте становится методологически хрупким и рискованным. Поэтому мы хотели подобрать инструмент, который позволит получать причинно-корректные оценки без влияния на пользовательский опыт.
Сам же self-service позволяет стандартизировать и ускорить аналитику. Раньше процесс выглядел так. Стейкхолдер приходил к аналитику и просил: «Посчитай эффект от этого ролика, пожалуйста». А дальше методологию оценки эффекта полностью определял аналитик, опираясь на личную экспертность и интуицию. Затем начинался долгий, ручной и не масштабируемый процесс, который каждый аналитик выполнял с нуля. При этом большая часть времени уходила не на сам расчёт эффекта, а на то, чтобы понять, какие переменные контролировать, чтобы оценка эффекта была честной. Поиск конфаундеров мог занимать часы или даже дни, и каждый аналитик делал его по-своему.
Ещё факторы риска — высокий порог входа в Causal Inference и опасность упустить важные допущения и предпосылки. Они тоже учащают ошибочные оценки и приводят к нарушению каузальных выводов.
Все перечисленные сложности — лишь часть проблем, с которыми мы сталкивались, пытаясь получить причинно-корректные выводы в контентной среде. На практике их ещё больше:
нестабильные выборки
нет единых стандартов фич
есть проблемы с воспроизводимостью
неоднородные поверхности
необходимость постоянно валидировать качество данных и многое другое
Именно поэтому мы хотели создать единый, стандартизированный, воспроизводимый self-service инструмент на базе методов propensity score. На нём была бы вся техническая и методологическая сложность, а пользователю оставалось только интерпретировать результат.
Вот почему мы выбрали propensity score и зачем нам понадобился self-service. Расскажем, как устроена архитектура этого инструмента и за счёт чего он обеспечивает стабильность, масштабируемость и прозрачность анализа.
Архитектура нашего решения
Наш self-service инструмент состоит из трёх блоков:
Входные параметры
Core — PSM-движок
Выходные параметры
И всё это обёрнуто в интерфейс чат-бота. Пользователь просто задаёт вопрос в чате, а бот запускает весь движок под капотом и возвращает готовый отчёт в несколько секунд.

Остановимся на каждом из них чуть подробнее.
Входные параметры
В нашем случае есть три обязательных входных параметра:
Объект — выбранное видео, которое мы хотим проанализировать (его идентификатор).
Тритмент — формальное определение того, что считается просмотром в рамках анализа. В разных командах это может означать загрузку плеера, начало воспроизведения, просмотр 30 секунд и так далее.
Метрика — целевой показатель, на который мы оцениваем влияние (например, watch time, глубина просмотра, длина сессии и так далее).

Core
Под капотом Core-компонента PSM-движок решает множество задач. Пройдёмся по каждому этапу работы системы.
Проверка данных. Данные проверяются и валидируются с помощью кастомных airflow-операторов от DWH VK Видео.
Сбор признаков. На этом этапе инструмент формирует набор признаков, которые будут использоваться для оценки propensity score. Критически важно правильно выбрать признаки, потому что именно они позволяют корректно учесть различия между группами и снять влияние конфаундеров.
Поскольку признаки напрямую зависят от выбранной метрики и тритмента, мы провели исследование, выявили все релевантные конфаундеры и собрали словарь вида «метрика — набор конфаундеров». На основе этих конфаундеров формируются конкретные признаки, которые используются в модели.
Прежде чем добавить новую метрику в инструмент, мы изучаем её причинные зависимости, определяем соответствующие конфаундеры и только затем проектируем нужные признаки.
Формирование выборки. Под формированием выборки мы понимаем каузальное допущение, которое есть у causal inference.
Всё начинается с overlap — допущения, согласно которому мы гарантируем, что у каждого пользователя есть шанс попасть и в тритмент, и в контрольную группу. С тестовой группой всё понятно — это пользователи, которые просмотрели видео. А вот с контрольной группой интереснее. Если тритмент = «просмотрел конкретное видео», то многие пользователи могли просто не увидеть карточку этого видео (например, не заходили во вкладку «Тренды», не подписаны и так далее). И их фактическая вероятность просмотра ≈ 0. Если включить их в анализ, мы нарушим одно из главных допущений Causal Inference — overlap. Поэтому мы принимаем условие, что в выборку включаются только те пользователи, которые видели карточку видео и теоретически могли его посмотреть.

Помните, выше мы говорили, что в видеосервисах пользователи сильно влияют друг на друга, и что это нужно контролировать? Это одно из допущений Causal Inference, которое мы должны соблюдать — SUTVA (Stable Unit Treatment Value Assumption). Согласно ему пользователи не должны взаимно влиять друг на друга, а тритмент должен быть тождественным для всех участников. В контентных системах полностью соблюсти SUTVA, к сожалению, невозможно: можно лишь пытаться частично контролировать нарушения.
Рассмотрим на примере. Допустим, что после просмотра видеоролика user_1 переслал его своим друзьям, и они тоже посмотрели. Получается, наш тритмент (просмотр видео) влияет не только на user_1, но и на user_5 и user_2. Как мы работаем с этим? Исключаем пользователей, которые посмотрели видео через личные сообщения или по прямой ссылке.

Изоляция эффекта. Следующее предположение, которое мы соблюдаем, — изоляция предыдущего и следующего эффекта. Нам нужно избегать так называемого carry-over effect — ситуации, когда эффект от предыдущего контента перетекает в последующий период и искажает оценку.
Например, пользователь посмотрел исследуемое видео 1 февраля, но 20 января видел выпуск другого шоу, а 2 февраля — ещё одного. И поскольку исследование проводится уже постфактум, сложно понять, просмотр какого именно контента даёт эффект на пользователя.

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

Значение N определяется на следующем этапе.
Определение длительности эффекта. Есть много методологий подсчёта длительности эффекта. Мы смотрим кумулятивную кривую прироста эффекта пользователей и выбираем тот N, после которого кривая выходит на плато и дальнейший прирост мал в сравнении с шумом. То есть хотим понять — эффект ещё растёт или уже стабилизировался и дальше прироста нет.
Мы считаем, что плато наступило, если одновременно выполнены два условия:
Если между соседними точками (например, между 48 ч и 72 ч) прирост эффекта меньше 10% от уже достигнутого — значит, рост замедлился
Если разница между точками меньше погрешности измерений (доверительный интервал включает ноль) — значит, прирост статистически незначим. То есть эффект вроде бы чуть вырос, но это может быть просто случайный шум

Вычисление propensity score. На этом этапе инструмент автоматически присваивает каждому пользователю propensity score — оценку вероятности попасть в тритмент (совершить просмотр). Для расчёта propensity score используется заранее подготовленный набор препериодных признаков в зависимости от типа тритмента и метрики. Пример признаков, которые мы используем:
характеристики активности пользователя
аффинити к каналу
поведение на платформе
жанровые предпочтения
взаимодействие с контентом в период до релиза видео
Эти признаки не включают информацию из постпериода и формируются заранее в стандартизированной витрине.
Далее применяется предобученная ML-модель (у нас это градиентный бустинг), которая возвращает вероятность того, что пользователь мог бы оказаться в тритменте при прочих равных.
Наша цель — не предсказать поведение пользователя, а устранить систематические различия между группами. Поэтому мы не гонимся за идеальной моделью. Сложные модели дают слишком резкие значения PS-скора — много значений очень близко к 0 или 1. Это уменьшает эффективный размер выборки (ESS) и делает веса нестабильными.
Полученные PS-скоры передаются на следующий шаг пайплайна.
Мэтчинг. Не будем подробно останавливаться на мэтчинге — он заслуживает отдельной статьи. Скажем лишь, что в методиках мэтчинга всё крутится вокруг концептов расстояния и похожести. Способы замера расстояний и их сопоставления добавляют различия между методиками мэтчинга.
Мы используем в инструменте не парный мэтчинг, а взвешивание на основе propensity score. Выбираем варианты inverse probability weights (IPW), которые распределяют веса так, чтобы пользователи с похожими значениями PS получали сопоставимый вклад в оценку. При этом у представителей тритмент-группы обычно вес 1. Пользователи из контроля получают больший вес, если они по PS похожи на тритмент, но не попали в него. Это позволяет корректно сравнить группы и снизить селф-селекцию без взрыва весов.
Диагностика. Последний шаг — баланс ковариат.
После взвешивания на основе propensity score инструмент проверяет, насколько хорошо теперь группы тритмента и контроля сопоставимы по всем признакам из препериода. Для этого используется SMD (standardized mean difference) — стандартизированная разница средних между группами. Мы считаем SMD для каждой ковариаты отдельно и анализируем весь их набор. Если SMD превышает порог хотя бы по одной ковариате, это означает, что взвешивание не полностью устранило различия между группами — и полученный баланс неудовлетворителен. В этом случае инструмент помечает, что результат низкого качества: эффект, рассчитанный на несбалансированных группах, нельзя интерпретировать как причинный — мэтчинг и веса не сработали корректно. Если так происходит, инструмент либо делает тримминг PS-скоров, либо использует другой мэтчинг.
Мы используем порог SMD < 0,1 для всех ковариат, который выбрали эмпирически. В экспериментальных тестах на исторических данных платформы именно значение 0,1 давало лучшее сочетание двух критериев:
устойчивости оценок эффекта
стабильности ESS
Более строгие пороги (например, 0,05) сильно сокращали эффективную выборку и ухудшали мощность оценки. Более мягкие (> 0,1) приводили к заметным сдвигам эффекта при повторных запусках на разных семплах. Поэтому порог 0,1 стал оптимальным компромиссом между точностью и стабильностью результата.

Чтобы результаты были наглядными, мы строим график Love Plot. Здесь по горизонтали (ось X) видим стандартизированные разницы средних (SMD), а по вертикали (ось Y) перечислены признаки. График наглядно иллюстрирует разницу между балансами ковариат до и после мэтчинга. До мэтчинга большинство признаков находилось далеко за пределами установленного порога.

Выходные параметры
После сопоставления рассчитываем average treatment effect on the treated (ATT) — средний эффект для тех, кто подвергся воздействию:
где:
— ожидаемое значение метрики
для группы, которая получила воздействие (treatment), при условии, что они действительно находятся в этой группе (T=1)
— гипотетическое ожидаемое значение метрики Y для тех же людей, если бы они не получили воздействие. Здесь мы подразумеваем ситуацию, в которой T = 0 для тех, кто на самом деле находится в группе воздействия
Примечание: ATT — не та же метрика, что и ATE, который мы измеряем в классических A/B-тестах. ATE (average treatment effect ― средний эффект воздействия) учитывает всех пользователей из группы тритмента, даже тех, кто не пользовался тритментом (фичей). В то же время ATT учитывает только тех пользователей, которые пользовались новой фичей.
На выходе мы получаем отчёт с результатами оценки эффекта от видеоконтента в таком виде:
Юнит анализа
Видео
Метрика
Тип тритмента
Тип оценки
Значение оценки
Доверительный интервал
Длительность эффекта
Статзначимость
Conditional independence — почему это работает
Методы, основанные на propensity score, опираются на ключевое предположение conditional independence. Если условиться на набор наблюдаемых признаков X, то назначение пользователя в тритмент или контроль не даёт информации, какими были бы его потенциальные исходы.
Это означает, что после учёта X мы можем рассматривать разницу между пользователями в тритмент- и контрольной группе как эквивалентную разнице, которая возникла бы при случайном назначении в группы. Не потому, что назначение реально случайное, а потому, что все систематические факторы назначения отражены в X и компенсированы мэтчингом (взвешиванием).
Propensity score создаёт ситуацию, структурно эквивалентную A/B-эксперименту: после корректировки по X тритмент и контроль становятся сопоставимыми — как если бы мы рандомизировали пользователей.

Что в итоге
Self-service инструмент, разработанный на основе propensity score, уже помогает нам оценивать эффект от нового видеоконтента на платформе VK Видео. Но мы понимаем, что у этой его версии есть точки роста, поэтому рассматриваем решение как базу для построения более продвинутого и функционального инструмента. Как будет развиваться сервис, расскажем в одной из следующих статей.
