Я твой продукт анализировал – Telegram
Я твой продукт анализировал
1.69K subscribers
103 photos
9 videos
2 files
51 links
Про продуктовую аналитику в IT, мысли, методы анализа и алгоритмы. Всё, что ты хотел знать, но стеснялся спросить.

ЛС тут: @de_kn
Download Telegram
📌 6. T-тест. Выравниваем распределение

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

Чтобы попытаться выровнять распределение, мы можем использовать много методов — от простого логарифмирования и стандартизации, до рангового преобразования и трансформации Йео-Джонсона.


Сразу оговорюсь, что на практике в АБ с выравниванием заморачиваются не часто (можешь щегольнуть скиллом на работе), поэтому я не буду слишком углубляться в описание всех методов, а разберу мой любимый — степенную трансформацию Бокса-Кокса.

☝️ Главный нюанс, который стоит знать про BCT (Box-Cox transformation) — он не работает с отрицательными значениями. В коде последней строкой фикс для таких случаев.

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

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

Вот так это выглядит в R (версия для Python в комменте):

library(MASS)
library(car)

# Вычисляем лучшее значение лямбды
par(mfrow = c(1, 1))
boxcox_result <- boxcox(df$metric ~ 1, lambda = seq(-3,3,0.1))

# Сохраняем его
best_lambda <- boxcox_result$x[which.max(boxcox_result$y)]

# Применяем преобразование
df$metric_transformed <- car::bcPower(df$metric, best_lambda)

# При наличии отрицательных значений, смещаем нашу метрику на минимальную величину +1
df$metric <- df$metric+ abs(min(df$metric)) + 1


📎 У меня на гитхабе есть демка такого преобразования (R).

#ABtest
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥1
Знакомтесь, это Остин и Тимон - мои помощники)

Пятница всё-таки, давайте разбавим ленту своими бандитами ⬇️🙂
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍5
📌 7. T-тест

Вот мы и добрались до самого теста

Он довольно простой. Нулевая гипотеза в обоих вариантах одинаковая: средние значения в двух группах равны. Т.е. нам бы хотелось эту гипотезу отклонить (p-value < 0.05) и показать всем что наш тестовый вариант статистически значимо отличается от контрольного.

# Расчет t-теста Стьюдента
t.test(metric ~ var, data = df, var.equal = T)

# чтобы переключиться на Уэлча, замени в var.equal T на F


from scipy.stats import ttest_ind

# Расчет t-теста Стьюдента
group1 = df[df['var'] == 'A']['metric']
group2 = df[df['var'] == 'B']['metric']

t_stat, p_value = ttest_ind(group1, group2, equal_var = True)

# чтобы переключиться на Уэлча, замени в equal_var True на False


Чтобы сделать твой отчёт более важным и профессиональным, можно добавить визуализации и дельты.

Дельты это разницы метрик по итогам теста. Например ты тестировал вырос ли средний чек. Посчитай его на варианте A и на B, разница тут и будет дельтой. А лучше в проценты переведи, продактам такое нравится 🙂

Главное самому не обмануться — дельты, полученные по итогам теста вообще ничего не прогнозируют. Если ты получаешь стат. значимый рост метрики в +30%, это не значит что раскатив вариант, у вас бизнес вырастет на 30%. Это просто саммари по итогам конкретного теста, в конкретный период, на конкретных юзерах.


А то потом придёт продакт через месяц и будет спрашивать, как так, 30% же было, где они?

Для визуализаций вариантов подходят чарты, которые хорошо показывают разбросы данных, например:

Боксплоты
Диаграмма плотностей
Наложенная гистограмма
График доверительных интервалов

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

#ABtest
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥1
📌 8. T-тест. Интерпретация теста

Вдогонку к предыдущему посту, будет не лишним немного рассказать как интерпретировать T-тест.

Пост для любителей разобраться чуть глубже.

Базово его результат выглядит как-то так:

Two Sample t-test

data: money by var
t = -14.679, df = 998, p-value < 2.2e-16
alternative hypothesis: true difference in means between group A and group B is not equal to 0
95 percent confidence interval:
-10.869281 -8.305884
sample estimates:
mean in group A mean in group B
15.49617 25.08376


🧐 Что тут происходит?

