VWE (Variance Weighted Estimator) - как еще один метод снижения дисперсии.



🚙 Зачем это нужно?



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



💡 Основная идея



Дать пользователям с меньшей дисперсией метрики больший вес для снижения общей дисперсии эффекта.



🖥 Как реализовать?



Предположим, мы хотим оценить ARPU и применить к выручке на пользователя для того чтобы снизить дисперсию. Основная реализация заключается в том, что мы смотрим на то, как изменялась метрика в предпериоде и тем самым мы знаем ее дисперсию и как следствие вес. Затем, мы берем вес для метрики на пользователя, равный 1 / дисперсию, тем самым становится очевидно, что при больших дисперсиях вес становится меньше и затем рассчитываем среднее в группе A и группе B. Код который можно реализовать у себя ниже при сплите 50 / 50 с историей в 21 день (это также можно поресерчить, например, если у нас есть бОльшая история по пользователям, будет меньшее смещение, как мне кажется). Чем-то похоже на стратификацию, где каждой страте мы присваиваем вес, только здесь вес рассчитывается на истории пользователя:



import numpy as np

import pandas as pd



n_users = 1000

days = 21

pre_experiment_revenue = np.random.normal(loc=5, scale=2, size=(n_users, days))



control_group_revenue = np.random.normal(loc=5, scale=2, size=500)

treatment_group_revenue = np.random.normal(loc=5.5, scale=2, size=500)



pre_experiment_df = pd.DataFrame(pre_experiment_revenue, columns=[f'day_{i+1}' for i in range(days)])

pre_experiment_df['user_id'] = np.arange(n_users)



experiment_df = pd.DataFrame({

'user_id': np.arange(n_users),

'group': ['control'] * (n_users // 2) + ['treatment'] * (n_users - n_users // 2),

'revenue': np.concatenate([control_group_revenue, treatment_group_revenue])

})



data = pd.merge(experiment_df, pre_experiment_df, on='user_id')

data['user_variance'] = data[[f'day_{i+1}' for i in range(days)]].var(axis=1)

data['weight'] = 1 / data['user_variance']

data['weighted_revenue'] = data['revenue'] * data['weight']




👎 Минусы VWE:



Аномалии могут поломать оценку

Метод может быть чувствителен к аномальным значениям в предэкспериментальных данных, что может привести к некорректным оценкам весов



Необходима история по пользователям, должна быть богатая история по действиям, например, когда замеряем CTR

VWE требует значительного объема предэкспериментальных данных для точного расчета дисперсий и весов. В случае недостатка данных, результаты могут быть менее надежными



Может давать смещение

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



Можно использовать с CUPED с уже перевзвешенными значениями. В статье от Facebook удалось добиться следующих результатов по снижению дисперсии в %.



CUPED only - 37,24%

VWE only - 17,31%

CUPED + VWE - 48,38%




На стратификации не смотрели, как я понимаю, но можно было бы еще, наверное снизить либо есть какие-то ограничения про которые я не знаю. А с Ratio-метрикой так вообще прикол: линеаризируем, VWE, CUPED, стратификацию



Этот метод еще освещался на Avito Analytics Meetup + был разбор статьи на YouTube



😉 Ставьте реакции, если пост был полезен, пишите комментарии. Дальше разберем стратификацию и линеаризиацию