Одна строка — много объектов: как агрегировать эмбеддинги для ML-моделей

от автора

Коротко

Иногда в задаче машинного обучения одна строка датасета соответствует не одному объекту, а целому набору связанных объектов.

Например:

день по акции -> много новостейпользователь -> много комментариевтовар -> много фотографийклиент -> много обращений в поддержкусессия -> много событий

Каждый такой объект можно представить эмбеддингом. Новость — текстовым эмбеддингом, картинку — визуальным эмбеддингом, событие — вектором признаков или embedding‑представлением.

Но возникает практическая проблема: модель обычно ждет фиксированное число признаков в одной строке, а связанных объектов может быть разное количество. Сегодня у акции 3 новости, завтра 100, послезавтра 0. У одного пользователя 5 комментариев, у другого — 500.

В этой статье я хочу разобрать несколько способов бороться с такой задачей: от простых счетчиков и среднего эмбеддинга до MIL, LLM‑разметки и гибридной схемы, где MIL работает как фильтр перед LLM.

Это не статья с бенчмарком и готовыми цифрами качества, а практический обзор подходов, которые можно попробовать в задаче «много объектов на одну строку».

Откуда у меня возникла такая задача

С этой проблемой я столкнулся не как с абстрактной задачей, а в довольно практическом контексте.

Я руководил AI‑командами в студенческих проектах НИУ ВШЭ, и в двух командах возникла похожая идея: ребята прогнозировали стоимость акций и хотели учитывать новости.

На первый взгляд все звучит логично. Цена акции зависит не только от исторических значений, объема торгов и технических индикаторов. На нее может влиять информационный фон: отчетность компании, новости о дивидендах, санкции, судебные иски, сделки M&A, смена руководства, изменения в отрасли.

Но дальше появляется вопрос: как именно добавить новости в модель?

Обычно временной ряд или табличная модель устроены так, что на один объект приходится одна строка фиксированной длины:

дата, тикер, цена_вчера, объем_вчера, лаги, день_недели, ...

А новости устроены иначе:

2025-01-01 -> 0 новостей2025-01-02 -> 7 новостей2025-01-03 -> 126 новостей

Если взять эмбеддинг каждой новости, мы получим не один вектор, а набор векторов разной длины. И это уже не ложится напрямую в обычную табличную модель.

То есть проблема не в том, чтобы получить эмбеддинг новости. Проблема в том, как из переменного числа эмбеддингов получить фиксированное представление для одной строки датасета.

Почему это не только про новости и акции

Новости для прогноза акций — просто понятный пример. На самом деле такая постановка встречается гораздо шире.

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

пользователь -> 100 комментариев -> бан / не бан

Или задача с карточкой товара. У одного товара может быть несколько фотографий. Каждую фотографию можно превратить в image embedding, но итоговый таргет может быть один: категория товара, вероятность покупки, качество карточки, вероятность жалобы.

товар -> 10 фотографий -> вероятность покупки

Или клиентская аналитика:

клиент -> много обращений в поддержку -> вероятность оттока

Или поведенческие данные:

сессия пользователя -> много событий -> вероятность покупки

Общая схема везде похожая:

одна строка датасета    ↓к ней относится N связанных объектов    ↓N разное для каждой строки    ↓каждый объект можно представить вектором    ↓нужно получить фиксированный набор признаков

Именно эту задачу я дальше и буду иметь в виду.

Лестница методов

Методов решения много. Ниже — не полный список всех возможных способов, а несколько практических подходов, которые можно рассматривать как лестницу сложности.

1. Простые счетчики и базовые признаки

Перед тем как использовать эмбеддинги, LLM или MIL, часто полезно начать с очень простых признаков.

Для новостей это могут быть:

количество новостей за деньколичество новостей за последние 3 / 7 / 14 днейколичество источниковсредняя длина новостичисло новостей с упоминанием компаниичисло новостей с ключевыми словами

Для комментариев:

количество комментариев пользователяколичество комментариев за последние N днейсредняя длина комментариячисло жалобдоля удаленных комментариевчисло комментариев с токсичными словами

Для изображений:

количество изображенийсреднее качество изображениядоля пустых или слишком темных изображенийналичие главного объекта на фото

Такие признаки выглядят слишком простыми, но это нормальный бейзлайн. Иногда сам факт всплеска активности уже дает полезный сигнал.

Например, если по акции внезапно вышло в 10 раз больше новостей, чем обычно, это само по себе может быть важным признаком. Даже без понимания текста.

2. Эмбеддинг каждого объекта

Следующий шаг — представить каждый связанный объект вектором.

новость -> text embeddingкомментарий -> text embeddingкартинка -> image embeddingсобытие -> event embedding

После этого для одной строки датасета получится набор эмбеддингов:

строка_i -> [embedding_1, embedding_2, ..., embedding_N]

Но проблема все еще остается. У разных строк разное количество объектов. У одной строки может быть 2 эмбеддинга, у другой — 200.

Поэтому нужен способ агрегации.

3. Простая агрегация эмбеддингов

