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: |

Members can post their voice notes of themselves screaming. Interestingly, the group doesn’t allow to post anything else which might lead to an instant ban. As of now, there are more than 330 members in the group. Clear The court said the defendant had also incited people to commit public nuisance, with messages calling on them to take part in rallies and demonstrations including at Hong Kong International Airport, to block roads and to paralyse the public transportation system. Various forms of protest promoted on the messaging platform included general strikes, lunchtime protests and silent sit-ins. Among the requests, the Brazilian electoral Court wanted to know if they could obtain data on the origins of malicious content posted on the platform. According to the TSE, this would enable the authorities to track false content and identify the user responsible for publishing it in the first place. Deputy District Judge Peter Hui sentenced computer technician Ng Man-ho on Thursday, a month after the 27-year-old, who ran a Telegram group called SUCK Channel, was found guilty of seven charges of conspiring to incite others to commit illegal acts during the 2019 extradition bill protests and subsequent months.
from us


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