← Назад к вопросам

Какие должны быть пользователи в экспериментах?

2.0 Middle🔥 161 комментариев
#A/B тестирование#Процессы и планирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Какие должны быть пользователи в экспериментах

Введение в разделение на когорты

Выбор правильных пользователей для экспериментов — критический фактор успеха A/B тестирования. Неправильная когорта может привести к ложным выводам, потерь времени и неправильным решениям. Я расскажу о типах пользователей и критериях их выбора.

1. Целевая аудитория (Target Audience)

Определение: Пользователи, на которых направлена новая фича.

Примеры:

  • Для фичи "Голосовые сообщения" → Пользователи, которые активно используют текстовый чат
  • Для фичи "Premium" → Пользователи с DAU ≥1 месяц
  • Для фичи "Gruppenkzur" → Пользователи, которые находятся в 2+ группах

Как выбрать:

SELECT user_id, country, dau, group_count, last_active
FROM users
WHERE dau >= 1 MONTH  -- Активные пользователи
  AND created_at >= '2023-01-01'  -- Не древние
  AND country IN ('US', 'GB', 'CA', 'DE', 'FR')  -- Англоязычные
  AND device_type = 'mobile'  -- Если фича для мобилки
LIMIT 50000;

Важно: Целевая аудитория должна иметь потребность в фиче, иначе результаты будут шумные.

2. Активные пользователи (Active Users)

Определение: Пользователи, которые регулярно используют приложение.

Почему важны: Неактивные пользователи создают шум, потому что их поведение непредсказуемо.

Критерии активности:

DAU (Daily Active Users): Последний день использования < 7 дней назад
MAU (Monthly Active Users): Последний день использования < 30 дней назад
WAU (Weekly Active Users): Последний день использования < 7 дней назад

Правило: Для экспериментов используй DAU, не MAU. DAU → чистая когорта, MAU → шум.

Как проверить:

активные = df[df['last_active'] <= pd.Timestamp.now() - pd.Timedelta(days=1)]
процент = len(активные) / len(df) * 100
print(f"Активных пользователей: {процент}%")

3. Пользователи без экспериментов (Experiment-Naive Users)

Определение: Пользователи, которые не участвовали в других экспериментах за последние N дней.

Почему важно: Если пользователь участвует в 3 экспериментах одновременно, результаты будут заведены взаимным влиянием.

Правило:

Минимальный интервал между экспериментами для одного пользователя: 7-14 дней
(Washout period = время отмывки)

Как проверить:

SELECT user_id, COUNT(experiment_id) as active_experiments
FROM user_experiments
WHERE end_date IS NULL OR end_date >= NOW() - INTERVAL '14 days'
GROUP BY user_id
HAVING COUNT(experiment_id) <= 1;  -- Только в одном эксперименте

Мой пример: Один пользователь участвовал в эксперименте "новый UI" и "новый алгоритм ранжирования" одновременно. Мы не знали, что улучшило вовлечение. Результат: потеря 2 недель времени.

4. Представители разных регионов (Geo-Diverse)

Определение: Пользователи из разных стран/регионов.

Почему важно: Поведение сильно различается:

  • В США пользователи быстрее принимают новые фичи
  • В Европе люди заботятся о приватности
  • В Азии высокая цена интернета → оптимизация трафика важна

Правило: Минимум 5-10 стран в когорте, с представлением каждой страны ≥5% пользователей.

Как разбить:

SELECT country, COUNT(*) as user_count, COUNT(*) * 100.0 / SUM(COUNT(*)) OVER () as percentage
FROM users_in_experiment
WHERE country IS NOT NULL
GROUP BY country
ORDER BY user_count DESC;

-- Результат:
US          15000   30%  ✓
DE          10000   20%  ✓
FR          8000    16%  ✓
GB          7000    14%  ✓
JP          5000    10%  ✓
RU          5000    10%

5. Пользователи по платформе (Platform Diversity)

Определение: Пользователи на разных устройствах и ОС.

Почему важно: Фича может работать хорошо на iOS, но плохо на Android, или наоборот.

Критерии:

iOS vs. Android: 50/50 или по реальной доле
Мобиль vs. Web vs. Desktop: По стратегии
Версия OS: iOS 14+, Android 11+

Правило: Минимум 30% на меньшей платформе.

6. Новые пользователи (New Users) vs. Опытные (Power Users)

Определение: Когда используется какая когорта.

Новые пользователи (0-7 дней)

Когда тестировать:

  • Фичи для onboarding
  • Первая страница приложения
  • Начальная настройка

Преимущества:

  • Нет привычек (bias меньше)
  • Быстрее видны результаты

Недостатки:

  • Могут уйти из приложения
  • Не все фичи им доступны

Размер когорты: ≥1000 новых пользователей для статистической значимости.

Опытные пользователи (30+ дней)

Когда тестировать:

  • Основной функционал
  • Монетизация
  • Долгосрочные метрики

Преимущества:

  • Стабильное поведение
  • Высокая DAU
  • Меньше чёрного шума

Недостатки:

  • Могут быть консервативны к изменениям
  • Нужно дольше ждать результатов

Размер когорты: ≥500-1000 пользователей.

Power Users (вершина пирамиды)

Определение: Пользователи с активностью в топ-10%.