t. Это значение t-критерия, по которому вычисляется p-value. То, что значение отрицательное, означает что среднее группы A меньше среднего B.

df: Степени свободы. Они нужны для расчёта t-критерия.

p-value: Наш ключевой показатель, вероятность получить такую разницу средних, если бы на самом деле различий не было. Или нам можно идти в казино, или выиграла альтернативная гипотеза (средние не равны, варианты различаются).

95% доверительный интервал: Доверительный интервал для различия средних значений находится между -10.8 и -8.3, со знаком минус. Т.е. с 95% уверенностью можно сказать, что среднее значение группы B выше среднего значения группы A на величину от 8.3 до 10.8.

Оценки выборочных средних: Среднее значение для группы A составляет 15, а для группы B - 25. Та самая средняя дельта.

#ABtest
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥3
t_test_sample_data.csv
2 KB
📌 9. T-тест. Задача

T-тест, наверное, один из самых популярных методов расчёта АБ-тестов. Его используют почти все команды, где работа над экспериментами не вынесена в отдельное подразделение.

У этих, конечно, всё серьезнее 🙂

Умение правильно считать T-тест это хороший базовый скилл, которым должны обладать все аналитики, продуктовые в особенности.


Для закрепления и тренировки, вот вам выгрузка данных по тесту с ёлками.

Можете сами посчитать и попробовать сделать свои выводы.

Если будут возникать вопросы, пишите в комменты или напрямую мне, разберёмся 🙂

#ABtest
🔥7👍1
📌 Как запускают тесты

На прошлой неделе было много технической базы, на этой будет поменьше 🙂

А пока прервёмся на что-то попроще. Давай порассуждаем как вообще происходит запуск теста в команде. Рассмотрим пример компании, где тесты плюс-минус поставлены на поток.

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

Чтобы идея превратилась в аналитический артефакт, с которым можно работать, её нужно задокументировать. Так она становится гипотезой. Для ведения документации, я обычно создаю отдельную ветку в confluence (скорее всего у тебя в команде он тоже есть).

Далее, если нужно, ты идёшь к продакту и вы выдаёте задачу дизайнеру на разработку тестового варианта.

Когда у тебя появляются картинки, ты идёшь в свою сплит-систему и создаёшь тест. В любой системе, кастомной или сторонней, обычно нужно завести ID теста/вариантов и описания вариантов.

После этого нужно поставить задачу на разработку. В задаче нужно оставить ID теста и вариантов, продублировать описание вариантов, приложить картинки. Чем более полно ты опишешь задачу, тем больше вероятность получить то что заказывал.

Когда тест запустят на стороне разработки, обязательно сверься с базой и убедись что всё летит как надо (скорее всего у тебя в БД есть таблица типа ab_test, где хранятся данные по юзерам, тестам и вариантам).

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

В общем-то это всё. Это один из самых частых флоу, который я встречал. Но он, естественно, не всегда такой и у тебя будут свои нюансы на каждом шаге. Иногда у твоей сплитовалки нет интерфейса и ты “заводишь” тест напрямую в задаче на разработку, иногда это сторонняя система со своими правилами.


Но т.к. АБ — это твоя территория, тебе и менеджерить весь процесс 🙂
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥1
В Белграде Coca-Cola вчера раздавала новогоднее настроение и бургеры деда Мороза) 🎄
🎉7🔥1
📌 10. Биномиальные тесты и тесты пропорций

Продолжаем обсуждать методы расчёта АБ-тестов, менее популярные, но для общего развития — полезные.

Иногда данные для теста не агрегированы вокруг какого-нибудь периода, а подчиняются биномиальному распределению (сэмпл данных выглядит так: 0, 0, 1, 0, 1, 1 и тд, где 0 - не было события, 1 - было).

Такие данные бывают при расчётах, например, конверсий.

Для расчёта биномиальных тестов используют 2 популярных подхода:

Z-тест. Сравнивает доли успехов в биномиальных данных. На малых выборках критично нормальное распределение.

Критерий Хи-квадрат. На биномиальных данных сравнивает частоты выпадения категорий.

И тот и другой тест, по сути, делают нужную нам проверку, но Z-тест лучше работает на больших выборках.


