ZASQL_PYTHON Telegram 301
Анализ экспериментов с Ratio-метриками

Проводя эксперименты, обычно, мы используем базовые методы: t-test, z-test, bootstrap (если данных не так много). Это для одних метрик, но, предположим, мы работаем с метриками-отношения (представляют из себя деление суммы случайной величины X на сумму случайной величины Y).

В этом случае в группе A и группе B у нас нет дисперсии. В самом деле, рассмотрим средний чек - метрика отношения (сумма GMV / количество заказов), CTR (сумма кликов / количество показов). Получаем некоторую метрику Za и Zb для которой мы знаем значение, но дисперсии метрики не знаем.

Отсюда выход:

а) провести бутстрап, чтобы найти распределение этой метрики и узнать распределение статистики
б) бакетировать (меньше по ресурсам, чем бутстрап).
в) применять другие методы (например, линеаризацию или дельта-метод).
г*) что-то другое...

Бутстрап

Для оценки распределения метрики можем использовать выборочные значения в группе A и группе B и найти разницу, таким образом, мы получим «разницу средних». Из минусов: MDE не рассчитать (при дизайне эксперимента), очень долгий расчет при больших выборках, ресурсов может не хватить.

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


def bootstrap_ratio(data, nominator, denominator, group_column, group_value, n_iter=10000):

group_data = data[data[group_column] == group_value]

boot_ratios = []
for _ in range(n_iter):
sample = group_data.sample(len(group_data), replace=True)
ratio = sample[nominator].sum() / sample[denominator].sum()
boot_ratios.append(ratio)

return np.array(boot_ratios)


Бакетизация

Делим также пользователей по бакетам (с их GMV и количеством заказов), распределение метрики будет нормальным, главное, чтобы в бакетах было достаточное количество наблюдений. Мы делаем n-подвыборок (где n - это количество бакетов). Из минусов: сложность работать с маленькими выборками, зависимость от количества бакетов (тонкая настройка).


def bucketize(data, nominator, denominator, n_buckets=50, random_state=42):

data = data.sample(frac=1, random_state=random_state).reset_index(drop=True)
buckets = np.array_split(data, n_buckets)
bucket_ratios = [bucket[nominator].sum() / bucket[denominator].sum() for bucket in buckets]

return bucket_ratios



Пару слов про дельта-метод и линеаризацию.

В общем-то это об одном и том же. Мы хотим найти дисперсию метрики для того, чтобы применить классические методы (например, t-test). В дельта-методе мы корректируем дисперсию на корреляцию двух случайных величин (числителя и знаменателя). Только есть разница: дельта-метод вычисляет дисперсию на уровне выборки сразу, а линеаризация позволяет Ratio-метрику превратить в поюзерную. Результаты сонаправлены.

Дельта-метод


def calculate_ratio_variance(values_numerator, values_denominator):

mean_num = np.mean(values_numerator)
mean_denom = np.mean(values_denominator)
variance_num = np.var(values_numerator, ddof=1)
variance_denom = np.var(values_denominator, ddof=1)

covariance_num_denom = np.cov(values_numerator, values_denominator)[0, 1]

ratio_variance = (
(variance_num / mean_denom ** 2)
- (2 * (mean_num / mean_denom ** 3) * covariance_num_denom)
+ ((mean_num ** 2 / mean_denom ** 4) * variance_denom)
)

return ratio_variance


Линеаризация


# ratio_control - ratio-метрика в контрольной группе (для теста также рассчитывается)

def calculate_ratio_control(numerator_control, denominator_control):
return sum(numerator_control) / sum(denominator_control)

ratio_control = calculate_ratio_control(numerator_control, denominator_control)

def linearization(numerator, denominator, ratio_control):
return numerator - ratio_control * denominator


Дополнительные материалы для ознакомления: первый, второй, третий, четвертый, пятый

Понравился пост? Давайте наберем 150 🐳🐳🐳, если хотите продолжение, пишите в комментариях, часто ли используете подобные методы?
🐳67532🖕1



tgoop.com/zasql_python/301
Create:
Last Update:

Анализ экспериментов с Ratio-метриками

Проводя эксперименты, обычно, мы используем базовые методы: t-test, z-test, bootstrap (если данных не так много). Это для одних метрик, но, предположим, мы работаем с метриками-отношения (представляют из себя деление суммы случайной величины X на сумму случайной величины Y).