Метрики:

  • DAU ≥1 месяц
  • Количество отправленных сообщений > среднего в 3 раза
  • Количество групп > среднего

Когда тестировать:

  • Премиум-фичи
  • Функции для power users
  • Интеграции

Преимущества:

  • Дадут ценный фидбек
  • Быстро примут хорошую фичу

Недостатки:

  • Результаты не генерализируются на обычных пользователей
  • Требуют особого внимания

7. Контрольная группа (Control Group)

Определение: Пользователи, которые НЕ получают новую фичу.

Размер: Зависит от ожидаемого эффекта:

Если ожидаю 2% улучшение → 50/50 (control vs. test)
Если ожидаю 10% улучшение → 30/70 (control vs. test)
Если ожидаю 20% улучшение → 20/80 (control vs. test)

Правило: Контрольная группа всегда должна быть ≥10% от когорты.

Статистический расчёт:

N = (Z_α/2 + Z_β)^2 * (σ₁² + σ₂²) / (μ₁ - μ₂)²

Где:
Z_α/2 = 1.96 (95% confidence)
Z_β = 0.84 (80% power)
σ = стандартное отклонение метрики
μ = средняя метрика

Пример: Для метрики с σ=10, ожидаемый эффект 2%, нужно 5000 пользователей в каждой группе.

8. Изоляция и блокировка (Quarantine)

Определение: Пользователи, которых нельзя включать в эксперименты.

Кто блокируется:

  • QA и тестеры компании
  • Пользователи, которые используют VPN (нестабильная геолокация)
  • Пользователи с множественными аккаунтами (fraud)
  • Пользователи из стран, на которые наложены санкции

Как блокировать:

WHERE user_id NOT IN (
  SELECT user_id FROM user_blocks WHERE reason = 'QA_TESTER'
)
AND fraud_score < 0.3
AND country NOT IN ('RU', 'IR', 'KP')
AND vpn_detected = FALSE;

9. Рандомизация и баланс (Randomization)

Определение: Как разделить пользователей на контрольную и тестовую группы.

Методы:

Случайная рандомизация (Random Assignment)

import random
random.seed(user_id)  # Фиксированный seed
if random.random() < 0.5:
    variant = 'control'
else:
    variant = 'test'

Deterministic hash (стабильный)

import hashlib
hash_value = int(hashlib.md5(str(user_id).encode()).hexdigest(), 16)
if hash_value % 2 == 0:
    variant = 'control'
else:
    variant = 'test'

Почему детерминистичный hash лучше:

  • Пользователь всегда в одной группе
  • Если перезагрузим эксперимент, результаты совпадут
  • Нет необходимости хранить назначения в БД

Проверка баланса:

SELECT variant, COUNT(*) as user_count, COUNT(*) * 100.0 / SUM(COUNT(*)) OVER () as percentage
FROM experiment_users
GROUP BY variant;

-- Должно быть примерно:
control  25000   50%  ✓
test     25000   50%

Практический пример: Дизайн когорты для эксперимента

Задача: Протестировать новую фичу "Emoji reactions" в мессенджере.

Критерии когорты:

# 1. Базовая фильтрация
users = df[
    (df['last_active'] <= NOW - 1 day) &  # DAU
    (df['created_at'] >= '2023-01-01') &  # Не древние
    (df['country'].isin(['US', 'DE', 'FR', 'GB', 'JP', 'BR'])) &  # 6 стран
    (df['device_type'].isin(['ios', 'android'])) &  # Мобиль
    (df['fraud_score'] < 0.3)  # Не мошенники
]

# 2. Исключить из других экспериментов
users = users[
    ~users['user_id'].isin(active_experiments['user_id'])
]

# 3. Выбрать 50k пользователей
users_sample = users.sample(n=50000, random_state=42)

# 4. Разделить 50/50
control = users_sample[hash(user_id) % 2 == 0]  # 25k
test = users_sample[hash(user_id) % 2 == 1]  # 25k

# 5. Проверить баланс
print(f"Control: {len(control)} ({len(control)/len(users_sample)*100:.1f}%)")
print(f"Test: {len(test)} ({len(test)/len(users_sample)*100:.1f}%)")

# 6. Проверить распределение по странам
for country in ['US', 'DE', 'FR', 'GB', 'JP', 'BR']:
    control_pct = (control['country'] == country).sum() / len(control) * 100
    test_pct = (test['country'] == country).sum() / len(test) * 100
    print(f"{country}: control={control_pct:.1f}%, test={test_pct:.1f}%")

Итоговый чеклист для выбора пользователей

  • Целевая аудитория — фича релевантна выбранным пользователям
  • Активные пользователи — только DAU, не MAU
  • Experiment-naive — не в других экспериментах за 14 дней
  • Geo-diverse — минимум 5-10 стран
  • Platform-diverse — iOS и Android равномерно
  • Контрольная группа — минимум 10% когорты
  • Статистическая мощность — расчитано необходимое N
  • Рандомизация — используется детерминистичный hash
  • Баланс — control и test группы равномерно распределены
  • Проверка блокировок — QA и fraud исключены
  • Размер когорты — ≥5000 для новичков, ≥1000 для опытных

Главное правило: Чем лучше твоя когорта спроектирована, тем чище результаты и надёжнее выводы.