/docs
, так же в виде комментариев к коду.
Разработать сервис прескоринга клиентов с функционалом дополнительной клиентской аналитики для повышения конверсии.
Цель - разработать алгоритм для пре-скоринга по анкетам клиентов, чтобы выдавать лучшие предложения клиенту, а также предлагать варианты (сумма - срок кредита) для повышения вероятности одобрения и объяснять решение пре-скоринга.
Если клиент считается полностью ненадежным, то лучше вообще не рекомендовать его банкам. Это поможет избежать репутационных убытков, предотвратив статистику о большом количестве неблагонадежных клиентов, связанных с Mandarin и/или конкретным магазином, по сравнению с другими сервисами.
Цель прескоринга — со стороны банков заранее отсеять совсем неблагонадежных клиентов, не расходуя время и деньги на их дальнейшую проверку, со стороны клиента, смогут принимать более обоснованные решения, выбирая банк не только по условиям кредита, но и учитывая свои шансы на успех.
Цель дополнительного функционала:
для стейкхолдера:
- дополнительная аналитика по клиентам
- возможность разбивать клиентов на обоснованные когорты
- [гипотеза] дополнительная конверсия за счет уникальной аналитики для клиента (как сконфигурировать кредит, что помешает взять)
для клиента:
- развернутая аналитика по пре-скорингу (выгодно отличает от закрытых моделей скоринга банков) - продумать с точки зрения безопасности.
- реклама на основе когорты клиента (возможно будет уместно)
Основное конкурентное преимущество - прозрачность принятия решения, дополнительная аналитика, распределенное API.
Инструкции по настройке окружения для скачивания и запуска проекта локально.
Копирование репозитория:
git clone https://github.com/xausssr/urfum_hack_3.git
Переход в директорию проекта с основным кодом:
cd urfum_hack_3/src
Для сборки контейнеров:
- перейти в
src
cd urfum_hack_3/src/
- построить образ для API
docker build -t urfum/prescoring_api -f DockerfileApi .
- построить образ для WORKER
docker build -t urfum/prescoring_worker -f DockerfileWorker .
- запустить образы (с учетом проброса портов из докера наружу)
- стартуем api
docker run -it --rm -p 8000:8000 -d -v <путь до репозитория>\urfum_hack_3\src\data:/prescoring_api/data --name precsoring-api urfum/prescoring_api
- стартуем worker
docker run -it --rm -d -v <путь до репозитория>\urfum_hack_3\src\data:/worker/data --name precsoring-w1 urfum/prescoring_worker
Воркеры запускаются только после запуска api! Иначе базы не инициализируются!
Так как mvp на SQLite3 (однофайловая БД, для скорости разработки), нужно пробросить папку src/data
в контейнеры. На проде можно заменить на postgres или, если прямо много всего - то разнести: задачи на kafka (ил rabbitmq/zmq), базу на кластер postgres.
Размеры образов
- api ~ 180 Mb образ
- worker ~ 1.3 Gb образ
- перейти в
src
cd urfum_hack_3/src/
- Запустить сборку проекта:
docker-compose build
- Запустить образы
docker-compose up -d
- Для остановки проекта набираем команду:
docker-compose stop
После запуска, локальный проект будет доступен по адресу: http://localhost:8000/ или http://0.0.0.0:8000/
До 16.12.2023 сервис доступен на http://sgorynych.pro:8000/
Если зайти с браузера на основной эндпоинт (/
, либо http://sgorynych.pro:8000/
) будет редирект на подробную документацию Api (эндпоинты, структуры данных, ответы, ошибки).
Для тестирования использовать любой генератор запросов или (postman, curl и т.д.) или воспользоваться встроенной в FastAPI swagger документацией (кнопка "Try it out")
Сервис работает по следующей схеме:
- Клиент посылает POST-запрос к API на
/upload_features
, после чего API берет хэш от объекта и смотрит в базу - если такого не было - добавляет в таблицу задач новую задачу, если был - ничего, возвращает клиенту хэш. - Клиент опрашивает через некоторое время API get-запросом на
/check_state
с полученным ранее хэшем. Если true - шаг 3, если false - продолжает периодический опрос. - Клиент запрашивает результат через GET-запрос
/get_result
с ранее полученным хэшем и получает его в заданном формате.
При тестирование возможны разные длительности выполнения задачи - очередь общая для всех.
Подробная документация эндпоинта в swagger
Отправляем данные на обработку /upload_features
- POST-запрос, тело (имена колонок преобразованы: все в нижний регистр, пробелы заменены на "_"):
{
"birthdate": "1988-07-21 00:00:00.0000000",
"education": "Высшее - специалист",
"employment_status": "Работаю по найму полный рабочий день\\/служу",
"value": "9 - 10 лет",
"jobstartdate": "2013-09-01 00:00:00.0000000",
"position": "начальник п",
"monthprofit": 180000.0,
"monthexpense": 100000.0,
"gender": 0,
"family_status": "Никогда в браке не состоял(а)",
"childcount": 0,
"snils": 0,
"merch_code": 77,
"loan_amount": 137000.0,
"loan_term": 18.0,
"goods_category": "Furniture"
}
Если данные корректны - вернется:
{
"task_id": "0bf47865db14802e29de4d4f769c00b97966a691", // хеш задачи
"is_complete": false // есть ли ответ по ней, если отправить ранее загруженные данные - будет true, можно сразу на шаг 3
}
Если признак не передан - модель считает значение признака пропуск
. Если не соблюден формат данных (например, в текстовую фичу отправили число):
{
"detail": [
{
"type": "string_type",
"loc": [
"body",
"goods_category" // имя ошибочной фичи
],
"msg": "Input should be a valid string", // пояснение
"input": 120,
"url": "https://errors.pydantic.dev/2.5/v/string_type"
}
]
}
Подбробное описание структуры данных: документация, раздел Schemas -> FeaturesStructure.
Подробная документаця эндпоинта в swagger
После удачной отправки данных опрашиваем (переодически) /check_task
c аргументом task_id
- GET-запрос:
http://sgorynych.pro:8000/check_task?task_id=0bf47865db14802e29de4d4f769c00b97966a691
Если задача готова - вернется true
- просто булевое значение, если еще в очереди - false
.
При подаче некорректного task_id
вернет ошибку 404 с телом:
{
"detail": "Task not found"
}
Если указан не верный аргумент:
{
"detail": [
{
"type": "missing", // пропущен аргумент
"loc": [
"query",
"task_id" // какой нужно указать
],
"msg": "Field required", // сущность ошибки
"input": null,
"url": "https://errors.pydantic.dev/2.5/v/missing"
}
]
}
Подробная документаця эндпоинта в swagger
Если на шаге 2 вернулось true
необходимо послать запрос на /get_result
c аргументом task_id
- GET-запрос:
http://sgorynych.pro:8000/get_result?task_id=0bf47865db14802e29de4d4f769c00b97966a691
Ошибки аналогичны пункту 2
В ответе будет json с id задачи и вероятностью для каждого банка:
{
"task_id": "0bf47865db14802e29de4d4f769c00b97966a691",
"bank_a": "0.40770822763442993",
"bank_b": "0.6711390018463135",
"bank_c": "0.5725244879722595",
"bank_d": "0.4870204031467438",
"bank_e": "0.4528646767139435"
}
API построено на конфигах - можно изменять количество банков, используемые фичи, хост и порт api и расположение БД. Файлы содержатся в src/configs
- Андрей Толстых - руководитель команды, ML, аналитик данных
- Вадим Ахметов - ML-инженер, аналитик данных
- Дмитрий Акинин - защита проекта, подготовка документации, сбор и анализ данных
- Илья Колосов - ML, аналитик данных
- Ирамаль Искужин - бекенд-разработчик, аналитик данных