Всем привет! Меня зовут Гриша Крюков, я аналитик в команде антифрода Авито. Расскажу, как использование пользователями нескольких профилей может приводить к неверным бизнес-решениям и почему качественное обнаружение связей между профилями напрямую влияет на качество А/В-тестов. Обсудим проблему на интуитивном уро��не и строго математически докажем ряд утверждений, сопроводив симуляциями на синтетических данных. Статья будет интересна тем, кто увлекается аналитикой данных, А/В-тестами или просто любит математику.

Содержание:

Как мультиаккаунты влияют на A/B-тестирование

A/B-тестирование — это метод анализа, который помогает сравнить два варианта чего-либо, например, веб-страницы, объявления или продукта, чтобы понять, какой из них работает лучше по ключевым метрикам. В этом эксперименте аудиторию случайным образом делят на две группы: тестовую с новой версией продукта и контрольную, в которой всё по-старому. Затем сравнивают поведение этих групп, чтобы оценить влияние изменений.

Подробнее про A/B можно узнать в этой статье.

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

Рассмотрим пару игрушечных примеров

  1. Предположим, на сайте есть пользователи, которые нецензурно ругаются, чем огорчают других пользователей и приводят к их оттоку. Сквернословы так любят ругаться, что продолжают это делать несмотря на любые предупреждения. Наш аналитический отдел решает провести А/В-тест. Пользователи в тестовой группе получают предупреждение «Мат — это плохо» каждый раз, когда используют недопустимые слова.

    Часть нарушителей устанет от таких странных предупреждений и перейдёт на профили, которые находятся в контрольной группе. Они используют свои старые аккаунты или создадут новые. Что мы увидим в данных? Пользователи в тестовой группе ругаются реже, ура, катим фичу на всех! 

    Но что произойдёт, когда предупреждения начнут уходить всем подряд? Люди продолжат ругаться в том же объёме, что и до теста, ведь в действительности предупреждения не заставляют их фильтровать лексику — максимум стимулируют перейти на профиль без надоедливых предупреждений. Получается, мультиаккаунты пользователей испортили А/В-тест, что привело к неверному бизнес-выводу.

  2. Представим, что вы — пользователь приложения и у вас есть два профиля, которые вы активно используете. В один прекрасный день компания решает провести А/В-тест, и ваши профили оказываются в разных группах. Поэтому, например, в одном и том же сценарии мы видим разные цвета кнопок с разных профилей. Но ведь мы можем начать чаще пользоваться тем профилем, где дизайн лучше. Но так бывает не всегда.

    Возможна другая ситуация. У вас один профиль, и он попал в контрольную группу. К вам приходит друг, который попал в тестовую группу, и рассказывает, какое крутое изменение появилось в приложении. Вы тоже хотите крутую фичу, поэтому создаёте новый профиль, и ваша новая учётная запись может попасть в тестовую группу.

Суть явления понятна, но почему оно может быть негативным для компании? Да, если пользователи будут чаще пользоваться профилями из тестовой группы, то метрики из этой группы могут быть завышены. Что в этом плохого? Пользователи перетекают в те профили, где им удобнее — то есть «голосуют ногами». Казалось бы, если пользователи готовы менять профиль, чтобы получить тестируемое изменение — это мощный маркер, что им всё нравится, а значит новинку можно выкатывать на всех.

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

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

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

Почему бы просто не сделать единицей теста не профиль, а мультиаккаунт? И теперь, сколько бы профилей пользователь ни создал, он попадёт в одну и ту же группу — а значит, проблема решена.

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

Ошибка первого рода (α) — ситуация, когда отвергнута верная нулевая гипотеза (об отсутствии связи между явлениями)

Ошибка второго рода (β) — это ситуация, когда принята неверная нулевая гипотеза.

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

Почему мультиаккаунты портят работу стандартных A/B-тестов

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

n=(Vari+Var2)×(zα/2+zβ)²/MDE²

  • n — размер выборки для каждой группы теста;

  • Vari — дисперсия группы i;

  • zα/2, zβ — значения стандартного нормального распределения, соответствующие заданным уровням значимости и мощности;

  • MDE — минимальный дет��ктируемый эффект. Это минимальный размер эффекта, который мы сможем задетектировать в рамках A/B теста при заданных значениях уровня значимости и мощности.

