Ошибка random split — одна из самых частых причин провала рекомендательной системы в продакшне. Мы занимаемся обучением рекомендательных моделей, которые работают в реальных условиях, а не на переобученных метриках. Типичный случай: клиент из e-commerce использовал случайную разбивку, получил NDCG@10 = 0.65, но после внедрения модель показывала 0.4. После перехода на temporal split метрики упали, зато A/B тест дал +5% к выручке. Клиент отметил: «Случайная разбивка давала завышенные метрики — временной split оказался единственно честным». Наш стек: PyTorch, Hugging Face Transformers, Faiss для ANN поиска, ONNX Runtime для инференса. Опыт команды — более 5 лет в ML и 50+ внедрённых рекомендательных систем в e-commerce, медиа и fintech. Используем Weights & Biases для трекинга экспериментов и MLflow для управления моделями. Закажите предварительный анализ данных — мы оценим вашу задачу и предложим оптимальное решение.
Проблемы, которые решаем
Неправильная генерация отрицательных примеров
Если брать uniform sampling из всех товаров, модель не научится отличать популярное от релевантного. Мы используем popularity-based и hard negative mining (например, товары, которые модель уже ошибочно ранжирует высоко). Hard negative sampling улучшает Recall@20 в 1.3 раза по сравнению с uniform.
Холодный старт для новых пользователей и товаров
Без контентных признаков модель выдаёт нулевые предсказания. Мы добавляем side information (категорию, текст описания, изображения) через эмбеддинги.
Temporal bias
Реальные сценарии — это последовательность действий. Если перемешать данные случайно, модель «увидит» будущее во время обучения. Temporal split с отложенными по времени val/test — обязательное условие.
Как мы это делаем: развёрнутый кейс
Среди наших проектов — интернет-магазин с 5M взаимодействий и 200K товаров. Мы построили Two-Tower модель с объединением через HNSW индекс. Пайплайн включал:
- предобработку логов: дедупликация, фильтрация ботов, взвешивание взаимодействий (покупка > просмотр);
- negative sampling 4:1 с учётом популярности; временной split: 28 дней на train, 7 на val, 7 на test;
- Two-Tower: user tower — слой эмбеддингов + Dense(256), item tower — то же + L2 нормализация. Loss — Weighted BCE с логарифмом позитивных весов;
- обучение 20 эпох с early stopping по NDCG@10, используя AdamW (LR=1e-3). На GPU A100 — 45 минут;
- деплой через Triton Inference Server с ONNX моделью. Latency p99 — 12 мс.
Результат: lift по NDCG@10 на 22% относительно ALS-бейзлайна, онлайн A/B тест показал +8% к добавлениям в корзину.
Почему важен правильный negative sampling?
Негативные примеры задают границу принятия решений. Если все отрицательные — это случайные десятичные товары, модель легко их отличит. Но на практике нужно различать почти релевантные — например, тёмный диван vs чёрный диван. Hard negative sampling (из top-100 невзаимодействованных) даёт более robust обучение. У нас это реализовано через кэш с эмбеддингами и онлайн-выборку.
Что даёт временная разбивка?
Оценка модели на временном сплите — единственный способ получить честные метрики. Случайная разбивка может «заглянуть» в будущее, завышая результаты. NDCG@10 на temporal split коррелирует с онлайн-результатами A/B тестов: расхождение <15%.
Сравнение архитектур моделей
| Модель | Качество (NDCG@10) | Время обучения (5M) | Инференс latency | Особенности |
|---|---|---|---|---|
| ALS (матричная факторизация) | 0.42 | 30 мин (CPU) | <1 мс | Простой baseline, не использует side info |
| Two-Tower (Dense 256) | 0.53 | 45 мин (A100) | 3–12 мс | Гибкая, cold start через признаки |
| BERT4Rec (трансформер) | 0.58 | 4 часа (A100) | 50 мс | Только последовательности, нет холодного старта |
По сравнению с ALS, Two-Tower даёт прирост в 1.2 раза по NDCG@10 при сопоставимом времени инференса.
Сравнение стратегий negative sampling
| Стратегия | Качество (Recall@20) | Скорость обучения | Сложность реализации |
|---|---|---|---|
| Uniform | 0.48 | Высокая | Низкая |
| Popularity-based | 0.55 | Средняя | Средняя |
| Hard negative (online) | 0.61 | Низкая (из-за пересчёта эмбеддингов) | Высокая |
На практике комбинируем popularity-based и hard negatives: 80% популярных, 20% хард-негативов. Это даёт баланс качества и скорости.
Процесс работы
- Аналитика: изучаем логи взаимодействий, выявляем бутылочные горлышки (sparsity, cold start, imbalance).
- Проектирование: выбираем архитектуру, функцию потерь, стратегию negative sampling.
- Реализация: пишем pipeline на PyTorch + Hugging Face, интегрируем с вашей системой логирования.
- Тестирование: offline метрики (NDCG, recall@k) + онлайн A/B тест на 2-4 недели.
- Деплой: контейнеризация, мониторинг (дрейф данных, latency), документация.
Сроки и стоимость
Сроки: от 2 недель (baseline + доработка) до 2 месяцев (full pipeline с кастомной архитектурой). Стоимость обсуждается индивидуально после анализа данных. Наши клиенты отмечают экономию на инфраструктуре до 40% и снижение затрат на поддержку до 30% благодаря оптимизации пайплайна.
Что входит в работу
- Подготовленный датасет для повторного обучения
- Baseline (ALS или Two-Tower) с отчётом по метрикам
- Обученная финальная модель (PyTorch/ONNX)
- Документация по воспроизведению pipeline
- Код пайплайнов (препроцессинг, обучение, инференс)
- Методичка по дообучению на новых данных
- Консультация по инструментам NDCG и Temporal Split
Получите консультацию специалиста — мы обсудим ваш проект и предложим оптимальное решение.







