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 марта.
Разберем, какие типовые задачи решает продуктовая аналитика, познакомимся с инструментами аналитика. Записаться
