- BrainTools - https://www.braintools.ru -

Мы думали, что в скоринге важен размер выборки. Оказалось, что дело в числе дефолтов

Сравниваем TabPFN-2.5 и CatBoost на банковских данных и считаем, сколько стоит выигрыш в качестве

Когда я начинал эксперимент, гипотеза была простой: чем больше заявок в обучении [1], тем лучше модель. Это звучит очевидно, однако данные показали другое.

Возьмём три набора для обучения, в каждом из которых ровно 500 дефолтных заявок. В первом всего 2 000 заявок (25% дефолтных), во втором 5 000 (10%), в третьем 50 000 (1%). CatBoost на них показывает почти одинаковое качество: ROC AUC 0,683, 0,681 и 0,686. Размер выборки отличается в 25 раз, а результат тот же. Совпало только число дефолтов.

Дальше о том, как я к этому пришёл, где новая табличная модель TabPFN обгоняет CatBoost и почему «взять лучшую» оказалось не самым полезным вопросом.

Задача: две ошибки с разной ценой

Банк решает, выдавать ли кредит, и ошибиться может двумя способами. Ошибка [2] I рода: кредит выдали клиенту, который потом ушёл в дефолт. Это прямые потери банка, и в работе она главная. Ошибка II рода: отказали клиенту, который вернул бы кредит, то есть банк потерял прибыль. Чтобы сравнивать модели честно, я не брал порог 0,5, потому что вероятности у моделей, обученных на выборках с разной долей дефолтов, смещены. Вместо этого я фиксировал долю отказов: на валидации находится порог, при котором отказывают 10% самых рискованных заявок, и он применяется к тесту.

Чтобы сравнивать модели честно, я не брал порог 0,5: вероятности у моделей, обученных на выборках с разной долей дефолтов, смещены. Вместо этого я фиксировал долю отказов: на валидации находится порог, при котором отказывают 10% самых рискованных заявок, и он применяется к тесту.

import numpy as np

def threshold_by_reject_rate(p_val, q):
    #Порог, при котором отказывают доле q самых рискованных заявок.
    return np.quantile(p_val, 1 - q)

thr = threshold_by_reject_rate(p_val, q=0.10)
reject = p_test >= thr
err1 = ((~reject) & (y_test == 1)).sum() / (y_test == 1).sum()  # пропущенные дефолты

При такой постановке ошибка II рода у всех моделей почти одинакова (около 0,09–0,10), поэтому сравнивать их нужно по ошибке I: сколько дефолтов модель пропустила.

Участники

CatBoost — базовый вариант. Градиентный бустинг над деревьями давно стал стандартом для таблиц. Он быстро учится и спокойно работает в проде.

TabPFN-2.5 — табличная foundation‑модель. Она предобучена на огромном числе синтетических задач и на ваших данных не обучается в привычном смысле: вы отдаёте ей обучающую выборку как контекст, и она выдаёт ответ за один прямой проход. Заявлено, что она особенно хороша на малых выборках.

Ограничение: лицензия TabPFN-2.5 некоммерческая. Для исследований это нормально, а «просто внедрить в банке» нельзя. Версию модели я задавал явно: в новых релизах пакета по умолчанию грузится уже другая.

Данные

Я взял открытый обезличенный набор кредитных историй Альфа‑Банка (соревнование Data Fest): 3 млн заявок, дефолт определяется как просрочка 90+ дней за 12 месяцев, доля дефолтов 3,55%. Историю клиента (несколько прошлых кредитов на заявку) я свёл к одной строке из 128 признаков.

Ограничения данных стоит назвать сразу. Анкеты нет, есть только кредитная история. В наборе только те клиенты, которым банк кредит выдал, поэтому выборка смещена. Смысл кодов статусов платежей не раскрыт, и я их не интерпретирую. Разбиение сделано по времени, а не случайно: модель учится на прошлом и применяется к будущему, а случайное разбиение скрыло бы дрейф и завысило качество. Доля дефолтов действительно «плывёт»: 3,61% в обучающем пуле, 3,49% на валидации и 3,21% на тесте.