Проверим на синтетических данных. Мы хотим получить размер выборки, чтобы наша мощность была не менее 80% при вероятности ошибки первого рода не выше 5% (α = 0.05, β = 0.2). Пусть в контроле у величины нормальное распределение со средним 0 и дисперсией 1, а в тесте — нормальное распределение со средним 0.5 и дисперсий 1, то есть эффект составляет половину стандартного отклонения. Проведём симуляции A/A/B-тестов и замерим, как часто мы совершаем ошибки первого и второго рода при разных размерах выборки. Видим, что теоретический расчёт необходимого размера выборки оказался довольно близок к реальному размеру выборки, на котором мы получили желаемую мощность.

Распределения в тестовой и контрольной группах
Распределения в тестовой и контрольной группах
Зависимость вероятностей ошибок первого и второго рода в зависимости от размера выборки
Зависимость вероятностей ошибок первого и второго рода в зависимости от размера выборки

Всё работает отлично! Почему бы просто не использовать эту формулу, но взять в качестве единицы наблюдения не профиль, а мультиаккаунт? Есть фундаментальные отличия. 

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

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

Gui, Huan, et al. «Network a/b testing: From sampling to estimation» Proceedings of the 24th International Conference on World Wide Web. 2015.

Liu, Yang, et al. «Cluster-adaptive network a/b testing: From randomization to estimation» Journal of Machine Learning Research 25.170 (2024): 1-48.

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

Проблема 1. Из-за ошибок кластеризации внутри одного мультиаккаунта может оказаться несколько пользователей.

Проблема 2. Из-за неполной информации о связях профилей разные аккаунты одного пользователя могут попасть в тестовую и контрольную группы.

Последовательно погрузимся в каждую из двух проблем.

К чему ведёт объединение разных пользователей в одну единицу тестирования

Построим модель. Поделим кластеры на тестовую и контрольную группы, в каждой группе по n кластеров. При этом внутри одного кластера могут оказаться K пользователей, где K — случайная величина, принимающая целые положительные значения. Ki =1, значит, что в i-ом кластере ровно один аккаунт. В идеальном мире K=1 для всех кластеров.

Каждый пользователь имеет свои индивидуальные значения из распределений XC и XT, которые он показывает в контрольной и тестовой группах соответственно. 

Цель: измерить эффект нашей инициативы, то есть разницу средних: E[XT]–E[XC], где E[X] —математическое ожидание случайной величины X.

Однако проблема в том, что при таком дизайне теста мы наблюдаем не величины из распределения X. Дело в том, что когда K пользователей попадают в один кластер, мы наблюдаем сумму K величин из распределения X. Иными словами, мы наблюдаем Yi, где Y = X1+X2+... +Xk.

Чтобы понять, как это преобразование влияет на результаты теста, изучим связь X и Y.

Эффект на матожидание. Y — это сумма из K величин, взятых из распределения X. Воспользовавшись независимостью K, X, мы применяем тождество Вальда и получаем:

E[Y]=E[K]E[X]

Вывод. Наблюдаемый эффект растёт пропорционально среднему числу пользователей на кластер. Хорошая новость, что направленность метрик сохраняется: если нет разницы между тестом и контролем в метрике X, то её не будет и в метрике Y; если есть эффект на метрику X, то будет эф��ект и на метрику Y с тем же знаком.

Эффект на дисперсию. Дисперсия величины Y вырастет по сравнению с дисперсией величины X, что может негативно сказаться на длительности теста.

Var(Y)=Var (X) × E [K] + (E [X])² × Var(K)

Заметим, что при константном K=1 (идеальный мир без ошибок кластеризации) E[K] = 1, Var(K) = 0 , и при подстановке в формулу мы получаем верное тождество Var(Y) = Var(X), поскольку в идеальном мире X и Y совпадают.

Эффект на необходимый объём выборки. Суммаризируем эффекты и посмотрим, как они влияют на размер выборки, необходимый для детекции эффекта с требуемой мощностью.

