Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🚀 Avito Split Detector

Гибридный ML-сервис для кейса Авито на IT Purple Hack 2026: система определяет, когда объявление о ремонте стоит разделить на отдельные услуги, и при необходимости генерирует черновики новых объявлений.

Проект занял 2 место в своём треке. В репозитории лежит рабочее решение: FastAPI API, демо-интерфейс, скрипты оценки, данные, обученная модель и архив исследовательских экспериментов.

✨ Что делает проект

На вход подаётся объявление из широкой категории Ремонт квартир и домов под ключ. На выходе система возвращает:

  • detectedMcIds — какие дополнительные микрокатегории найдены в тексте.
  • shouldSplit — нужно ли разделять объявление.
  • splitMcIds — какие микрокатегории стоит вынести в отдельные объявления.
  • drafts — опциональные тексты черновиков, сгенерированные через OpenRouter.

Ключевое решение принимается локально и быстро: LLM используется только как копирайтер после того, как ML-модель уже решила, что сплит нужен.

🧠 Архитектура

  1. Rule-based детектор микрокатегорий Регулярные выражения находят упоминания самостоятельных услуг: сантехника, электрика, плитка, обои, полы, гипсокартон, демонтаж и другие работы.

  2. ML-модель для решения о сплите CatBoost-классификатор использует TF-IDF признаки текста и ручные meta-features: длину объявления, количество найденных категорий, плотность услуг, маркеры списков, цены, слова про комплексный ремонт и слова про отдельные работы.

  3. Опциональный LLM-копирайтер Если задан OPENROUTER_API_KEY и включена генерация черновиков, сервис отправляет запрос в OpenRouter и получает текст объявления в стиле автора. Без API-ключа проект всё равно полностью работает и возвращает локальный fallback-текст.

📂 Структура репозитория

.
├── solution.py                 # Pipeline: детектор, ML-инференс, опциональная генерация
├── detector.py                 # Отдельный детектор микрокатегорий
├── api/
│   ├── api.py                  # FastAPI приложение
│   └── static/index.html       # Демо-интерфейс
├── model/
│   └── split_detector.pkl      # Предобученная модель для быстрого запуска
├── tests/                      # Контрактные тесты API и pipeline
├── eval_speed_metrics.py       # Локальная оценка без LLM-вызовов
├── run_test_dataset.py         # Пакетный прогон rnc_test.csv
├── rnc_dataset_markup.json     # Обучающая/оценочная выборка
├── rnc_mic_key_phrases.csv     # Словарь микрокатегорий
├── rnc_test.csv                # Тестовая выборка
└── experiments/                # Архив R&D-экспериментов

Если файла model/split_detector.pkl нет, Pipeline обучит модель заново на rnc_dataset_markup.json и сохранит её локально.

⚡ Быстрый старт

Нужен Python 3.10+.

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Запустить тесты:

python -m pytest tests -q

Проверить скорость и метрики без LLM:

python eval_speed_metrics.py

Запустить web-демо:

uvicorn api.api:app --reload --port 8000

Открыть в браузере: http://127.0.0.1:8000.

🔐 Настройка LLM

Генерация черновиков по умолчанию выключена в API-запросах и в пакетном прогоне датасета. Чтобы включить OpenRouter-копирайтер:

cp .env.example .env
# Заполните .env, затем загрузите переменные в текущую shell-сессию:
set -a
source .env
set +a

Локальный ML-путь не требует API-ключа.

🌐 Пример API-запроса

curl -X POST http://127.0.0.1:8000/analyze \
  -H "Content-Type: application/json" \
  -d '{
    "itemId": 42,
    "mcId": 101,
    "mcTitle": "Ремонт квартир и домов под ключ",
    "description": "Делаем ремонт под ключ. Отдельно выполняем электрику, сантехнику и укладку плитки.",
    "use_ai_drafts": false
  }'

📦 Пакетный инференс

Быстрый локальный прогон без черновиков:

python run_test_dataset.py --limit 20

Полный прогон с опциональной генерацией черновиков:

python run_test_dataset.py --generate-drafts

По умолчанию результат сохраняется в predictions_test.json. Другой путь можно указать через --output path.json.

📈 Проверенный статус

На включённом датасете eval_speed_metrics.py обрабатывает 2480 объявлений примерно за 5 секунд на локальном ноутбуке и работает без LLM-вызовов. Исторический результат на хакатонном hold-out: F1 = 0.70, Precision = 0.81 для класса Split.

🧾 Для ревьюеров

  • Production path намеренно гибридный: сначала детерминированная детекция и ML-классификация, затем LLM-копирайтинг.
  • Реальные API-ключи не хранятся в репозитории. OpenRouter настраивается через переменные окружения.
  • experiments/ оставлен как R&D-архив: он показывает путь исследования, но рабочий сценарий проекта — solution.py + api/api.py.

About

Гибридный ML-сервис для сплита микрокатегорий

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages