Как определить длительность A/B-теста для оценки модели кредитного скоринга?

Ответ

При планировании A/B-теста для кредитного скоринга я определял длительность, исходя из двух ключевых факторов: статистической достаточности и бизнес-цикла кредита.

Мой расчётный процесс:

  1. Определение целевой метрики и MDE. Основная метрика — коэффициент дефолта (Default Rate, DR). Я договаривался с бизнесом о минимальном значимом эффекте (MDE). Например, мы хотели обнаружить снижение DR с 5.0% до 4.5% (MDE = 0.5 п.п.).

  2. Расчёт необходимого размера выборки. Использовал калькулятор мощности для пропорций (двухвыборочный Z-тест):

    from statsmodels.stats.power import NormalIndPower
    from statsmodels.stats.proportion import proportion_effectsize
    
    # Исходные параметры
    p1 = 0.05  # DR в контроле
    p2 = 0.045 # Ожидаемый DR в тесте
    alpha = 0.05  # Уровень значимости
    power = 0.8   # Статистическая мощность
    
    # Расчёт эффекта и размера выборки на группу
    effect_size = proportion_effectsize(p1, p2)
    analysis = NormalIndPower()
    sample_size_per_group = analysis.solve_power(effect_size=effect_size, alpha=alpha, power=power)
    print(f"Необходимо заявок на КАЖДУЮ группу: {int(sample_size_per_group)}")
  3. Учёт периода наблюдения (observation window). Для кредита важен полный цикл — время, за которое становится ясно, платёжеспособен ли заёмщик. В моих проектах это было 3-6 месяцев (зависит от продукта: кредитная карта или автокредит).

  4. Расчёт длительности теста.

    • Допустим, по расчётам нужно 10 000 заявок на группу, а в тест идёт 50% трафика.
    • Если ежедневно поступает 500 заявок, то тестовая группа получает 250 в день.
    • Фаза набора: 10 000 / 250 = 40 дней для набора достаточной выборки.
    • Итоговая длительность: 40 дней (набор) + 90 дней (наблюдение за дефолтами) = ~130 дней.

Важно: Я всегда добавлял буфер на сезонность (например, не запускать набор в декабрьские праздники) и проверял, что в тесте участвуют все типы заёмщиков.

Ответ 18+ 🔞

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

Как я, сука, считал:

  1. Целевая метка и MDE. С бизнесом договориться — это отдельный ёперный театр. Объясняешь им, что смотрим на дефолты (Default Rate, DR). Говорю: «Ребята, какое изменение для вас овердохуища, чтобы паханы наверху заметили?». Допустим, сошлись на том, чтобы поймать падение с 5.0% до 4.5%. Вот тебе и MDE — 0.5 процентного пункта. Ни хуя себе амбиции!

  2. Считаем, сколько нам нужно народу. Беру свой калькулятор мощности, э бошка думай, и вбиваю цифры. Код простой, но без него — пиздопроебибна ситуация, будешь на глазок мерять.

    from statsmodels.stats.power import NormalIndPower
    from statsmodels.stats.proportion import proportion_effectsize
    
    # Исходные параметры
    p1 = 0.05  # DR в контроле
    p2 = 0.045 # Ожидаемый DR в тесте
    alpha = 0.05  # Уровень значимости
    power = 0.8   # Статистическая мощность
    
    # Расчёт эффекта и размера выборки на группу
    effect_size = proportion_effectsize(p1, p2)
    analysis = NormalIndPower()
    sample_size_per_group = analysis.solve_power(effect_size=effect_size, alpha=alpha, power=power)
    print(f"Необходимо заявок на КАЖДУЮ группу: {int(sample_size_per_group)}")

    Выдаёт тебе циферку. Допустим, 10 000 на группу. Удивление пиздец — а где ж их столько набрать-то?

  3. А тут главный подвох — окно наблюдения. Это ж кредиты, чувак! Нельзя через неделю посмотреть и решить, платёжеспособный клиент или пидарас шерстяной. Нужно дать ему время проявить себя. В моих случаях это 3-6 месяцев, пока не станет ясно — герой он или бздун, который сольётся. Вот и приплюсуй эти месяцы ко всему сроку.

  4. Итоговая арифметика, ебушки-воробушки.

    • Нужно 10 000 заявок на тест. Трафик делим пополам.
    • Если в день 500 заявок, то в тест идёт 250.
    • Набираем выборку: 10 000 / 250 = 40 дней. Месяц с хвостиком.
    • А теперь ждём: 40 дней + 90 дней наблюдения = вот тебе и ~130 дней, больше четырёх месяцев!

И последний штрих, без которого — хитрая жопа. Всегда смотрел, чтобы в тест попали все типы клиентов — и те, что с ипотекой, и те, что распиздяи смердящие. И на календарь глядел, чтобы набор не на новогодние праздники пришёлся, а то терпения ноль ебать будет ждать, пока все с похмелья отойдут. В общем, хуй с горы — задача не для слабонервных.