**Контекст:** Мобильная игра запускает сезонное событие с 4 вариантами награды за daily login. Нужно выбрать лучший вариант за 14 дней. Классический A/B-тест покажет результат только в конце, а bandit позволит адаптировать трафик к лучшему варианту в процессе.
**Данные:** предварительные оценки (из фокус-группы):
| Вариант | Описание | Ожидаемый Retention D7 | Неопределённость |
|---------|----------|----------------------|-----------------|
| A (контроль) | 100 монет | 32% | Базовый |
| B | 50 монет + скин | 34% | Высокая |
| C | 1 бесплатный spin | 36% | Очень высокая |
| D | VIP-доступ 24ч | 33% | Средняя |
Параметры:
- DAU: 200 000
- Длительность: 14 дней
- Бизнес-цена ошибки: каждый 1 п.п. retention D7 ≈ +$50 000 LTV за сезон
Результаты после 14 дней (обе стратегии):
Классический A/B (равномерный сплит 25/25/25/25):
| Вариант | n | Retention D7 | 95% CI |
|---------|------|-------------|--------|
| A | 700 000 | 32.1% | [31.7%, 32.5%] |
| B | 700 000 | 35.2% | [34.8%, 35.6%] |
| C | 700 000 | 33.8% | [33.4%, 34.2%] |
| D | 700 000 | 32.8% | [32.4%, 33.2%] |
Thompson Sampling bandit (адаптивный сплит):
| Вариант | n (final) | % трафика к дню 14 | Retention D7 |
|---------|-----------|-------------------|-------------|
| A | 280 000 | 5% | 32.0% |
| B | 1 420 000 | 62% | 35.1% |
| C | 680 000 | 25% | 33.9% |
| D | 420 000 | 8% | 32.7% |
**Задание:**
1. Рассчитайте cumulative regret для обоих подходов.
2. Когда лучше A/B, а когда bandit? Постройте decision framework.
3. Какие статистические проблемы возникают при bandit-подходе?
4. Предложите гибридный подход для данного кейса.
Структура для ориентира — реальные значения из эталонного решения.
import numpy as np
# Thompson Sampling симуляция
np.random.seed(42)
true_rates = {'A': 0.321, 'B': 0.352, 'C': 0.338, 'D': 0.328}
arms = list(true_rates.keys())
# Beta priors
alpha_prior = {a: 1 for a in arms}
beta_prior = {a: 1 for a in arms}
total_users = 200000 * 14 # 2.8M
batch_size = 200000 # daily
days = 14
allocation_history = {a: [] for a in arms}
cumulative_regret = 0
best_rate = max(true_rates.values())
for day in range(days):
# Thompson sample
samples = {a: np.random.beta(alpha_prior[a], beta_prior[a]) for a in arms}
# Allocate proportionally to samples (softmax-like)
total = sum(samples.values())
alloc = {a: int(batch_size * samples[a] / total) for a in arms}
for arm in arms:
n = alloc[arm]
successes = np.random.binomial(n, true_rates[arm])
alpha_prior[arm] += successes
beta_prior[arm] += n - successes
allocation_history[arm].append(n)
cumulative_regret += n * (best_rate - true_rates[arm])
print("Final allocation (%):")
for arm in arms:
total_n = sum(allocation_history[arm])
print(f" {arm}: {total_n:>10,} ({total_n/2800000*100:.1f}%)")
print(f"Cumulative regret: {cumulative_regret:,.0f} retention events")
A/B-тест multi-armed bandit Thompson sampling regret exploration-exploitation
Это задание для уровня Senior. Senior-уровень — глубокое понимание темы, опыт решения нестандартных задач, обсуждение trade-off на собеседовании.
Подобные задания в категории «A/B-тесты» регулярно дают на собеседованиях аналитика данных в Яндекс, Сбер, Ozon, Авито, Тинькофф, Wildberries, T-Bank, X5, ВТБ и других крупных IT-компаниях. Тематика: A/B-тест, multi-armed bandit, Thompson sampling, regret, exploration-exploitation.
На реальном собеседовании на подобную задачу отводится 30-60 минут с обсуждением подходов, оптимизаций и trade-off. Для тренировки рекомендуем сначала решить самостоятельно, потом сверить с эталонным решением и подсказками.
На zasqlpython.ru есть другие задания в категории «A/B-тесты», продуктовые кейсы, справочник метрик, AI мок-собеседование с разбором ваших ответов.
← Все задания