Оба теста можно считать как напрямую из данных (рассчитав пропорции и стандартные ошибки), так и сгруппировав их в таблицу сопряженности:
# создание таблицы сопряженности
table <- table(df$var, df$metric)

n <- colSums(table) # вычисляем суммы по каждому варианту
x <- table[, 2] # вычисляем количество единиц в каждой группе

# z-тест
prop.test(x, n)

# хи-квадрат
chisq.test(table)


import pandas as pd
from scipy import stats
from statsmodels.stats.proportion import proportions_ztest

# создание таблицы сопряженности
table = pd.crosstab(df['var'], df['metric'])
n = table.sum(axis=1).values # вычисляем суммы по каждому варианту
x = table[1].values # вычисляем количество единиц в каждой группе

# z-тест
z_test = proportions_ztest(x, n)

# хи-квадрат
chi2_test = stats.chi2_contingency(table)


#ABtest
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥2
📌 11. Bootstrap 🔥

Однажды на собесе меня спросили “если бы ты выбирал только один метод расчёта АБ-тестов, что бы это было?” — не сомневаясь ни секунды я ответил — бутстрэп.


По теории некоторых классических расчётов АБ мы пробежали, а теперь посмотрим на короля среди методов рассчётов.

Это не самый популярный метод — и очень зря.

Главный плюс бутстрэпа — отсутствие ограничений. Ему абсолютно всё равно какое там у тебя распределение или дисперсия. Он прекрасно справляется с любой задачей, а его точности позавидуют классические методы.

Единственный минус — он требует просит больших выборок. Оценить твоих 100 человек он, конечно, сможет, но здесь это не лучший подход. Но и не слишком огромных, сэмпл из миллиона строк тут тоже не лучший вариант. Скоро поймёшь почему.

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

Метод основан на идее повторного использования существующих данных для генерации большого числа псевдовыборок:

1️⃣ Из исходной выборки создается большое количество новых выборок заданного размера. Каждая выборка формируется путем случайного извлечения элементов из исходной выборки с возвращением.

2️⃣ Для каждой псевдовыборки вычисляется интересующая статистика (например, среднее значение или дисперсия). Это дает распределение статистик, которую мы уже используем как нам нужно.

Обычно бутстрэп генерит тысячи сэмплов, поэтому очень большой исходный набор может сильно нагрузить мощности твоей Э-ВЭ-ЭМ.

‼️ Я накидал тебе shiny-приложение по бутсрэпированию разницы метрик. Оно генерит сэмплы на варианты и считает разницу средних, и так много раз. А потом вычисляет p-value для проверки стат. значимости. Подойдёт для стандартных АБ.

Эксклюзивно для подписчиков канала 😀

Можешь проверить на задаче по T-тесту (сэмпл данных можно скачать прям в приложении), а потом использовать в работе 😉

#ABtest #инструменты
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2
А хотите разбавим ленту лонгридом как я вкатывался 300 лет тому назад? Покекать с тогдашних реалий, погрустить с реалий нынешних.

Ставь 👍 если да и 😐 если понимаешь, что я всё равно выложу
👍24😐7😁1
📌 Как я "вкатился"

Кулстори как я врывался в этот ваш ИТ.

Присаживайтесь поудобнее, мы тут надолго 😅

Мой карьерный путь начался после ухода со специальности “Электростанции” Энергетического факультета, в качестве электрика в 2010-м. В электрике я задержался недолго, и по какому-то стечению обстоятельств меня занесло в монтаж оптоволокна к одному подрядчику Ростелекома. Там меня определили спайщиком. Работа была интересная, Fujikura в сердечке ❤️

Но как-то, сидя зимой на какой-то крыше и распаивая кросс, за 15к рублей в месяц, я подумал о работе в офисе. А чё, сидишь там, кофе пьёшь в тепле. Кайф. Погуглил что там доступно у нас в городе, и принял решение попробовать этот ваш ИТ. В то время диковинный.

В коммерческую аналитику я пошёл не сразу, до этого начинал с фронт-энда, который в те времена назывался просто вёрсткой. Учился я на это дело по видосам и статьям в интернете, не долго, месяц может. Это вам не современные реактивные фреймворки, тогда самой крутой технологией был jQuery, а для крепкого фуллстека было достаточно знать HTML, CSS, JS и PHP.

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

