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:Аномалии могут поломать оценку
Метод может быть чувствителен к аномальным значениям в предэкспериментальных данных, что может привести к некорректным оценкам весов
Необходима история по пользователям, должна быть богатая история по действиям, например, когда замеряем CTRVWE требует значительного объема предэкспериментальных данных для точного расчета дисперсий и весов. В случае недостатка данных, результаты могут быть менее надежными
Может давать смещениеПри расчете в оценке среднего мы можем получить небольшое смещение из-за перевзвешивания. Другая задача - это получение несмещенной оценки (например, как корректировка средним значением в преэкспериментальной группе при CUPED
Можно использовать с CUPED с уже перевзвешенными значениями. В статье от Facebook удалось добиться следующих результатов по снижению дисперсии в %.
CUPED only - 37,24%
VWE only - 17,31%
CUPED + VWE - 48,38%На стратификации не смотрели, как я понимаю, но можно было бы еще, наверное снизить либо есть какие-то ограничения про которые я не знаю. А с Ratio-метрикой так вообще прикол: линеаризируем, VWE, CUPED, стратификацию
Этот метод еще освещался на Avito Analytics Meetup + был разбор статьи на YouTube
😉 Ставьте реакции, если пост был полезен, пишите комментарии. Дальше разберем стратификацию и линеаризиацию