Group Sequential Tests: очередное ускорение тестов

Group Sequential Tests: очередное ускорение тестов

https://t.me/abba_testing

Наивная Alpha-Spending

Для начала имеет смысл рассмотреть базовый наивный подход к снаряду, он нам нужен только для того, чтобы от него потом оттолкнуться в плане теории и не возвращаться!

В момент подглядывания (оно же промежуточный анализ, interim analysis), мы будем использовать более жесткую версию нашей запланированной на финальный расчет альфы, то есть скорректированную. Чтобы скорректировать альфу, мы можем использовать alpha-spending функцию - функция, которая "расходует", берет некоторую долю альфы на каждое подглядывание:

Это один из возможных вариантов функции !

Декомпозируем:

power тут именно про возведение в степень! К мощности теста отношения не имеет

Важное свойство: на момент старта наша альфа = 0, а на контрольный анализ согласно запланированной = 0.05:

Почему старт = (0) понятно, но почему конец = (1) ? Здесь 0 и 1 это отражение полноты от запланированного эксперимента, то есть на самом деле оперируют не столько кол-вом подглядыванием, сколько % размера выборки от запланированного (столько, сколько мы охватим при данном подглядывании). Поэтому вместо конкретного значения, какое это по счёту подглядывание, мы будем указывать долю аудитории на этот момент:

  • подглядывание №1 - 0.2 (20%)
  • подглядывание №2 - 0.4 (40%)

...

Посмотрим, какой будет результат, когда мы подставим альфа = 0.05, 5 раз будем смотреть в тест (4 раза подглядыванием + наш классичесий контрольный замер) и power, то есть степень, поставим сначала как 0.2:

[ 0 - 0.00, 1 - 0.03624, 2 - 0.04163, 3 - 0.04514, 4 - 0.04782, 5 - 0.05]

Изменим power на 0.5:

[ 0 - 0.00, 1 - 0.02236, 2 - 0.03162, 3 - 0.03873, 4 - 0.04472, 5 - 0.05]

Обратите внимание, что при power = 0.5 альфы жестче!

Применение:

  • Мы можем либо заранее определиться с количеством подглядываний, и это предпочтительнее, так как это делает наш подход более строгим по процедуре. Определяемся - получаем на каждый день подглядывания альфу.
  • Либо мы можем в момент, когда хотим подсмотреть тест, поставить % размера выборки от плана.

Вот, собственно, и всё!

Конечно, подводный камень, то есть наивность, тут в том, что на самом деле ошибка 1-го рода хотя бы 1 раз тут не 0.05, а больше: мы можем совершить ошибку или в первом тесте или во втором и пр. отсюда вероятность это сумма этих альф, для примера с power = 0.2 это 0.22...

Границы по Pocock

Когда слышишь "ошибка 1-го рода хотя бы 1 раз", то в голову может прийти классика множественного тестирования - какая-нибудь поправка, например, в самом классическом виде по Бонферрони это одна и та же ужесточенная альфа на все тесты.

Для наших 4+1 подглядываний, - или interim analysises + контрольный, - наша альфа по Pocock была бы 0.0158. На самом деле Pocock (1977) вычислял не столько альфу, сколько границы значимости, а уже от них можно было рассчитать область значимости - альфу.

Метод хорош только в случае, если все наши подглядывания равноценны, что не так, банально потому, что у нас идет накопление информации к моменту каждого нового подсмотра. Можно даже сказать так: всякий промежуточный тест это оценка по некоторой доле измерений от запланированной. Например, 1-ое подглядывание = 20%, 2-ое - 40%, ... финальное - 100%. И 80% как будто состоятельнее, чем 20%.

Чуть более официально эти доли называются как information fraction

Метод Lan, Kim и DeMets

На самом деле функции alpha-spending как раз и придумали исследователи Lan, Kim и DeMets в 1983 году. И их подход был кратно мудрее, чем наивный. Чтобы ошибка 1-го рода хотя бы 1 раз была согласно альфе в дизайне, скажем, 0.05, наши все подглядывания должны иметь такие альфы, чтобы в сумме давать 0.05!

Как этого добавиться?

Возьмём степень (power) у нашей базовой alpha-spending функции = 2:

[ 0 - 0.00, 1 - 0.002, 2 - 0.008, 3 - 0.018, 4 - 0.032, 5 - 0.05]

Далее нам нужно вычесть из каждой альфы предыдущую, то есть вот так:

Пример:

  • α*(t) - α*(t-1) для t = 0.20 и t = 0.00 это будет 0.002
  • α*(0.4) - α*(0.2) = 0.008 - 0.002 = 0.006
  • α*(0.6) - α*(0.4) = 0.018 - 0.008 = 0.01

и тд.

Мы получим:

[0 - 0.00, 1 - 0.002, 2 - 0.006, 3 - 0.01, 4 - 0.014, 5 - 0.018]

Это и будут нашими новыми альфами для каждого промежуточного анализа и контрольного в том числе (0.018). В таком подходе у нас действительно будет растрата альфы в дизайне - при каждом подглядывании у нас теряется некоторая доля, прочая остается на все последующие.

Обратите внимание, что проведя тест за тестом c такими альфами, у нас ошибка 1-го рода в первом подглядывании или во втором или ... и так до контрольного будет равна альфе!

Попробуйте сложить альфы из списка выше - увидите

Так как альфа это источник критических значений (bounders - b), то

z - это статистика теста, b - критическое значение при конкретной альфе

Вот наши b, границы значимости для двустороннего теста, когда у нас большие выборки и наш t-test свёлся к z-тесту:

Минус такого подхода в том, что у нас в том числе на контрольное, конечное сравнение получается довольно жесткая альфа (больше по модулю, чем 1.96), а это значит, что у нас теряется мощность теста. И она тем больше теряется, тем больше мы подглядываем в тест.

