Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

credit_risk — прогноз проблемных кредитов

Python scikit-learn PostgreSQL

Модель бинарной классификации, которая по анкете клиента заранее оценивает: вернёт он кредит или нет.

Содержание

Установка и запуск

  1. Клонировать репозиторий и установить зависимости:

    git clone https://github.com/DesertFull-sql/credit-risk.git
    cd credit-risk
    pip install -r requirements.txt
  2. Создать файл .env по образцу .env.example и указать строку подключения к базе данных:

    DATABASE_URL=postgresql+psycopg2://user:password@localhost/dbname
    
  3. Сравнить модели через кросс-валидацию:

    python -m src.train
  4. Оценить лучшую модель на отложенном тесте и сохранить её:

    python -m src.evaluate

Результат сохраняется в файл models/credit_model.joblib.

Структура проекта

credit_risk/
├── .env                 # секреты
├── .env.example         # шаблон конфигурации
├── requirements.txt     # зависимости
├── data/                # данные
├── models/              # сохранённые модели
├── notebooks/           # эксперименты
└── src/
    ├── config.py        # настройки проекта: пути, признаки, константы
    ├── data.py          # загрузка данных из PostgreSQL (SQLAlchemy)
    ├── preprocess.py    # очистка: дубликаты, выбросы
    ├── features.py      # трансформеры признаков (ColumnTransformer)
    ├── models.py        # сборка пайплайнов трёх моделей
    ├── train.py         # обучение и кросс-валидация
    └── evaluate.py      # итоговая оценка и сохранение модели

Постановка бизнес-задачи

Банк выдаёт кредиты и теряет деньги на клиентах, которые их не возвращают.

Проблема: в момент заявки не видно, кто в итоге окажется надёжным, а кто — нет.

Задача: до выдачи кредита, используя только данные из анкеты (возраст, доход, стаж, параметры кредита), спрогнозировать, станет ли клиент проблемным. Тип задачи — бинарная классификация (два исхода: «в норме» / «проблемный»).

Что это даёт банку:

  • меньше невозвратов и потерь;
  • обоснованное решение: кого одобрить, а кого проверить внимательнее;
  • скорость: модель отвечает мгновенно, вручную такой анализ за секунды не сделать.

Исходные данные

Данные: таблица credit_risk в локальной базе PostgreSQL — 32 581 анкета, 11 признаков + целевая переменная.

Признак Что означает
person_age возраст
person_income годовой доход
person_emp_length стаж работы в годах
loan_amnt запрашиваемая сумма кредита
loan_int_rate процентная ставка
loan_percent_income доля ежемесячного платежа в доходе
cb_person_cred_hist_length срок кредитной истории
person_home_ownership жильё: своё, в ипотеке, аренда и т. п.
loan_intent цель кредита
loan_grade кредитный рейтинг клиента
cb_person_default_on_file были ли просрочки раньше
loan_status целевая переменная: в норме (0) / проблемный (1)

Классы несбалансированы: проблемных кредитов значительно меньше, чем нормальных, — это учтено при обучении (class_weight="balanced").

Что сделала модель

  1. Загрузил данные из PostgreSQL через SQLAlchemy.
  2. Очистил данные (data cleaning): удалил полные дубликаты строк, отбросил выбросы (возраст старше 100 лет, стаж больше 50 лет), заполнил пропуски (импутация): loan_int_rate — медианой, person_emp_length — константой -1.
  3. Подготовил признаки (feature engineering): категориальные колонки (цель кредита, тип жилья, рейтинг) закодировал OneHotEncoder с handle_unknown="ignore"; для линейной модели добавил масштабирование StandardScaler; всё собрал в единый ColumnTransformer, а его — в прогнозный конвейер Pipeline вместе с моделью.
  4. Обучил три модели: случайный лес (RandomForest, 300 деревьев), дерево решений (DecisionTree, глубина 8) и логистическую регрессию (с масштабированием признаков).
  5. Оценил честно через кросс-валидацию: каждую модель обучал на 5 фолдах данных и проверял на невиданных (стратифицированная схема, чтобы пропорции классов сохранялись). Метрики: accuracy, precision, recall, F1, ROC-AUC.
  6. Проверил лучшую модель на отложенном тесте (20% данных, которых модель никогда не видела, с сохранением пропорций классов) и сохранил её через joblib.

Результаты

Сравнение моделей (5-фолдная кросс-валидация, mean ± std)

Модель ROC-AUC F1
Random Forest (случайный лес) 0.932 ± 0.005 0.818 ± 0.016
Decision Tree (дерево решений) 0.904 ± 0.005 0.776 ± 0.014
Logistic Regression (логистическая регрессия) 0.870 ± 0.006 0.642 ± 0.004

Лучший и самый стабильный результат у случайного леса, поэтому дальше работаю с ним.

Итоговая оценка на отложенном тесте (случайный лес)

Тест: 6 482 анкеты, которых модель не видела.

Метрика Значение
Accuracy (доля верных ответов) 0.94
ROC-AUC 0.9356

Матрица ошибок (confusion_matrix):

          предсказано
           0      1
 факт 0 [5042    22]
      1 [ 395  1023]
  • Precision класса 1 = 0.98 — из 100 анкет, которые модель назвала проблемными, ~98 действительно проблемные. Ложных тревог почти нет.
  • Recall класса 1 = 0.72 — модель поймала 1 023 из 1 418 проблемных кредитов (~3 из 4), пропустила 395. Часть «плохих» проходит как «хорошие».

Выводы

  • Случайный лес обходит обе альтернативы и стабилен на всех фолдах — результат надёжный.
  • Модель предупреждает редко, но почти всегда по делу: precision = 0.98.
  • Цена этой осторожности — recall = 0.72: примерно четверть проблемных кредитов пропускается. Если для банка важнее не упустить дефолты, порог решения можно сместить вручную — это выбор бизнеса, а не техники.
  • Для банка модель полезна как первый фильтр заявки: явно проблемные — на проверку, остальное — стандартный поток.

Дальнейшие шаги

  • подбор гиперпараметров через GridSearchCV;
  • индикаторы пропусков (add_missing_indicators);
  • отбор признаков и сравнение с бустингами (XGBoost, LightGBM);
  • развёртывание модели как сервиса (FastAPI) для проверки заявок онлайн.

About

Бинарная классификация кредитного риска с помощью Scikit-learn (случайный лес, ROC-AUC 0,936)

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages