A/B‑тестирование — золотой стандарт проверки гипотез, но что, если сам эксперимент изначально кривой?
A/A‑тест — это контрольная проверка, где две группы пользователей получают абсолютно одинаковый опыт. Если при этом обнаруживаются статистически значимые различия, значит, где‑то косяк: либо в рандомизации, либо в сборе данных.
Типичные проблемы, которые A/A‑тест помогает выявить:
Ошибка в распределении трафика (неравномерное распределение пользователей по группам).
Баги в логике измерения (ошибки в коде сбора метрик, дублирование событий, потери данных).
Случайные выбросы (например, если сегментация пользователей утекла в один регион или на одно устройство).
Если A/A‑тест проваливается, доверять A/B‑тесту бессмысленно.
Как реализуется A/A-тест?
Общая схема:
Генерируем случайные группы (A и B).
Собираем метрики (конверсии, время на сайте, глубину просмотров и т. д.).
Сравниваем их статистически — не должно быть значимых различий.
Разберем реализацию в коде.
Базовый A/A-тест с t-тестом
import numpy as np
import pandas as pd
from scipy import stats
np.random.seed(42)
n_users = 10000
conversion_rate = 0.1
data = pd.DataFrame({
'user_id': np.arange(n_users),
'conversion': np.random.binomial(1, conversion_rate, n_users),
'group': np.random.choice(['A', 'B'], size=n_users, p=[0.5, 0.5])
})
# Проверка среднего значения конверсии в группах
group_stats = data.groupby('group')['conversion'].mean()
print(group_stats)
# Статистический тест
stat, p_value = stats.ttest_ind(
data[data['group'] == 'A']['conversion'],
data[data['group'] == 'B']['conversion']
)
print(f"p-value: {p_value:.5f}")
print("ОК" if p_value >= 0.05 else "Ошибка: группы различаются!")
Если p‑value < 0.05, тест провален, и нужно разбираться, почему так произошло.
A/A-тест с бутстрепом
Когда данных мало, лучше использовать бутстреп вместо t‑теста:
def bootstrap(data_A, data_B, n_iterations=10000):
boot_means_A = [np.mean(np.random.choice(data_A, size=len(data_A), replace=True)) for _ in range(n_iterations)]
boot_means_B = [np.mean(np.random.choice(data_B, size=len(data_B), replace=True)) for _ in range(n_iterations)]
ci_A = np.percentile(boot_means_A, [2.5, 97.5])
ci_B = np.percentile(boot_means_B, [2.5, 97.5])
return ci_A, ci_B
ci_A, ci_B = bootstrap(
data[data['group'] == 'A']['conversion'].values,
data[data['group'] == 'B']['conversion'].values
)
print(f"95% доверительный интервал для группы A: {ci_A}")
print(f"95% доверительный интервал для группы B: {ci_B}")
percentile([2.5, 97.5])
даёт 95% доверительный интервал. Если доверительные интервалы пересекаются — различий нет. Если не пересекаются, значит, есть проблема.
Кейс: A/A-тест
Предположим, есть данные по трафику с веб‑сайта, и нужно проверить, не сломан ли процесс сегментации пользователей.
# Загрузка реальных данных (пример: лог конверсий сайта)
df = pd.read_csv('website_data.csv')
# Проверяем, что распределение по группам равномерное
print(df['group'].value_counts())
# Проверяем конверсии в группах
group_conversion = df.groupby('group')['conversion'].mean()
print("Средние конверсии:")
print(group_conversion)
# Проверяем статистическую значимость различий
stat, p_value = stats.ttest_ind(
df[df['group'] == 'A']['conversion'],
df[df['group'] == 'B']['conversion']
)
print(f"p-value: {p_value:.5f}")
if p_value < 0.05:
print("Ошибка: группы различаются! Нужно проверить логику сегментации.")
else:
print("Группы распределены корректно, можно запускать A/B-тест.")
Этот код загружает данные, проверяет равномерность распределения пользователей и конверсий, а затем запускает t‑тест для проверки статистических различий. p‑value в A/A‑тестах не всегда = 1, и незначительные отклонения (например, p = 0.08) допустимы.
Итог: когда A/A-тест обязателен?
Запускаем A/A‑тест всегда, если:
Вы тестируете новую систему экспериментов — без него просто нет уверенности, что она работает правильно.
Вы работаете с малым трафиком — случайные флуктуации сильнее на малых объемах.
Вы не уверены в рандомизации — если метод распределения пользователей в тесте новый или нестандартный.
Игнорировать A/A‑тест = рисковать результатами всего A/B‑теста. Проверяйте себя перед A/B‑тестами и сэкономите кучу времени и денег на исправление ошибок.
Кто такой аналитик и кто такой продуктовый аналитик? Обсудим эти роли на открытом уроке 20 марта.
Разберем, какие типовые задачи решает продуктовая аналитика, познакомимся с инструментами аналитика. Записаться