Собесов

Лига Ставок — стали ли пользователи делать больше ставок после обновления

Кейсы и метрикиQuasi-experiment / pre-postСредняяMiddle

Условие

Лига Ставок выпустила новую версию приложения, в которой исправили проблему с заключением пари (раньше было много ошибок). Обновление не A/B: его постепенно раскатывают всем. Не выложили в сторы.

Менеджер просит проанализировать, стали ли пользователи делать больше ставок после обновления.

Дано: user_id, platform, install_date (дата установки обновления), bets_date, bets (дата и кол-во ставок).

Решение

Каркас: квази-эксперимент pre-post

A/B нет, контроль явный отсутствует. Доступные дизайны:

  1. Pre-post within user: для каждого пользователя сравнить bets/day за N дней до install_date и N дней после.
  2. DiD-аналог: пользователи, обновившиеся раньше, vs обновившиеся позже (на одной и той же календарной дате).
  3. Interrupted Time Series: на агрегатном уровне (DAU bets) — сменилось ли trend после релиза.

Реализация (1 — Pre-post)

import pandas as pd
import numpy as np
 
df = pd.read_csv('liga_stavok.csv')
df['install_date'] = pd.to_datetime(df['install_date'])
df['bets_date']    = pd.to_datetime(df['bets_date'])
df['lt_day']       = (df['bets_date'] - df['install_date']).dt.days
 
# pre vs post 14 days
pre  = df[(df['lt_day'] >= -14) & (df['lt_day'] < 0)].groupby('user_id')['bets'].mean()
post = df[(df['lt_day'] >=   0) & (df['lt_day'] < 14)].groupby('user_id')['bets'].mean()
 
paired = pd.merge(pre.rename('pre'), post.rename('post'), left_index=True, right_index=True)
paired['delta'] = paired['post'] - paired['pre']
 
print(paired['delta'].describe())
# paired t-test
from scipy import stats
t, p = stats.ttest_rel(paired['post'], paired['pre'])

Реализация (2 — DiD-like)

Сравниваем «early adopters» (обновились в первые 7 дней раскатки) и «late adopters» (через 30+ дней). Для каждой когорты — pre-period (до релиза) и post-period (после релиза). Возможно поймать «выживший выборка» эффект, но при правильной идентификации — DiD-оценка.

Реализация (3 — ITS)

daily = df.groupby('bets_date')['bets'].sum().reset_index()
# импульсивный тест: change point detection
from ruptures import Pelt
algo = Pelt(model="rbf").fit(daily['bets'].values)
points = algo.predict(pen=10)

Или линейная регрессия с break-point на release date:

bets_t = β0 + β1 * t + β2 * post + β3 * t * post + ε

β2 — сдвиг уровня в момент релиза.

Проверка / интерпретация

  • Sanity: количество user-pairs > 1000 для значимости.
  • Бустраппинг — устойчивее t-test (распределение ставок имеет heavy-tail).
  • Сегментация: по platform (iOS/Android), новые/возвращающиеся.

Подводные камни

  1. Selection bias в pre-post: пользователь, который активно ставил pre, мог обновиться. Сравнение «до vs после» среди обновлённых — не каузальный эффект.
  2. Survivor bias: те, кто перестал ставить после установки, могут быть unobservable; те, кто продолжил — overrepresented.
  3. Сезонность: спортивные события (Лига Чемпионов, ЧМ) — резкий рост ставок без всякого релиза. Используйте YoY или контрольную группу.
  4. Привычка пользователей: пользователи 14 дней до релиза могли быть активны редко; после релиза — выросли «по совпадению» (новый сезон).
  5. «Постепенно отправляем»: пользователи получают update в разное время. Лучше работать с relative time lt_day, не absolute.
  6. Гипотеза «больше ставок»: но возможно средний размер ставки или success rate — что важнее. Уточните, что именно метрика успеха.

Что лучше всего ответить менеджеру

«Да, стало больше ставок: medio per user/day +X.XX (CI [a, b]), p < 0.05 на paired t-test. Но это не A/B, а pre-post — есть confounders (сезонность, выжившая аудитория). Чтобы убедиться, что эффект именно от bug-fix, нужно: (a) контрольная группа на сегменте, который ещё не обновился; (b) контроль на сезонности (YoY same-period); (c) расследование bug-rate в логах — упал ли в пост-периоде.»

Эталонный ответ

Pre-post within user — paired t-test или Wilcoxon на mean bets/day. Дополнительно DiD «early vs late adopters» и ITS на DAU. Главное — указать, что без A/B каузально оценить нельзя; идентифицируйте confounders (сезонность, survivor bias, постепенная раскатка).

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти