Как посчитать sequential testing в SQL
Содержание:
Зачем sequential testing
Классический A/B: заранее посчитал sample size, ждёшь до конца, смотришь p-value. На практике PM подсматривает каждый день. Если останавливаться на первой «значимости», ложно-позитивных в 3–10 раз больше, чем кажется. Sequential testing — методы, которые позволяют смотреть в любой момент, не теряя гарантий по alpha.
Peeking-bias и его цена
WITH simulated_peeking AS (
SELECT
run_id,
day,
cumulative_p_value,
MIN(cumulative_p_value) OVER (PARTITION BY run_id ORDER BY day) AS min_p_so_far
FROM null_simulation_runs
)
SELECT
COUNT(DISTINCT CASE WHEN min_p_so_far < 0.05 THEN run_id END)::NUMERIC * 100
/ COUNT(DISTINCT run_id) AS false_positive_rate_pct
FROM simulated_peeking;Симуляция показывает, что peeking 30 раз превращает заявленный alpha 5% в фактические ~25%.
Alpha-spending O'Brien-Fleming
Идея: делим alpha по «информационной шкале». На ранних просмотрах используем очень маленький alpha, на финальном — близкий к 0.05.
WITH config AS (
SELECT 0.05::NUMERIC AS total_alpha, 5::INT AS planned_looks
),
schedule AS (
SELECT
gs AS look_number,
gs::NUMERIC / planned_looks AS information_fraction,
total_alpha
FROM config, generate_series(1, planned_looks) gs
)
SELECT
look_number,
information_fraction,
-- O'Brien-Fleming приближение: z-граница ~ z_alpha / sqrt(t)
-- z_0.05/2 ≈ 1.96; пересчёт в эффективный alpha
2 * (1 - 0.5 * (1 + ERF(1.96 / SQRT(information_fraction) / SQRT(2)))) AS alpha_for_look
FROM schedule;В Postgres нет встроенной ERF (некоторые дистрибутивы её добавляют), часто считают вне или через polynomial approximation. Логика: на 1-м просмотре alpha < 0.001, на финальном ≈ 0.04.
mSPRT в SQL
Modified Sequential Probability Ratio Test от Optimizely. Считает «mixture likelihood ratio» — растёт постепенно:
WITH cumulative AS (
SELECT
day,
SUM(CASE WHEN variant = 'B' THEN revenue ELSE 0 END) OVER (ORDER BY day) AS s_b,
SUM(CASE WHEN variant = 'A' THEN revenue ELSE 0 END) OVER (ORDER BY day) AS s_a,
SUM(CASE WHEN variant = 'B' THEN 1 ELSE 0 END) OVER (ORDER BY day) AS n_b,
SUM(CASE WHEN variant = 'A' THEN 1 ELSE 0 END) OVER (ORDER BY day) AS n_a
FROM ab_daily
),
test_stat AS (
SELECT
day,
n_a, n_b,
(s_b / NULLIF(n_b, 0) - s_a / NULLIF(n_a, 0)) AS diff,
-- упрощённое: |z| > порог = решение
(s_b / NULLIF(n_b, 0) - s_a / NULLIF(n_a, 0))
/ NULLIF(SQRT(
(s_a / NULLIF(n_a, 0) * (1 - s_a / NULLIF(n_a, 0))) / NULLIF(n_a, 0)
+ (s_b / NULLIF(n_b, 0) * (1 - s_b / NULLIF(n_b, 0))) / NULLIF(n_b, 0)
), 0) AS z
FROM cumulative
)
SELECT
day,
z,
CASE WHEN ABS(z) > 2.5 THEN 'STOP — reject H0' ELSE 'continue' END AS decision
FROM test_stat;Порог 2.5 — пример, реальный msprt-порог зависит от заданного τ (prior variance).
Always-valid p-value
Aaditya Ramdas и команда Berkeley предложили AV-p-values, которые остаются валидными при любом числе просмотров. В SQL обычно делают post-hoc adjustment к классическому p:
SELECT
day,
classical_p_value,
-- Bonferroni-like adjustment for N looks
LEAST(classical_p_value * planned_looks, 1.0) AS always_valid_p
FROM ab_daily_p_values;Грубо, но проще, чем mSPRT — годится для дашбордов.
Частые ошибки
Ошибка 1. Пытаться имитировать sequential testing «глазами». «Если 3 дня подряд p < 0.05» — это не sequential, и не контролирует alpha.
Ошибка 2. Бесконечное подсматривание. Если число просмотров неизвестно, нужен фреймворк always-valid, не fixed alpha-spending.
Ошибка 3. Альфа-спендинг для ratio-метрик без delta method. SRM / clicks-per-session — нужна вариация ratio (delta method) до того, как считаете границы.
Ошибка 4. Игнорировать SRM check на ранних шагах. Sample Ratio Mismatch (бакетинг сломан) часто проявляется в первые часы. Если sequential test «находит эффект» — проверьте SRM.
Ошибка 5. Сообщать «classical p» при sequential дизайне. В отчёте — корректированный p и информация о фреймворке (mSPRT / O'Brien-Fleming).
Связанные темы
- Как посчитать t-test в SQL
- Как посчитать Bonferroni correction в SQL
- Sequential testing простыми словами
- Как посчитать SRM в SQL
FAQ
Можно ли sequential без библиотеки?
Базовое alpha-spending — да, по табличным границам. mSPRT — лучше через сервис (Optimizely / GrowthBook).
Когда выбрать sequential vs fixed-horizon?
Sequential — когда хотите ранний stop. Fixed — когда команда дисциплинирована, готова ждать.
Какой alpha-spending для 10 просмотров?
O'Brien-Fleming или Pocock; таблицы по α=0.05, K=10 в учебниках. Точные значения — пакет gsDesign в R.
Sequential vs Bayesian?
Bayesian decision (posterior probability) даёт интуитивную остановку, но требует prior. Sequential — частотный, без приоров.
Минимум на early stop?
Никогда не останавливать до контрольной точки SRM и до minimum sample for variance estimation (обычно n > 1000 на ARM).