Рассмотрим первый пример из вступительной части. Пусть в контроле величина X имеет нормальное распределение со средним 0 и дисперсией 1, а в тесте — нормальное распределение со средним 0.5 и дисперсий 1, то есть эффект составляет половину стандартного отклонения.

Подумаем, какое распределение лучше взять для моделирования числа пользователей внутри мультиаккаунта (K). Из нашего знания о реальных сетях следует, что размеры их кластеров также зачастую подчиняются степенному закону. Поэтому давайте предположим, что разница «ожидания» и «реальности» также подчиняется степенному закону.

Пример распределения, которое принимает целые положительные значения и подчиняется степенному закону: распределение Ципфа (дзета-распределение). 

Жми сюда!

Занятный факт

При вычислении моментов этого распределения активно используется дзета-функция, та самая, про которую сформулирована знаменитая гипотеза Римана — одна из семи задач тысячелетия. 

Вернёмся к примеру из начала статьи с нормальными распределениями. Давайте для модели положим, что K имеет дзета-распределение с параметром s=4.1. В этом случае E[K] ≈ 1.1, то есть на один кластер в среднем приходится 1.1 реальных пользователей.

Зависимость вероятностей ошибок первого и второго рода в зависимости от размера выборки, где количество реальных людей внутри одного кластера имеет дзета-распределение с параметром s=4.1
Контрольная группа: нормальное распределение со средним 0 и дисперсией 1
Тестовая группа: нормальное распределение со средним 0.5 и дисперсией 1

Получаем парадоксальный на первый взгляд результат:

  1. В ситуации полной информации (1 кластер = 1 реальный пользователь) нам нужно 63 кластера на группу. 

  2. В ситуации, где на кластер приходится в среднем 1.1 реального пользователя, нам нужно 59 кластеров, что меньше 63! 

Неужели объединение разных пользователей в один кластер может уменьшить время теста? Как бы не так! Мы не учли, что в неидеальном мире на один кластер приходится 1.1 пользователь, поэтому матожидание числа пользователей в каждой из групп 1.1 × 59 = 64.9, что больше 63 пользователей на группу при полной информации.

Интересно, что при сокращении эффекта различия могут стать более значительными. Поменяем целевую величину X, взяв логнормальные распределения с эффектом на среднее в 10%.

Зависимость вероятностей ошибок первого и второго рода в зависимости от размера выборки, где количество реальных людей внутри одного кластера имеет дзета-распределение с параметром s=4.1Контрольная группа: логнормальное распределение с параметрами s=0.5, scale = eТестовая группа: логнормальное распределение с параметрами s=0.5, scale = e^1.1
Зависимость вероятностей ошибок первого и второго рода в зависимости от размера выборки, где количество реальных людей внутри одного кластера имеет дзета-распределение с параметром s=4.1
Контрольная группа: логнормальное распределение с параметрами s=0.5, scale = e
Тестовая группа: логнормальное распределение с параметрами s=0.5, scale = e^1.1

Теперь, ��сли бы мы слепо воспользовались размером выборки для величины X при полной информации, то получили бы мощность всего 60% вместо желаемых 80%.

Перейдём от частных примеров к общим результатам. Правда ли, что ожидаемое число реальных пользователей при неполной информации о кластерах больше, чем в идеальном мире? Да, и мы даже знаем, на сколько.

Утверждение. Пусть в тестовой и контрольной группе величина X имеет одинаковые дисперсии. Тогда требуемый размер выборки увеличится на Var(K) / (E[K] × (CVₓ)²) × 100%. Где за CVₓобозначен коэффициент вариации — отношение стандартного отклонения X к матожиданию X. Иными словами, процент увеличения ожидаемого числа пользователей по сравнению с реальным миром положительный и пропорциональный Var(K) / E[K].

Это всё здорово, но интуитивно не ясно, как связаны дисперсия и матожидание. Давайте сделаем опору на интерпретируемую величину: среднее количество реальных пользователей на кластер E[K]. Посмотрим, как переменные зависят от E[K], где для расчётов используем распределение Ципфа с требуемым матожиданием.

Изменение требуемого числа кластеров и реального числа пользователей с ростом среднего числа реальных людей на один кластер
Контрольная группа: логнормальное распределение с параметрами s=0.5, scale = e
Тестовая группа: логнормальное распределение с параметрами s=0.5, scale = e^1.1

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

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

Как влияют на тест связи между аккаунтами, которые мы не видим

Отметим, что тема влияния связей между аккаунтами на эффект теста уже поднималась в литературе. Например, в статье The effect of alter ego accounts on a/b tests in social networks авторы показывают, что использование альтер-эго (вторых аккаунтов) смещает результаты A/B-тестов. Причём размер смещения зависит от графовой структуры и увеличивается, если растёт частота использования альтер-эго.

Иллюстрация смещения, которое посчитали на различных датасетах. Avery, Katherine, Amir Houmansadr, and David Jensen. «The effect of alter ego accounts on a/b tests in social networks.» Companion Proceedings of the ACM Web Conference 2024
Иллюстрация смещения, которое посчитали на различных датасетах. Avery, Katherine, Amir Houmansadr, and David Jensen. «The effect of alter ego accounts on a/b tests in social networks.» Companion Proceedings of the ACM Web Conference 2024

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

Постановка модели. Пусть у нас N пользователей в тестовой группе и N в контрольной. 

В контроле пользователь i приносит xᵢ, в тесте xᵢ + yᵢ. xᵢ независимы и одинаково распределены по X (распределение контрольной группы), yᵢ независимы и одинаково распределены по Y (распределение прироста от нахождения в тестовой группе). При этом нахождение в контрольной группе для пользователя как минимум не хуже, чем нахождение в тестовой группе. А для некоторых строго лучше, например, условия тестов антифрода, где хотим тестировать меры воздействия на плохих пользователей. В связи с этим у некоторых пользователей возникают стимулы попасть в тестовую группу.

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

Пусть q— доля трафика, которая проходит через первый аккаунт юзера, остальные 1 − q идут через второй. Как такой переток между группами отразится на параметрах теста?

Эффект на матожидание. Будет создано pN новых аккаунтов, они распределятся поровну между группами. Итого в каждой группе окажется N + pN/2 аккаунтов. Это знаменатель нашего матожидания, в числителе будет суммарный доход от всех пользователей в группе.

В контрольной все N юзеров остаются на своих местах, плюс добавляются pN/2 перебежчиков из тестовой группы, которые приносят 1 − q от xᵢ. Итого матожидание в контроле:

(N × E[X] + pN/2 × (1 − q) × E[X])/(pN/2) = E[X] × (1 + (1 − q) × p/2)/(1 + p/2)

В тестовой группе лишь (1 − p)N остаются на местах и приносят xᵢ + yᵢ. Остальные pN приносят q × (xᵢ + yᵢ), после чего создают альтер-эго. pN/2 после создания альтер-эго остаются в тестовой группе и приносят  (1 − q) × (xᵢ + yᵢ) с нового аккаунта (суммарно xᵢ + yᵢ со старого и нового профилей). Поделив числитель и знаменатель на N, получаем формулу матожидания в тестовой группе:

E[X + Y] × (1 − (1 − q) × p/2)/(1 + p/2)

Поэтому наблюдаемый эффект составляет:

E[X + Y] × (1 − (1 − q) × p/2)/(1 + p/2) − E[X] × (1 + (1 − q) × p/2)/(1 + p/2) = (E[Y] − (1 − q) × p/2 × (2E[X] + E[Y]))/(1 + p/2)

Проанализируем результаты. Очевидно смещение. Даже при отсутствии реального эффекта на целевую метрику (т.е. при E[Y] = 0) результат может смещаться в пользу контрольной группы — эффект составит: −(1 − q) × p * E[X]/(1 + p/2), его знак совпадает с E[X].

Положительный эффект (E[Y] > 0) также может исказиться: как минимум уменьшиться, а при больших p и малых q даже развернуться в противоположную сторону!