Как-то я смотрел какой-то видос из блога AIC, это был ролик с Виталиком Черемисиновым. Он там дико грузил терминами и до меня дошло — аналитическое сопровождение вашего сайта! Гениально. Это ж не продукт полноценный, подумал я, че там делов-то, прикрутил метрику, конверсии туда-сюда, изи. И так, в общем-то и было. Клиенты знать не знали про такие чудеса, а когда мы просто прокатывали рандомные АБ-тесты через калькуляторы, да ещё и умудрялись растить там какие-то циферки, они были довольны.

Меня это всё дело увлекло и я решил разобраться предметнее. Нагуглил что вообще надо знать (отдельным квестом было собрать такую инфу, медийных аналитиков было полтора человека, а структурированных статей не было вообще) и начал со статистики. Первым был какой-то учебник по курсу универской статистики, дико душный, но основательный. По метрикам я читал Красинского, и в целом следил за блогом Черемисинова. Кучу всякой ненужной фигни впитывал, очень много уделил времени качественным исследованиям, которые в дальнейшей практике применял всего пару раз 🙂

Когда я понял, что хотел бы заниматься аналитикой официально, погуглил вакансии и нашёл одну продуктовую компанию, которым как раз нужен был аналитик. Написал им большое письмо на почту со своей историей, и они с удовольствием закинули мне тестовое — посмотреть их CJM и порекомендовать доработки (тогда вот такая жесть была, да). Ну а я то чё, я ж в студии чем только не занимался, чё мне ваша CJM. Накидал каких-то мыслей и отправил обратно.

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

На работе никто понятия не имел зачем я нужен. Да и я тоже не особо. Пилил какой-то дашборд в амплитуде, ходил по офису с важным видом, сыпал терминами типа “выборка” и “распределение”, ловил за это восторженные взгляды и учил R по книге великого Хэдли Уикема. За бешенные деньги тогда, 50к рублей.

О питоне в то время и речи не шло, он не был привычным языком аналитиков на Руси. Да, всякие numpy-scipy появились в 2006-2008, но популярными у нас они стали сильно позже. Я так и вообще не слышал о таких, хотя целенаправленно копался в той части интернета.

А потом начали набирать популярность всякие курсы. Мне очень помог в своё время курс скиллбокса “UX-аналитик”, он вышел одним из первых. Вели его нынешние отцы EXPF — Искандер Мирмахмадов и всё тот же Виталик Черемисинов. Не то чтобы курс был крутым и полным, наоборот, одна тема — один видос на 10 минут. Но он задавал вектор. Видишь тему — гуглишь книгу.

Я даже как-то написал письмо в AIC типа вот он я, хочу к вам, но на тех собесе Виталика впечатлить не удалось. Зато мы прекрасно поболтали и он накидал тонну фидбека, с которым я перешёл к дальнейшему развитию более структурно.

#кулстори
🔥23👍41🤔1
This media is not supported in your browser
VIEW IN TELEGRAM
😁13
📌 12. Метод доверительных интервалов

Разберём ещё один метод расчёта АБ и потихоньку будем завершать вводную часть по этой теме.

Классический метод, который на практике я встречал не часто — оценка через доверительные интервалы (CI, confidence intervals). Он простой, хоть и не самый надёжный такой реализации.

Да, технически, интервалы в расчётах АБ заложены везде. Мы же поговорим о классике, когда построение CI это самоцель.

🧐 CI — это диапазон значений, в котором, с определённой вероятностью, находится истинное значение параметра.

Если CI выборок не пересекаются, то это означает стат. значимость в различиях (технически, среднее одной выборки не должно лежать в интервале второй, но на цифрах интервалов мы среднего не видим)

Ограничение: CI предполагают нормальные распределения выборок и теряют в точности на малых выборках.

Пример реализации метода:
# Заводим функцию для расчёта CI
calc_ci <- function(df, cl = 0.95) {
mean_metric <- mean(df$metric) # считаем среднее
std_error <- sd(df$metric) / sqrt(nrow(df)) # считаем стандартную ошибку
error_limit <- qt(cl / 2 + .5, df = nrow(df) - 1) * std_error # считаем предел погрешности
lower <- mean_metric - error_limit # считаем нижнюю границу интервала
upper <- mean_metric + error_limit # считаем верхнюю границу интервала
return(c(lower, upper))
}

