digestors.

Понятно, практично, по делу

Вопросы и ответы

Дедупликация новостей в ИИ-дайджестах: как убрать повторы

Представьте утро понедельника. Вы открываете новостной дайджест, а там одна и та же новость про заседание Центробанка — три раза, в разных формулировках, от трёх разных агентств.

Дедупликация новостей в ИИ-дайджестах: как убрать повторы

И рядом — почти такая же история про ключевую ставку, только с другой цифрой и другим заголовком. Знакомо? Тогда давайте разберёмся, как ИИ учится наводить порядок в этом хаосе и почему «просто сравнить тексты» тут не работает вообще. Речь пойдёт про дедупликацию — процесс, который превращает свалку из сотен похожих заметок в аккуратную ленту, где каждый инфоповод встречается ровно один раз. И нет, одной волшебной кнопки «убрать повторы» в природе не существует — это всегда комбинация нескольких алгоритмов, и сегодня я расскажу, как они устроены на пальцах.

Синтаксический фильтр: MinHash LSH — первая линия обороны

Когда в систему сыпятся десятки тысяч новостей в минуту, первым делом нужно быстро отсеять очевидных клонов. И тут на сцену выходит MinHash с приставкой LSH (Locality-Sensitive Hashing) — звучит страшно, но идея простая, как дважды два.

Смотрите: алгоритм разбивает каждую статью на маленькие кусочки текста — так называемые шинглы (обычно это последовательности из 3–5 слов подряд). Дальше для каждой статьи вычисляется специальная сигнатура — компактный «отпечаток пальца», который примерно отражает, какие шинглы в тексте встречаются. По сути, это быстрая оценка вероятности того, насколько два множества шинглов пересекаются — мера Жаккара, если говорить по-научному.

Почему именно MinHash, а не просто сравнение текстов? Потому что сравнивать два длинных документа слово за словом — это дорого и медленно. А MinHash позволяет заглянуть в «отпечаток» и за доли секунды сказать: «Эти две статьи похожи процентов на 90» — или не похожи. На практике такой подход способен прожевать около 85 000 документов в секунду при точности около 88% и полноте порядка 94%. Звучит впечатляюще, правда? Но есть нюанс: MinHash отлично ловит почти точные копии и перестановки фраз, а вот когда одна и та же новость изложена совершенно другими словами — он пасует. Для этого нужен совсем другой инструмент.

MinHash LSH — это скорость. Он сортирует тонны новостей за секунды, но мыслит на уровне букв и слов, а не смыслов.

Семантический анализ: когда слова разные, а суть одна

Вот типичная ситуация: РБК пишет «ЦБ повысил ключевую ставку», а Интерфакс в тот же час выдаёт «Банк России поднял ставку до 20%». Слова разные, порядок другой — а новость одна. Как это поймать?

Тут в игру вступают векторные эмбеддинги — это когда каждую статью превращают в набор чисел (вектор), в котором закодирован её смысл. Похожие по смыслу тексты оказываются рядом в этом многомерном пространстве, даже если написаны совершенно разными словами. Чтобы понять, насколько два текста «рядом», используют косинусное сходство — математическую меру угла между векторами. Чем ближе угол к нулю, тем больше тексты совпадают по смыслу.

Золотой стандарт здесь — модели вроде BERT и их наследники. Они умеют «читать» текст с учётом контекста и выдавать по-настоящему смысловые представления. За это приходится платить скоростью: эмбеддинговый поиск тянет примерно 1 200 документов в секунду при точности около 92% и полноте 89%. В 70 раз медленнее MinHash! Зато он ловит то, что MinHash пропускает — смысловые дубли, пересказы, переводные версии одной и той же истории.

Один мой знакомый разработчик как-то обронил: «BERT умный, но жадный до ресурсов» — и это, пожалуй, самая точная формулировка. Поэтому в реальных системах никогда не используют что-то одно.

Гибридный пайплайн: почему одного метода мало

Если вы думаете, что можно просто взять BERT и забыть про MinHash — вы будете правы ровно до того момента, пока ваш сервер не упадёт под нагрузкой. А если возьмёте только MinHash — будете каждое утро получать дайджест с пятью версиями одной и той же новости. Поэтому индустрия давно пришла к гибридному подходу — многоэтапному конвейеру, где каждый этап решает свою задачу.

Возьмём для примера пайплайн NewsCatcher — они публично описывают трёхступенчатую схему. Сначала идёт семантический скрининг: считаются эмбеддинги и сравниваются по косинусному сходству с порогом около 0,95 — то есть отсеиваются только очень близкие по смыслу кандидаты. Затем подключается расстояние Левенштейна — это сколько символов нужно поменять, чтобы один текст превратился в другой. Для заголовков порог строже — около 0,97, для полных текстов — около 0,92. Так ловятся почти точные копии и мелкие перестановки. Наконец, алгоритм выбирает «родительскую» статью — ту, которая выглядит наиболее авторитетно: первая по времени, с самым полным текстом, из топового источника. Остальные считаются дублями.

Есть и другой подход — у библиотеки NVIDIA NeMo Curator. Там идея чуть другая: сначала генерируются эмбеддинги трансформером, потом статьи кластеризуются методом k-средних (K-means), внутри каждого кластера попарно считается косинусное сходство, и из каждой группы смысловых близнецов остаётся только один представитель. Это особенно популярно при подготовке данных для обучения больших языковых моделей — там дубли буквально отравляют обучение.

Для наглядности — как могут сочетаться методы в реальном пайплайне:

ЭтапМетодЧто ловитПорог (примерно)
1. Первичный скринингMinHash LSHТочные и почти точные копииЖаккар ~0,8
2. СемантикаВекторные эмбеддинги + косинусПересказы, разные формулировки0,95
3. Точная доводкаРасстояние ЛевенштейнаМелкие правки, перестановки0,92–0,97
4. Выбор эталонаРанг источника / время публикацииСамая авторитетная версия

Как видите, тут нет одного-единственного «правильного» порога — каждый сервис подбирает значения под свой стек, свои источники и свои задачи. Универсального отраслевого стандарта, как ни странно, до сих пор нет.

Тонкая настройка: где заканчивается дубль и начинается другая новость

Самая коварная часть всей этой истории — не алгоритмы, а пороги. Чуть задрал порог косинусного сходства — и две разных новости про заседания разных регуляторов склеились в одну. Чуть опустил — и дайджест снова распух от дублей, только теперь они маскируются под «похожие, но разные» сюжеты.

Вот типичная боль: новость «Apple выпустила новый iPhone» и новость «Apple выпустила новый MacBook» — это разные инфоповоды, хоть и про одну компанию. MinHash скажет «очень похоже», BERT тоже подтвердит — но если оставить обе, пользователь будет благодарен, а если склеить — пожалуется на потерю информации. Поэтому серьёзные системы смотрят не только на сходство текста, но и на метаданные: дату, источник, тематические теги, иногда — имена собственные и числа.

Отдельная история — это «родительский выбор». Допустим, нашли мы пять дублей. Какого оставить? Обычно применяют эвристики: самое раннее время публикации, самый длинный текст, источник с наивысшим рейтингом, иногда — текст с наибольшим числом просмотров или цитирований. В NewsCatcher, например, именно последний шаг пайплайна отвечает за то, какую именно версию истории увидит читатель — и это, по сути, редакторское решение, только автоматизированное.

Порог — это не цифра в вакууме. Это компромисс между страхом пропустить дубль и страхом склеить две разные новости.

Масштаб и скорость: почему гибрид неизбежен

Давайте посчитаем на салфетке. Допустим, у вас новостная лента на 10 000 статей в час — это скромный региональный агрегатор. Если гнать её целиком через BERT, на сравнение пар уйдёт несколько часов даже на хорошем железе. MinHash LSH справится за минуты. Поэтому в индустрии и сложилась двух (а чаще трёх) ступенчатая архитектура: сначала дешёвый и быстрый фильтр отсекает 90% заведомо разных текстов, а оставшиеся 10% тщательно проверяет дорогая и умная модель.

В Сбере, например, ещё в 2023 году описывали похожий подход — MinHash для первичной фильтрации огромного потока, а затем ML-модели для финальной очистки. Логика простая: зачем платить нейросетевыми ресурсами за каждую пару, если 90% пар вообще ни при каких обстоятельствах не окажутся дублями? Пусть сначала MinHash скажет «нет», а умный BERT подключится только к подозрительным случаям.

На стыке 2025 и 2026 годов библиотеки вроде NeMo Curator становятся де-факто стандартом для подготовки датасетов — там подход тот же: эмбеддинги → кластеризация → попарное сравнение внутри кластеров → удаление дублей с сохранением лучшего представителя. Это особенно важно для обучения LLM, где дубли в обучающих данных буквально ухудшают качество модели.

Что со всем этим делать вам

Если вы собираете свой новостной дайджест или просто хотите понять, почему одни сервисы выдают чистую ленту, а другие — свалку, запомните главное: дедупликация — это не один алгоритм, а конвейер. Сначала MinHash LSH отсекает очевидное, потом эмбеддинги ловят смысл, потом точные метрики доводят результат, и в конце всегда стоит человекоподобный выбор «родителя» — какую версию истории показать читателю.

И ещё один лайфхак напоследок: если вы читаете дайджест, где три новости подряд выглядят как родные сёстры — не спешите ругать редакцию. Возможно, алгоритм просто решил, что это три разных инфоповода. Или, что чаще, ему не хватило умного семантического слоя, чтобы их склеить. Хорошая дедупликация — это всегда баланс между скоростью, точностью и здравым смыслом, и нащупывается он только в бою — на ваших собственных данных и ваших собственных читателях.

Частые вопросы

Что такое дедупликация новостей?
Дедупликация — это процесс, который объединяет похожие новости и оставляет в ленте один представитель инфоповода вместо нескольких повторов.
Как MinHash LSH находит дубли новостей?
Алгоритм разбивает статьи на шинглы, обычно последовательности из 3–5 слов, и сравнивает компактные сигнатуры текстов. Он хорошо ловит почти точные копии и перестановки фраз, но может пропустить пересказы с другой формулировкой.
Зачем использовать эмбеддинги при дедупликации новостей?
Эмбеддинги превращают статьи в векторы, отражающие их смысл, поэтому помогают находить тексты с разными словами, но одинаковым содержанием. Их сравнивают, в частности, с помощью косинусного сходства.
Почему для дедупликации используют несколько алгоритмов?
MinHash работает быстро, а семантический поиск лучше распознаёт смысловые дубли, но требует больше ресурсов. Поэтому системы обычно сначала отсекают очевидные совпадения, а затем тщательно проверяют подозрительные случаи.
Как выбирают, какую новость оставить из нескольких дублей?
В качестве «родительской» статьи обычно выбирают версию, которая раньше опубликована, содержит более полный текст или поступила из источника с более высоким рейтингом. В некоторых системах также учитываются просмотры или цитирования.