Разбиение сделано по времени, а не случайно: модель учится на прошлом и применяется к будущему. Случайное разбиение скрыло бы дрейф и завысило качество. Доля дефолтов действительно «плывёт»: 3,61% в обучающем пуле, 3,49% на валидации и 3,21% на тесте.

Из обучающего пула я нарезал 60 подвыборок: размер от 2 000 до 50 000 заявок, доля дефолтов 1%, естественная, 10% и 25%, по три повтора.

Находка № 1: качество определяют дефолты, а не строки

Я построил регрессию ROC AUC на логарифм числа дефолтов в обучении и отдельно на логарифм размера выборки. Число дефолтов объясняет 86–92% разброса качества между запусками, размер выборки только 23–44%.

Объём данных тоже влияет, но признаки коррелируют. На практике в скоринге редкий класс — главный дефицит. Если у вас мало дефолтов, то миллион «хороших» заявок почти не поможет.

 Рис. 1: Качество CatBoost на полном тесте растёт с числом дефолтов в обучении, а не с размером выборки: три набора с 500 дефолтами дают почти один и тот же AUC (0,681–0,686).

Рис. 1: Качество CatBoost на полном тесте растёт с числом дефолтов в обучении, а не с размером выборки: три набора с 500 дефолтами дают почти один и тот же AUC (0,681–0,686).

Находка № 2: где TabPFN выигрывает

Дальше я сравнил TabPFN и CatBoost на одних и тех же объектах. Из‑за стоимости вывода TabPFN считался на подмножествах валидации и теста по 10 000 объектов, на видеокарте Tesla T4 в Colab.

Результаты такие: при обучающей выборке до 10 000 объектов TabPFN нигде не хуже CatBoost по ROC AUC, а в 7 из 12 режимов выигрыш статистически значим, в основном при доле дефолтов 1% и естественной. Чем больше дефолтов в обучении, тем меньше преимущество, и это согласуется с находкой № 1. При 25 000 объектов модели неразличимы.

В бизнес‑метриках: при отказе 10% самых рискованных заявок TabPFN пропускает в среднем 75,0% дефолтов, CatBoost — 77,7%. Разница в несколько процентных пунктов, не революция. Абсолютные ошибки в обоих случаях высокие: AUC около 0,7, пропускается около трёх четвертей дефолтов.

Возможное объяснение: при малом числе дефолтов TabPFN опирается на знания, полученные при предобучении, а бустингу приходится выучивать всё из данных. Я это не проверял: измерено только то, что разница убывает с ростом числа дефолтов.

Рис. 2: Доля пропущенных дефолтов при отказе 10% заявок (естественная доля дефолтов; полосы - среднее ± стандартное отклонение по трём seed’ам). На малых выборках TabPFN выигрывает, при 25 000 объектов модели совпадают.

Рис. 2: Доля пропущенных дефолтов при отказе 10% заявок (естественная доля дефолтов; полосы — среднее ± стандартное отклонение по трём seed’ам). На малых выборках TabPFN выигрывает, при 25 000 объектов модели совпадают.

Цена вопроса

У TabPFN «обучение» почти бесплатное, зато вывод дорогой, потому что через сеть проходит вся обучающая выборка:

Размер обучения

2000

5000

10 000

25 000

Вывод TabPFN на 20 000 объектах, с

84

160

333

1243

Время растёт быстрее, чем размер данных. Бустинги на этом фоне дешёвые: LightGBM учится за секунды, CatBoost — за десятки секунд на процессоре. Оборудование разное (CPU и T4), поэтому сопоставлять можно только порядки. До 50 000 объектов на T4 TabPFN довести не удалось: в режиме с кэшем не хватило памяти [3].

Менеджер, который покупает скидку, а не качество

Из этого родилась идея «менеджера моделей»: правила, которое по характеристикам режима выбирает, кому доверить предсказание. Если дефолтов мало и выборка не слишком велика, берём TabPFN, иначе CatBoost. Пороги подбираются перебором на валидации, а цель такая:

