Настройка A/B-тестирования ML-моделей в продакшене
A/B-тестирование ML-моделей — единственный способ достоверно измерить бизнес-эффект новой версии модели. Метрика на тестовом датасете показывает, что модель стала точнее, но не отвечает на вопрос: принесёт ли это больше денег или лучший UX? Правильно настроенный A/B-тест даёт статистически обоснованный ответ.
Отличия ML A/B от классического A/B
В классическом A/B пользователи случайно распределяются между группами один раз. В ML A/B дополнительные сложности:
- Novelty effect: пользователи реагируют на новизну, которая не связана с качеством модели
- Long-term effects: рекомендательные системы влияют на долгосрочное поведение, не видное в краткосрочном тесте
- Carryover effects: эффект от предыдущего предсказания влияет на текущее поведение
- Network effects: в коллаборативных системах поведение одного пользователя влияет на других
Архитектура A/B для ML
Уровни распределения трафика:
-
User-level split — один и тот же пользователь всегда получает одну версию модели. Подходит для персонализации, рекомендаций.
-
Request-level split — каждый запрос случайно направляется в одну из версий. Подходит для stateless сервисов (поиск, ценообразование).
-
Cohort-based split — разбивка по сегментам пользователей. Важно для обеспечения баланса по демографическим характеристикам.
Роутинг трафика:
import hashlib
def get_model_version(user_id: str, experiment_id: str) -> str:
# Детерминированное хэширование для стабильного назначения
hash_key = f"{experiment_id}:{user_id}"
hash_value = int(hashlib.md5(hash_key.encode()).hexdigest(), 16)
bucket = hash_value % 100 # 0-99
if bucket < 50: # 50% трафика
return "model_v2"
else:
return "model_v1_control"
Инструменты
Nginx / Envoy — маршрутизация на уровне инфраструктуры по заголовкам или весам.
Seldon Core / KServe — Kubernetes-native инференс с встроенным A/B:
apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
spec:
predictors:
- name: control
traffic: 70
graph:
name: model-v1
- name: treatment
traffic: 30
graph:
name: model-v2
Feature flags (LaunchDarkly, Unleash) — для гибкого управления экспериментами без деплоя.
Статистическая методология
Метрики для ML A/B:
- Primary metric: бизнес-метрика (конверсия, ARPU, retention)
- Guardrail metrics: latency, error rate — не должны деградировать
- Secondary metrics: proxy-показатели (CTR, engagement)
Размер выборки и мощность теста:
Для обнаружения эффекта размером 2% при baseline конверсии 5%, уровне значимости α=0.05 и мощности 80%, нужно ~15000 пользователей на группу. Используйте калькулятор мощности (scipy.stats.norm или онлайн-инструменты) перед запуском.
Остановка теста:
- Не останавливайте тест раньше запланированного срока из-за ранних результатов (проблема peek)
- Минимальная длительность: 1-2 недели для учёта дневных и недельных паттернов
- Используйте Sequential testing (e-values) если нужно принимать решения раньше
Анализ результатов
from scipy import stats
control_conversions = [0, 1, 0, 1, ...] # 0/1 для каждого пользователя
treatment_conversions = [0, 1, 1, 0, ...]
# t-тест для непрерывных метрик
t_stat, p_value = stats.ttest_ind(control_conversions, treatment_conversions)
# Chi-squared для бинарных метрик
from scipy.stats import chi2_contingency
contingency = [[control_success, control_fail],
[treatment_success, treatment_fail]]
chi2, p_value, dof, expected = chi2_contingency(contingency)
print(f"Relative lift: {(treatment_rate - control_rate) / control_rate:.2%}")
print(f"P-value: {p_value:.4f}")
print(f"Statistically significant: {p_value < 0.05}")
Правильно настроенный A/B-тест позволяет принимать решения о деплое модели не на основе интуиции, а на основе данных с измеримым уровнем уверенности.







