Проект представляет собой ML-сервис для предсказания стоимости коммерческого транспорта на основе входных характеристик.
В соответствии с бизнес-задачей, основной фокус сделан на минимизации количества запрашиваемых у пользователя данных при сохранении высокой точности модели. Архитектура решения включает в себя модель машинного обучения, обернутую в кастомный scikit-learn пайплайн, Backend-сервис на FastAPI и Frontend-интерфейс на Streamlit.
Необходимо перед запуском контейнеров или локального тестирования загрузить веса:
- Предобученного пайплайна
cars_pipe.pkl - Обученный CatBoostRegressor
catboost_model.cbm
Данные файлы нужно скачать по ссылке и положить в папку app/model
Запуск микросервисов осуществляется в изолированных контейнерах.
# 1. Клонирование репозитория
git clone https://github.com/1337Tema/sber-ds-test.git
cd sber-ds-test
# 2. Сборка и запуск контейнеров
docker-compose up --build -d
# 3. Проверка статуса контейнеров
docker-compose psДоступные эндпоинты:
- Frontend (UI интерфейс):
http://localhost:8501 - Backend API (Swagger UI):
http://localhost:8000/docs - Healthcheck API:
http://localhost:8000/status
Для обновления весов модели или изменения логики предобработки:
# 1. Создание виртуального окружения и установка зависимостей
python -m venv .venv
.venv/Scripts/activate
pip install -r requirements.txt
# 2. Пересборка Pipeline
python app/model/pipeline.pyВ ходе проведения Exploratory Data Analysis (EDA) были выявлены следующие ключевые инсайты, определившие подход к предобработке:
- Дублирование и мультиколлинеарность признаков:
Признаки из ПТС (
engine_volume_pts,horse_power_pts) сильно дублировали фактические признаки (engine_volume,horse_power). Было принято решение оставить по одному признаку, заполнив пропуски значениями из колонок-дублей. Признакemission_class(класс выбросов) показал строгую прямую корреляцию сmake_year(годом выпуска) и был удален как избыточный. - Восстановление пропусков через зависимости:
- Выявлена строгая зависимость между типом кузова (
body_type) и типом шасси (chassis_type). Пропуски шасси успешно заполнены модой по группам кузова. - Пропуски объема двигателя восстанавливались с помощью многоуровневой группировки от строгой
[Марка + Тип кузова + Тип двигателя]до глобальной медианы.
- Выявлена строгая зависимость между типом кузова (
- Извлечение скрытых данных из текста и ссылок:
- Из колонки
urlудалось извлечь платформу-источник (auto.ru / drom.ru) и восстановить признак типа техники (url_tech_type). - С помощью регулярных выражений и словарей из текстовых полей
body_color,city,regionбыли извлечены наиболее частые значения для снижения высокой кардинальности признаков.
- Из колонки
- Аномалии и выбросы: Анализ боксплотов показал наличие экстремальных выбросов по мощности, массе и пробегу. Применен клиппинг по 1-му и 99-му перцентилям, что позволило сохранить дисперсию данных, не удаляя строки из датасета.
- Целевая переменная (
price): Распределение цены имело выраженный логнормальный характер. Для повышения устойчивости модели таргет был логарифмирован (np.log1p(y)).
С целью минимизации ввода данных пользователем - процесс моделирования строился вокруг отбора признаков и инкапсуляции сложной логики.
Был разработан кастомный конвейер на базе sklearn.Pipeline, состоящий из собственных трансформеров.
- Пайплайн инкапсулирует в себе: групповые импутеры (
EngineVolumeGroupImputer,ChassisGroupImputer), генератор фичей и жесткий фильтр (FeatureEngineer), а также обертку над инференсом (PreTrainedCatBoostWrapper).
- Выбран алгоритм CatBoostRegressor, так как финальный датасет содержит 14 категориальных переменных (марка, регион, спец. отметки и др.), с которыми CatBoost работает "из коробки" наиболее эффективно.
- На этапе прототипирования модель обучалась на полном наборе признаков. Впоследствии, с помощью
get_feature_importance(), порог важности был отсечен. - Результат: Количество требуемых признаков снижено до 26 самых значимых, что значительно упрощает удобство пользования для конечного пользователя, запрашивающего оценку авто.
В качестве Loss-функции применялась MAE (Mean Absolute Error), как наименее чувствительная к оставшимся выбросам в ценообразовании спецтехники. Оценка качества проводилась по MAPE, чтобы оценить модель с точки зрения бизнеса. Итоговые метрики, полученные при валидации составляют:
MAE: 414,043 руб.MAPE: 26.37%
Несмотря на выборку, ограниченную 2023 годом, я решил протестировать модель на реальных данных собранных с auto.ru. Для примера был взят автомобиль МАЗ 5440, его стоимость на момент 25.03.2026 составляет 1 690 000 рублей. Посмотрим какой прогноз выдает модель:
Таким образом, мы получаем, что модель ошиблась на 332 374 рубля, что даже ниже полученного MAE при тестировании на обучении. Полученный результат может говорить о хорошей обобщающей способности модели.
Для дальнейшего улучшения качества модели (снижения MAPE) и развития продукта предлагаются следующие шаги:
- Анализ описаний: Текстовое поле
descriptionможет нести ценность (наличие слов "капремонт", "тотал", "срочно", "лизинг"). Использование легковесных моделей, предобученных LLM или словарей может помочь извлечь новые признаки, которые могут оказаться полезными (например в описании часто упоминается число владельцев, а этот признак имел довольно большое число пропусков). - Кластеризация регионов: Замена простого категориального
regionна точные координатыlongitudeиlatitudeможет помочь модели лучше понимать данные, также можно будет попробовать кластеризовать регионы по цене, чтобы дать модели больше контекста. - Обработка категориальных переменных: В ходе EDA и обучения модели выяснились наиболее важные для модели признаки:
год производства,модель автомобиляимарка автомобиля. Для этих категорий можно попробовать применить Target Encoding, чтобы добавить больше контекста, а также можно попробовать создать комбинации этих (и не только) категориальных признаков.
- Оптимизация Docker: Переход на многоэтапную сборку контейнеров и разделение сред на staging/prod для уменьшения размера сервиса и ускорения развертывания.
- Мониторинг (Data Drift): Интеграция Prometheus + Grafana для мониторинга распределений входящих данных (например, обнаружение скачков цен в связи с изменением утильсбора).
- Тюнинг гиперпараметров: Проведение полноценной оптимизации гиперпараметров при помощи
Optunaдля максимизации качества CatBoost.