В этом случае в группе A и группе B у нас нет дисперсии. В самом деле, рассмотрим средний чек - метрика отношения (сумма GMV / количество заказов), CTR (сумма кликов / количество показов). Получаем некоторую метрику Za и Zb для которой мы знаем значение, но дисперсии метрики не знаем.

Отсюда выход:

а) провести бутстрап, чтобы найти распределение этой метрики и узнать распределение статистики
б) бакетировать (меньше по ресурсам, чем бутстрап).
в) применять другие методы (например, линеаризацию или дельта-метод).
г*) что-то другое...

Бутстрап

Для оценки распределения метрики можем использовать выборочные значения в группе A и группе B и найти разницу, таким образом, мы получим «разницу средних». Из минусов: MDE не рассчитать (при дизайне эксперимента), очень долгий расчет при больших выборках, ресурсов может не хватить.

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


def bootstrap_ratio(data, nominator, denominator, group_column, group_value, n_iter=10000):

group_data = data[data[group_column] == group_value]

boot_ratios = []
for _ in range(n_iter):
sample = group_data.sample(len(group_data), replace=True)
ratio = sample[nominator].sum() / sample[denominator].sum()
boot_ratios.append(ratio)

return np.array(boot_ratios)


Бакетизация

Делим также пользователей по бакетам (с их GMV и количеством заказов), распределение метрики будет нормальным, главное, чтобы в бакетах было достаточное количество наблюдений. Мы делаем n-подвыборок (где n - это количество бакетов). Из минусов: сложность работать с маленькими выборками, зависимость от количества бакетов (тонкая настройка).


def bucketize(data, nominator, denominator, n_buckets=50, random_state=42):

data = data.sample(frac=1, random_state=random_state).reset_index(drop=True)
buckets = np.array_split(data, n_buckets)
bucket_ratios = [bucket[nominator].sum() / bucket[denominator].sum() for bucket in buckets]

return bucket_ratios



Пару слов про дельта-метод и линеаризацию.

В общем-то это об одном и том же. Мы хотим найти дисперсию метрики для того, чтобы применить классические методы (например, t-test). В дельта-методе мы корректируем дисперсию на корреляцию двух случайных величин (числителя и знаменателя). Только есть разница: дельта-метод вычисляет дисперсию на уровне выборки сразу, а линеаризация позволяет Ratio-метрику превратить в поюзерную. Результаты сонаправлены.

Дельта-метод


def calculate_ratio_variance(values_numerator, values_denominator):

mean_num = np.mean(values_numerator)
mean_denom = np.mean(values_denominator)
variance_num = np.var(values_numerator, ddof=1)
variance_denom = np.var(values_denominator, ddof=1)

covariance_num_denom = np.cov(values_numerator, values_denominator)[0, 1]

ratio_variance = (
(variance_num / mean_denom ** 2)
- (2 * (mean_num / mean_denom ** 3) * covariance_num_denom)
+ ((mean_num ** 2 / mean_denom ** 4) * variance_denom)
)

return ratio_variance


Линеаризация


# ratio_control - ratio-метрика в контрольной группе (для теста также рассчитывается)

def calculate_ratio_control(numerator_control, denominator_control):
return sum(numerator_control) / sum(denominator_control)

ratio_control = calculate_ratio_control(numerator_control, denominator_control)

def linearization(numerator, denominator, ratio_control):
return numerator - ratio_control * denominator


Дополнительные материалы для ознакомления: первый, второй, третий, четвертый, пятый

Понравился пост? Давайте наберем 150 🐳🐳🐳, если хотите продолжение, пишите в комментариях, часто ли используете подобные методы?

BY Заскуль питона (Data Science)


Share with your friend now:
tgoop.com/zasql_python/301

View MORE
Open in Telegram


Telegram News

Date: |

5Telegram Channel avatar size/dimensions As the broader market downturn continues, yelling online has become the crypto trader’s latest coping mechanism after the rise of Goblintown Ethereum NFTs at the end of May and beginning of June, where holders made incoherent groaning sounds and role-played as urine-loving goblin creatures in late-night Twitter Spaces. A vandalised bank during the 2019 protest. File photo: May James/HKFP. How to create a business channel on Telegram? (Tutorial) Commenting about the court's concerns about the spread of false information related to the elections, Minister Fachin noted Brazil is "facing circumstances that could put Brazil's democracy at risk." During the meeting, the information technology secretary at the TSE, Julio Valente, put forward a list of requests the court believes will disinformation.
from us


Telegram Заскуль питона (Data Science)
FROM American