J=E_{mathrm{I}} + mu , C ;to; min,

где E_{mathrm{I}} — ошибка I рода, C — относительная стоимость вычислений, mu — цена вычислений: сколько ошибки банк готов уступить ради экономии времени.

Главный результат: менеджер не улучшает качество. При μ = 0 лучшим оказывается «TabPFN везде»: до 25 000 объектов TabPFN не уступает CatBoost ни в одном режиме, и переключаться не на что.

Менеджер задаёт компромисс между качеством и стоимостью вычислений:

Правило

Ошибка I рода

Отн. стоимость

CatBoost везде

0,777

0,19

TabPFN везде

0,750

1,00

Менеджер, μ = 0,01

0,753

0,49

Менеджер, μ = 0,02

0,758

0,34

При μ = 0,01 мы платим +0,3 п.п. ошибки I рода (интервал включает нуль) и экономим около половины вычислений. При μ = 0,02 платим +0,8 п.п. (разница уже значима) и экономим две трети.

Оговорки: экономию даёт в основном ограничение размера выборки Nmax, а порог по числу дефолтов определяется слабо и нестабилен, если исключить один размер выборки. Так что это не готовое правило для прода, а методика, показывающая, где лежит граница компромисса.

 Рис. 3: Граница компромисса менеджера: чем больше допустимая потеря качества, тем меньше вычислений.

Рис. 3: Граница компромисса менеджера: чем больше допустимая потеря качества, тем меньше вычислений.

Где модели ошибаются

Я посмотрел на ошибки отдельно. Вывод:

Обе модели пропускают в основном одних и тех же клиентов: 69,1% дефолтов пропущены обеими сразу, а поймать их хотя бы одной из двух удаётся лишь в 30,9% случаев (15,2% ловят обе, 10,7% только TabPFN, 5,0% только CatBoost). Поэтому «ансамбль мнений» тут мало что даёт.

Преимущество TabPFN сосредоточено у клиентов с короткой кредитной историей: при одном‑трёх прошлых кредитах она пропускает 56–57% дефолтов против 69–70% у CatBoost. Кроме того, пропущенные дефолты по имеющимся признакам почти неотличимы от добросовестных клиентов. Вероятно, решающие факторы лежат вне кредитной истории, а анкеты в данных нет.

Что я не проверял

TabPFN считался на подмножестве теста в 10 000 объектов, при размере обучения до 25 000, на одном ускорителе и без подбора гиперпараметров. CatBoost тоже не настраивался, так что при настройке разрыв мог бы сократиться. Выборка смещена (в ней только одобренные заявки), поэтому выводы о всём потоке заявок делать нельзя. Доверительные интервалы учитывают выбор объектов теста, но не разброс по обучающим подвыборкам, а времена измерены на разном железе и сопоставимы только по порядку величины.

Выводы

  1. В скоринге с дисбалансом важнее число редких примеров, чем общий размер выборки.

  2. На малых выборках и при редких дефолтах TabPFN не хуже CatBoost, а часто лучше, но платит временем вывода и ограничениями лицензии.

  3. Бустинги остаются быстрой и дешёвой базой, особенно когда дефолтов достаточно.

  4. Выбор модели — это выбор точки на кривой «ошибка и вычислительная цена», а не поиск победителя.

Код и скрипты воспроизведения: https://github.com/colziks/credit‑scoring‑model‑manager [4] (данные в репозиторий не входят).

Автор: colziks

Источник [5]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/38567

URLs in this post:

[1] обучении: http://www.braintools.ru/article/5125

[2] Ошибка: http://www.braintools.ru/article/4192

[3] памяти: http://www.braintools.ru/article/4140

[4] https://github.com/colziks/credit‑scoring‑model‑manager: https://github.com/colziks/credit-scoring-model-manager

[5] Источник: https://habr.com/ru/articles/1107838/?utm_campaign=1107838&utm_source=habrahabr&utm_medium=rss

www.BrainTools.ru

Rambler's Top100