Ответ
Да, проводил A/B тестирование для оценки эффективности изменений в продукте. Вот мой практический опыт:
1. Проект: Оптимизация конверсии на лендинге
Задача: Сравнить две версии кнопки CTA (Call-to-Action)
- Контрольная группа (A): Зеленая кнопка "Купить сейчас"
- Тестовая группа (B): Оранжевая кнопка "Получить скидку"
Метрики:
- Основная: Конверсия (клики/показы)
- Вторичные: Время на странице, bounce rate
2. Статистический анализ в Python
import numpy as np
import pandas as pd
from scipy import stats
import statsmodels.stats.api as sms
import matplotlib.pyplot as plt
# Генерация данных (пример)
np.random.seed(42)
control_size = 5000
treatment_size = 5000
# Контрольная группа (базовая конверсия 10%)
control_conversions = np.random.binomial(1, 0.10, control_size)
# Тестовая группа (улучшенная конверсия 12%)
treatment_conversions = np.random.binomial(1, 0.12, treatment_size)
# Базовые статистики
control_rate = control_conversions.mean()
treatment_rate = treatment_conversions.mean()
relative_improvement = (treatment_rate - control_rate) / control_rate
print(f"Control conversion rate: {control_rate:.3%}")
print(f"Treatment conversion rate: {treatment_rate:.3%}")
print(f"Relative improvement: {relative_improvement:.2%}")
3. Проверка статистической значимости
# Z-test для пропорций
from statsmodels.stats.proportion import proportions_ztest
count = np.array([control_conversions.sum(), treatment_conversions.sum()])
nobs = np.array([control_size, treatment_size])
z_stat, p_value = proportions_ztest(count, nobs, alternative='smaller')
print(f"Z-statistic: {z_stat:.3f}")
print(f"P-value: {p_value:.5f}")
# Доверительный интервал разницы
from statsmodels.stats.proportion import confint_proportions_2indep
ci_low, ci_high = confint_proportions_2indep(
count1=treatment_conversions.sum(), nobs1=treatment_size,
count2=control_conversions.sum(), nobs2=control_size,
method='wald',
compare='diff',
alpha=0.05
)
print(f"95% CI for difference: [{ci_low:.4f}, {ci_high:.4f}]")
4. Расчет мощности теста и размера выборки
# Расчет необходимого размера выборки до запуска теста
effect_size = sms.proportion_effectsize(0.10, 0.12) # Минимальный детектируемый эффект
power_analysis = sms.NormalIndPower()
required_n = power_analysis.solve_power(
effect_size=effect_size,
power=0.8, # 80% вероятность обнаружить эффект
alpha=0.05, # Уровень значимости 5%
ratio=1.0 # Равные группы
)
print(f"Required sample size per group: {int(required_n)}")
5. Анализ воронки и сегментация
# Анализ по сегментам пользователей
data = pd.DataFrame({
'group': ['control'] * control_size + ['treatment'] * treatment_size,
'converted': np.concatenate([control_conversions, treatment_conversions]),
'segment': np.random.choice(['new', 'returning'],
control_size + treatment_size,
p=[0.6, 0.4])
})
# Конверсия по сегментам
segment_analysis = data.groupby(['group', 'segment'])['converted']
.agg(['mean', 'count', 'sum'])
print(segment_analysis)
# Статистическая значимость по сегментам
for segment in ['new', 'returning']:
segment_data = data[data['segment'] == segment]
count = segment_data.groupby('group')['converted'].sum().values
nobs = segment_data.groupby('group').size().values
z_stat, p_value = proportions_ztest(count, nobs)
print(f"Segment {segment}: p-value = {p_value:.4f}")
6. Визуализация результатов
import seaborn as sns
# Распределение конверсий по дням (для проверки временных эффектов)
daily_data = pd.DataFrame({
'day': np.tile(range(14), control_size // 14 + treatment_size // 14)[:control_size + treatment_size],
'group': data['group'],
'converted': data['converted']
})
daily_conversion = daily_data.groupby(['day', 'group'])['converted'].mean().reset_index()
plt.figure(figsize=(12, 6))
sns.lineplot(data=daily_conversion, x='day', y='converted', hue='group')
plt.title('Daily Conversion Rates')
plt.xlabel('Day')
plt.ylabel('Conversion Rate')
plt.axhline(y=control_rate, color='blue', linestyle='--', alpha=0.5)
plt.axhline(y=treatment_rate, color='orange', linestyle='--', alpha=0.5)
plt.show()
7. Практические рекомендации из опыта:
-
Перед запуском:
- Рассчитываю минимальный детектируемый эффект (MDE)
- Определяю длительность теста с учетом сезонности
- Настраиваю систему сбора данных и event tracking
-
Во время теста:
- Мониторю равномерность распределения трафика
- Проверяю отсутствие технических проблем
- Отслеживаю вторичные метрики на предмет негативных эффектов
-
После теста:
- Анализирую результаты по сегментам
- Проверяю устойчивость результатов во времени
- Документирую выводы и рекомендации для product-менеджеров
Пример вывода из реального проекта: "Тест показал статистически значимое увеличение конверсии на 18% (p-value = 0.012). Эффект особенно выражен среди новых пользователей (+25%). Рекомендую внедрить изменение и мониторить долгосрочные метрики удержания."