Самый очевидный вариант — посчитать простые агрегаты по векторам.

Например:

mean poolingmax poolingmin poolingsum poolingmedian pooling

Самый простой вариант:

embedding_строки = mean(embedding_1, ..., embedding_N)

Так мы превращаем набор векторов в один вектор фиксированной длины. После этого его можно добавить к обычным табличным признакам и отправить в CatBoost, LightGBM, линейную модель или нейросеть.

Плюсы подхода:

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

Минусы тоже понятны. Если среди 100 новостей 99 нейтральные, а одна реально важная, то средний эмбеддинг может «размазать» этот сигнал. Важный объект потеряется на фоне большого количества шума.

4. Агрегация по временным окнам

Если задача связана со временем, полезно считать признаки не только за один момент, но и за несколько окон.

Например, для новостей:

средний эмбеддинг новостей за деньсредний эмбеддинг новостей за 3 днясредний эмбеддинг новостей за 7 днейколичество негативных новостей за 14 дней

Для комментариев пользователя:

эмбеддинг комментариев за последний деньэмбеддинг комментариев за неделюэмбеддинг комментариев за месяц

Это важно, потому что эффект может быть не мгновенным. Новость может влиять не только в день публикации, а комментарии пользователя могут показывать не один отдельный всплеск, а устойчивое поведение.

Но во временных задачах есть отдельный риск — утечка будущего. Если прогноз строится утром, нельзя использовать новости, которые вышли вечером того же дня. Нужно учитывать время публикации, время прогноза и доступность данных на момент принятия решения.

5. Взвешенная агрегация

Следующий шаг — не считать все объекты одинаково важными.

В обычном среднем каждый объект имеет одинаковый вес. Но в реальности новости, комментарии или изображения могут быть разной важности.

Вес можно задавать по разным правилам:

свежесть объектаисточникдлина текстарелевантность к компании или теметональностьважность, оцененная отдельной модельюуверенность моделикачество изображения

Тогда вместо обычного среднего можно использовать взвешенное среднее:

embedding_строки = weighted_mean(embeddings, weights)
  • Для новостей можно давать больший вес свежим новостям, новостям из более важных источников или новостям, где компания упоминается напрямую.

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

  • Для изображений можно давать больший вес тем фотографиям, где лучше виден основной объект.

Такой подход все еще достаточно простой, но уже позволяет учитывать, что не все элементы набора равны.

6. LLM-разметка объектов

LLM можно использовать не как финальную модель, которая сразу предсказывает таргет, а как инструмент для извлечения признаков.

Например, для новости можно попросить модель вернуть структурированную разметку:

тональность: positive / neutral / negativeтип события: отчетность / дивиденды / санкции / суд / M&A / другоеважность: 1-5относится ли новость напрямую к компаниипотенциальный горизонт влиянияуверенность оценки

Для комментария:

токсичностьоскорблениеугрозаспампризыв к нарушению правилтяжесть нарушения

После этого можно агрегировать уже не только эмбеддинги, но и полученные структурные признаки:

avg_news_importancemax_news_importancecount_negative_newsshare_direct_company_newscount_high_risk_commentsmax_toxicity

Плюс такого подхода в том, что LLM может выделять более интерпретируемые признаки. Мы получаем не просто вектор, а понятные характеристики объектов.

Но есть и ограничения:

стоимостьзадержканестабильность ответовриск галлюцинацийнеобходимость фиксировать промпт и модельнеобходимость проверять качество разметки

Поэтому я бы не воспринимал LLM-разметку как магическое решение. Это просто еще один способ feature engineering, который может помочь, если его аккуратно контролировать.

7. MIL: когда метка есть только у всего набора

Более продвинутый подход — Multiple Instance Learning, или MIL.

MIL подходит для ситуаций, где есть набор объектов, но метка известна только для всего набора целиком.

Например:

пользователь = набор комментариевметка = пользователь забанен / не забанен

Мы не знаем, какой конкретно комментарий стал причиной бана. Но знаем, что пользователь в целом был забанен.

Или:

день = набор новостейметка = рост / падение / доходность

Мы не знаем, какая именно новость повлияла на движение цены. Но знаем общий таргет на уровне дня.

В MIL одна строка датасета рассматривается как «мешок» объектов:

bag = набор объектовinstances = отдельные объекты внутри набораlabel = метка всего набора

Один из вариантов реализации MIL — attention pooling.

Идея такая: модель получает эмбеддинги всех объектов внутри набора, оценивает их важность и строит итоговое представление как взвешенную сумму.

embedding_1 -> weight_1embedding_2 -> weight_2embedding_3 -> weight_3...итоговое_представление = weighted_sum(embeddings, weights)

Плюс такого подхода в том, что модель может сама научиться выделять важные объекты внутри большого набора. Например, из 100 новостей выбрать 2–3, которые сильнее связаны с таргетом.

Минус — это уже более сложная модель. Ей нужно больше данных, ее сложнее валидировать, и она сильнее рискует переобучиться.