# Считаем CI для групп
ci_A <- calc_ci(df %>% filter(var == "A"))
ci_B <- calc_ci(df %>% filter(var == "B"))


# Заводим функцию для расчёта CI
def calc_ci(df, cl = 0.95):
mean_metric = np.mean(df['metric']) # считаем среднее
std_error = np.std(df['metric']) / np.sqrt(len(df)) # считаем стандартную ошибку
error_limit = stats.t.ppf(cl / 2 + 0.5, df = len(df) - 1) * std_error # считаем предел погрешности
lower = mean_metric - error_limit # считаем нижнюю границу интервала
upper = mean_metric + error_limit # считаем верхнюю границу интервала
return lower, upper

# Считаем CI для групп
ci_A = calc_ci(df[df['var'] == 'A'])
ci_B = calc_ci(df[df['var'] == 'B'])


#ABtest
👍4
📌 13. Парадокс Симпсона

Как-то я проходил собес и мне задали вопрос:

- Доводилось ли тебе иметь дело с парадоксом Симпсона?


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

О чём там был тест уже не вспомню, но это и не так важно. В этом тесте мы получили хорошие результаты и тестовый вариант выиграл по ключевой метрике.

Всё бы хорошо, но заказчик решил посмотреть его в разрезе платформ. Проблема была в том, что аудитории платформ (iOS vs Android) у нас были неравномерные, одной группы было сильно меньше.

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

Этот явление и есть парадокс Симпсона.

По смыслу он немного похож на "Эффект чирлидерш" от Барни Стинсона из HIMYM (if you know — you know).

Я не очень часто с ним сталкивался, во многом потому что сегментация по итогам теста не самое популярное развлечение.

Как его обойти?

🧐 Есть такая штука теорема “Принципа уверенности”, которая утверждает, что, если действие увеличивает вероятность события в каждой группе в отдельности, оно также увеличивает вероятность события во всей популяции.

В соответствии с этой теоремой, я вывел для себя два правила, которых стараюсь придерживаться:

Не сегментировать результаты теста. Этот вариант подходит чаще всего, когда сегментация не несет существенного значения для анализа.

Сегментировать заранее. Если всё же сегментация нужна, то стоит убедиться что группы будут сбалансированы. В идеале равные размеры выборок, но это скорее пожелание, чем правило. Другое дело — размеры выборок минимального сегмента. Если они слишком малы (например, у нас почти нет Android-юзеров), мы можем потерять в стат. мощности.

В таких ситуациях лучше лишний раз подумать над использованием первого правила и не сегментировать вообще.

#ABtest #собесы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥1
📌 14. Нестандартные тесты

В завершении цикла про АБ, будет полезным рассказать про некоторые их нестандартные вариации. Или другие типы тестов. Кому как нравится, я их условно разделил.

К первой вариации я бы причислил AB/n-тесты. Это расширенная версия АБ, когда в сравнении участвуют 3 и более вариантов. Самый частый метод расчёта таких тестов — дисперсионный анализ (ANOVA).

Ещё отдельно я бы вынес непараметрические тесты. Технически, это те же самые АБ (AБ/н), но методы их расчёта не делают предположений о распределении, как это делают параметрические тесты. К таким методам можно отнести критерии Манна-Уитни или Краскела-Уоллиса (такой непараметрический аналог ANOVA, когда вариантов 3 и более).

И нельзя не упомянуть Байесовских бандитов. В этих тестах алгоритм динамически “приспосабливается” для определения эффективного варианта, при постоянном обновлении данных. В отличии от АБ, где оба варианта наполняются на протяжении всего теста, бандиты постоянно обновляют вероятность выбора каждого варианта. За счёт этого они более гибкие в быстро меняющихся условиях.
Я довольно часто встречал их у ребят из маркетинга, на тестировании креативов, или в CPA на каналах. А вот в классической продуктовой аналитике почти не видел.

Можно ли успешно работать продуктовым аналитиком без этих тестов? Да легко. Но попробовать, хотя бы в образовательных целях, никогда не лишнее 🙂

#ABtest
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8