В некоторых точках (4, 6, 8 подглядываний) мощность больше только потому, что в симуляции страдала неравномерность разбиения выборки на каждое подглядывание

В целом, тут все тот же мотив, который пронизываем многое в AB: всегда чем-то жертвуешь в угоду контроля некоторого параметра. Тут классика: хотим контролировать ошибку 1-го рода на все семейство тестов (FWER) - увеличиваем ошибку 2-го рода!

И последним не стоит пренебрегать! Есть такая ошибка как M-ошибка, ошибка эффекта. То есть у нас есть переоценка эффекта, в случае, если мы обнаружили значимость. Мощность с M-ошибкой напрямую связана, см. этот пост: вот примерная функциональная зависимость:

Даже при классической мощности есть риск превышения на 16%!

Если у вас стат. значимый эффект в момент подсмотра, то именно тут рекомендую оценить мощность и перевзвесить эффект (формулу выводили в уже указанном посте):

Поздравляю, мы на самом деле только что рассмотрели подход в ускорении наших тестов как Group Sequential Testing, также старый как мир

Дополнительно: функций alpha-spending много, есть и те, которые определяются через кумулятивное распределение (O'Brien-Fleming); правильный выбор я бы назвал таким, который как минимум корректно ведет себя в симуляции в плане мощности (а не как у меня) и который вы сами находите подходящим для вашего случая / эксперимента.

Futility

Но что если мы хотим останавливать тест не только, когда обнаружим стат. значимый результат, но и тогда, когда крайне маловероятно, что наш ожидаемый эффект вообще существует? Снова-таки чтобы не тратить зря времени!

Такой подход называется как futility, то есть обнаружение тщетности наших попыток. И здесь мы от alpha-spending просто переходим к beta-spending, правда не совсем так, как ожидаем.

Pampallona и Kim (2021)

Функция у нас может быть та же, что и для alpha-spending + тот же алгоритм вычета, просто в нее мы подставляем beta (классика = 0.2) и получаем, например, вот такие значения:

[0 - 0.00, 1 - 0.008, 2 - 0.024, 3 - 0.04, 4 - 0.056, 5 - 0.072], в сумме 0.2

Однако вопрос, а что с ними делать, куда прикладывать?

Если мы делаем все с умом, то у нас должен быть согласованный MDE, на который мы согласны, либо в худшем случае желаемый, экономически целесообразный эффект, под который мы собрали размер выборки.

MDE - это минимальный эффект, что мы можем обнаружить при нашей конфигурации теста, если он вообще есть! А значит, его может и не быть: тогда в каком случае мы могли бы отвернуть гипотезу о том, что он есть? Только если мы это сделаем относительно HA! Но как получить HA? На конкретный момент подглядывания мы можем свиднуть H0 на запланированный MDE/SE, где SE - это оценка отклонения разниц текущего подглядывания, если это two-sample test.

Обычно, все мыслят сдвиг вправо, некоторый прирост, у нас так же!

Выходит, наш список beta's - это список на самом деле альф для HA.

Но на самом деле все гораздо проще: нам нужно построить критическое значение согласно конкретной beta на H0 и сдвинуть имеено его на MDE/SE!

Важно:

  1. Мы не можем прибавить к Mu_H0 просто MDE, потому что мы оперируем стандартным распределением, значит должны именно получить z-score MDE относительно H0 в рамках конкретных выборочных данных на момент промежуточной оценки.
  2. Раз beta теперь альфа, то при проверке "Mu_B не равно Mu_A" мы обязаны использовать двусторонний тест, а значит каждую beta делить пополам. Возьмем beta №1 дает зону для HA cлева = 0.008 / 2 = 0.004, смотрим:


Интерпретация такая: если у нас значение меньше сплошной фиолетовой линии, то отклоняем гипотезу о таком MDE, тщетно (futilely) искать таковой!

Выходит, в рамках каждого теста у нас две ассиметричные границы - для стат. значимости и для futility:

Сверху значимость, снизу - fulility; разная удаленность заметка невооруженным взглядом

Получается, мы можем ускорить тесты с двух сторон!

Нюансы:

  1. Если эффекта нет, то чем чем больше мы подглядываем, тем реже будем обнаружить тщетность наших усилий. Ок, нестрашно.

При этом сама доля таких фиксаций тщетности будет хоть и небольшой, но все же полезной. Или нет?..

2. Однако если эффект есть, у нас есть риск совершить ошибку, - не знаю, как верно назвать, - futility-error: не просто не обнаружить эффект как это есть при ошибке 2-го рода, а признать, что его нет вообще! Потому что именно так мы и будем думать и это будет выраженнее, чем просто при отсутствии стат. значимости. График похож на предыдущий, и он же может служить и оценкой fulfility-error:

Однако там, где у нас много подглядываний, там жестче границы, а поэтому много подглядывать для нас играет тут положительную роль.

В принципе, рассчитав MDE и зная поведение этой ошибки от кол-ва подсмотров, мы можем сделать и ее коррекцию, если только планируем (sic!) подглядывания. Например, пускай beta = alpha для beta-spending. Но как всегда, ценой увеличения того, что нам будет сложнее остановить тест, если эффекта а-ля MDE нет!

Заключение

На мой взгляд Group Sequential Testing через alpha/beta-spending куда как прямолинейнее и понятнее, чем mSPRT - сплошь привычные нам альфы и беты, просто под другим углом.

Это не серебряная пуля и нам будем чем жертвовать при его применении: мощностью и выводом/ошибкой про тщетность. Но с другой стороны, как уже и сказал, это весьма прозрачный метод в использовании с простыми концепциями под капотом. Легко объяснить, легко имплементировать.

Пользуйтесь!

Report Page