Выведем это формально. Пусть эффект составляет k от дохода в контрольной группе, то есть E[Y] = kE[X], k > 0, E[X] > 0. Тогда условие на то, что эффект не поменяет знак:

k × E[X] − (1 − q) × p/2 × (2E[X] + k × E[X]) > 0

Что при k > 0, E[X] > 0 эквивалентно:

k − (1 − q) × p/2 × (2 + k) > 0

Выражение слева растёт с ростом k (производная по k больше нуля), q и снижением p. Это значит, что смещение наиболее сильное при:

  • низком размере эффекта (маленькое k);

  • высокой вероятности создания нового аккаунта, который мы не отследим по зацепкам (высокое p);

  • и высокой скорости создания нового аккаунта после начала теста (низкое q).

Другое любопытное наблюдение состоит в том, что эффект может быть не только заниженным, но и завышенным. Пусть E[X] < 0, 0 < E[Y] < 2E[X]. Тогда есть положительный эффект, и при этом наблюдаемый эффект завышается:

(E[Y] − (1 − q) × p/2 × (2E[X] + E[Y]))/(1 + p/2) > E[Y].

Влияние на параметры теста. Мы уже поняли, что результаты смещены — это главный результат. Дисперсия также исказится, однако в этом исследовании приводить теоретические выкладки не будем — мы уже увидели, что главная беда не в росте дисперсии, а в смещении эффекта. Приведем расчёты на симуляциях. Для X выбрали логнормальное распределение с параметрами  s = 0.5, scale = 100. Для Y выбрали логнормальное распределение с параметрами  s = 0.25, scale = 10 (эффект E[Y] примерно равен 10).

Эффекты от увеличения вероятности создания нового аккаунта и скорости перехода на новый аккаунт
Эффекты от увеличения вероятности создания нового аккаунта и скорости перехода на новый аккаунт

Мы получили подтверждение расчётов: смещение действительно есть, и оно растёт с ростом p и снижением q. Интересна мощность. При отсутствии альтер-эго (p=0) мощность соответствует желаемым 80%. С ростом p мощность сначала снижается, а потом неожиданно вырастает под 100%. Парадокс в том, что при высоких p мы будем «мощно» принимать... неправильные решения. Ведь на метрику будет влиять сам тест!

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

Вероятно, параметр скорости осознания того, что нужно завести второй аккаунт (q) почти неподвластен нашему влиянию. Он очевидно зависит от эффекта в тесте: если это слишком явно и неприятно для пользователя, он быстрее решит перейти в дополнительный аккаунт, чтобы нейтрализовать эффект. Хочется порекомендовать делать эффекты менее болезненными и заметными для пользователя. Однако иногда нам надо произвести сильный эффект, чтобы убедить пользователя перестать совершать нежелательные действия.

Наиболее перспективным выглядит снижение p. Можно разложить вероятность создания невидимого для нас аккаунта на множители: p = p_new × p_invis, где
p_new — вероятность создания пользователей нового аккаунта,
p_invis — вероятность, что мы не увидим связь между старым и новым аккаунтом. Как и в случае с q, p_new зависит от меры воздействия на пользователей в тестовой группе. Чем неприятнее, тем выше этот параметр. А вот p_invis напрямую зависит от качества кластеризации, а именно от полноты. В идеальном мире с полной информацией о кластерах p_invis = 0, что гарантирует полное отсутствие смещения при любых других значениях параметров.

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

Выводы

Мы выяснили, что пользователи с мультиаккаунтами могут искажать результаты A/B-тестов, когда начинают чаще пользоваться тем профилем, который им кажется удобнее. Удобство, в свою очередь, может прямо зависеть от того, в тестовой или контрольной группе он оказался.

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

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

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

Если вы интересуетесь аналитикой и хотите получать больше прикладной и просто интересной профильной информации — подписывайтесь на телеграм-канал «Коммуналка аналитиков».

Узнать больше о задачах, которые решают инженеры AvitoTech, можно по этой ссылке. А вот тут мы собрали весь контент от нашей команды — там вы найдете статьи, подкасты, видео и много чего еще. И заходите в наш TG-канал, там интересно!