Важно: attention‑веса не всегда являются строгим объяснением. Лучше говорить аккуратно: модель посчитала эти объекты полезными для прогноза, а не доказала, что именно они стали причиной события.

8. MIL как фильтр перед LLM

Есть еще интересный гибридный вариант: использовать MIL не только как способ агрегации, но и как фильтр перед LLM.

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

Идея гибридного подхода:

много объектов    ↓эмбеддинги объектов    ↓MIL / attention модель    ↓top-k наиболее важных объектов    ↓LLM-разметка только этих объектов    ↓агрегированные признаки    ↓финальная модель

То есть MIL работает как обучаемый фильтр. Она выбирает top-k объектов, которые выглядят наиболее полезными для целевой задачи, а уже потом LLM подробно размечает только эти объекты.

Например, вместо того чтобы отправлять в LLM все 100 новостей за день, можно выбрать 5-10 наиболее важных новостей и разметить только их.

Плюсы:

меньше стоимостьменьше токеновменьше шумаLLM работает только с выбранными объектамипоявляется более понятный pipeline

Но здесь тоже есть риски.

Первый риск — фильтр может отбросить важный объект. Если MIL‑модель ошиблась на этапе отбора, LLM уже не увидит нужную новость или комментарий.

Второй риск — утечка данных при обучении фильтра. Если обучать MIL на всем датасете, а потом использовать его для отбора объектов в тестовом периоде, можно незаметно протащить информацию из будущего. Временную валидацию нужно делать честно.

Третий риск — переоценка интерпретируемости. Если объект попал в top‑k, это не значит, что он точно является причиной события. Это значит только, что модель считает его полезным для прогноза.

9. Объединение с основной моделью

На практике признаки из связанных объектов редко используются отдельно. Обычно они объединяются с обычными табличными признаками.

Например:

табличные признаки + агрегированные эмбеддинги -> CatBoost / LightGBM / нейросеть

Или можно обучить две модели:

модель на табличных признакахмодель на эмбеддингах / множестве объектов

А затем объединить их предсказания:

final_prediction = w1 * prediction_tabular + w2 * prediction_embeddings

Такой подход удобен как бейзлайн, потому что можно отдельно проверить, дает ли часть с эмбеддингами реальный прирост относительно обычных признаков.

Иногда прирост будет небольшим. Например, в задачах временных рядов лаги таргета и исторические признаки могут быть очень сильными, а новости добавляют только слабый и нестабильный сигнал. Поэтому важно честно сравнивать с простым бейзлайном, а не считать, что эмбеддинги или LLM автоматически улучшат качество.

Что важно не забыть

Есть несколько практических моментов, которые я бы проверял почти в любой такой задаче.

Честная валидация

Если задача временная, нужен временной split. Нельзя случайно перемешивать строки, если в реальности модель будет работать на будущих периодах.

Особенно опасно, если признаки из новостей или событий строятся с учетом данных, которые на момент прогноза еще не были доступны.

Сравнение с простыми бейзлайнами

Перед сложными методами стоит проверить:

модель без связанных объектовмодель с простыми счетчикамимодель со средним эмбеддингоммодель с более сложной агрегацией

Иначе можно построить сложный pipeline, который почти не улучшает качество относительно простого среднего.

Размер данных

MIL, attention pooling и другие обучаемые способы агрегации требуют больше данных. Если данных мало, простые методы могут оказаться стабильнее.

Интерпретируемость

Счетчики и LLM-разметка часто понятнее бизнесу, чем сырые эмбеддинги. Но LLM-разметку тоже нужно проверять, потому что модель может ошибаться или отвечать нестабильно.

Стоимость

Если объектов много, LLM может стать дорогой частью pipeline. Поэтому гибридная схема с предварительным отбором top-k объектов может быть полезной.

Итог

Главная мысль статьи простая: проблема не в том, чтобы получить эмбеддинг новости, комментария, картинки или события. Проблема в том, что к одной строке датасета может относиться переменное число таких объектов, а модель обычно ждет фиксированное число признаков.

Эту задачу можно решать разными способами:

простые счетчикиэмбеддинги объектовmean / max / sum poolingвзвешенная агрегацияагрегация по временным окнамLLM-разметкаMIL / attention poolingMIL как фильтр перед LLMобъединение с табличной моделью

Это не полный список всех возможных методов, а набор практических направлений, с которых можно начать.

В одних задачах хватит простых счетчиков и среднего эмбеддинга. В других важный сигнал будет находиться в одном редком объекте, и тогда простая агрегация может его потерять. Где-то поможет LLM-разметка, а где-то она добавит стоимость и шум. Где-то MIL даст прирост, а где-то переобучится.

Поэтому я бы воспринимал эти методы не как готовую инструкцию, а как набор вариантов для экспериментов.

Если упростить до одной фразы:

когда к одной строке относится много объектов, задача не в том, чтобы развернуть их в сотни колонок, а в том, чтобы аккуратно сжать это множество в фиксированное представление и не потерять важный сигнал.

ссылка на оригинал статьи https://habr.com/ru/articles/1043764/