Группировка, схлопывание, разнообразие

Рейтинг: 62.1% · 15 голосов
Полный курс об устройстве веб-поиска: обход, индексирование, факторы ранжирования, нейропоиск, поведенческие сигналы, антиспам, SEO. 23 модуля по главам с разбором и обсуждением.
Ответить
Аватара пользователя
kirill_ir
Сообщения: 25
Зарегистрирован: 11 май 2026, 05:31

Группировка, схлопывание, разнообразие

Сообщение kirill_ir »

Оглавление курса (23)
  1. Введение
  2. Теоретический фундамент (Information Retrieval)
  3. Краулинг (обход)
  4. Идентичность документа: каноникализация и дубли
  5. Индексирование и хранение
  6. Обработка и понимание запроса
  7. Текстовая релевантность
  8. Анализ ссылочного графа
  9. Таксономия факторов ранжирования
  10. Машинное обучение ранжированию (Learning-to-Rank)
  11. Нейросетевой поиск (Neural IR)
  12. Поведенческие сигналы и клик-модели
  13. Каскад ранжирования и обслуживание (serving)
  14. Инфраструктура и распределённое обслуживание
  15. Метапоиск и федерация источников
  16. Группировка, схлопывание, разнообразие (вы здесь)
  17. Постранжирование, антиспам и качество выдачи
  18. Свежесть и реалтайм
  19. Локализация, гео и персонализация
  20. Измерение качества и эксперименты
  21. SEO: оптимизация под факторы
  22. Этика, приватность и борьба со злоупотреблениями
  23. Capstone: сквозной проект
Часть V · ~9 ч · Сложность: (средний) · Пререквизиты: Модуль 14
Обзор модуля

К этому моменту каскад ранжирования (Модуль 12) уже выдал список документов, отсортированный по предсказанной релевантности. Казалось бы, осталось только показать топ-k пользователю. На практике между «отсортированным списком» и «финальной выдачей (SERP, search engine results page)» лежит целый слой постранжирования (post-ranking, re-ranking layer) — правил и алгоритмов, которые переупорядочивают, прореживают, схлопывают и перемешивают результаты. Этот модуль — о той части постобработки, которая отвечает за состав и структуру выдачи, а не за оценку отдельного документа.

В сквозном конвейере «обход → индекс → факторы → ранжирование → выдача → постобработка → измерение» мы находимся строго после ранжирования и до показа. Вход слоя — упорядоченный список кандидатов с их признаками (хост, домен, сервис-источник, кластер-дубликат, предсказанный интент); выход — то, что увидит человек: ограниченное число результатов с одного сайта, без видимых дублей, с покрытием разных смыслов запроса и с корректно вставленными спецблоками (картинки, видео, карта, быстрые ответы).

Зачем это нужно? Чистая сортировка по релевантности близоруко оптимальна: она ставит наверх k документов, каждый из которых по отдельности лучший, но вместе они могут быть тремя страницами одного сайта об одном и том же. Пользователю это бесполезно — ему нужна полезность всей страницы целиком, а не сумма поточечных скоров. Группировка, дедупликация и разнообразие — это переход от оптимизации «лучший документ» к оптимизации «лучшая выдача».
Внимание. Это средний по сложности модуль ((средний)), но глава 15.3 (разнообразие) — продвинутая ((продвинутый)): там появляется субмодулярная оптимизация и жадные алгоритмы с гарантиями. Если MMR и интентное покрытие новы — задержитесь на интуиции, прежде чем читать формулы.
Как читать по трекам
  • Студент — обязательны 15.1 (группировка/схлопывание как ограничение) и 15.3 (формальная постановка разнообразия, MMR, субмодулярность, жадная аппроксимация 1 − 1/e). Глава 15.2 — на уровне идей (три уровня дедупликации). Глава 15.4 — обзорно.
  • Инженер — всё обязательно. Особое внимание: инженерные заметки об overfetch (добор кандидатов под схлопывание), о порядке стадий пайплайна постранжирования, о ключах дедупликации и о слотовой модели вставки спецблоков.
  • SEO — главы 15.1 (лимит ~2 результата на сайт — ключевая SEO-врезка модуля) и 15.4 (как спецблоки отъедают позиции). Дедупликация (15.2) важна как причина, по которой «зеркала» и параметрические URL не дают лишних позиций. SEO-врезки разбросаны по всему модулю.
  • Смешанный — последовательно весь модуль; математику MMR и субмодулярности можно бегло просмотреть при первом проходе и вернуться позже.
Карта модуля
  • 15.1. Группировка по хосту/домену; host collapsing — ограничение числа результатов с одного сайта, схлопывание серий, добор кандидатов. (средний)
  • 15.2. Дедупликация на выдаче — устранение повторов по URL, хосту и сервису-источнику; три уровня и их ключи. (средний)
  • 15.3. Разнообразие выдачи — интентное покрытие, MMR-подобные подходы, субмодулярность, жадная аппроксимация. (продвинутый)
  • 15.4. Управление позициями и вставка спецблоков — слотовая модель, blending/федерация, вытеснение органики. (средний)
Глава 15.1. Группировка по хосту/домену; ограничение числа результатов с одного сайта (host collapsing) (средний)

Цели обучения

После главы студент сможет:
  • Объяснить, почему сортировка по поточечной релевантности порождает «засилье одного сайта» и почему это вредит полезности выдачи.
  • Различать уровни группировки: по хосту, по зарегистрированному домену (eTLD+1), по логическому сайту.
  • Реализовать алгоритм схлопывания (host collapsing) с лимитом и «раскрытием» серии в один сгруппированный блок.
  • Обосновать необходимость добора кандидатов (overfetch) при схлопывании и оценить нужный запас.
  • Связать лимит на сайт с метриками качества выдачи и со стратегией SEO.
Конспект

Проблема: жадная сортировка близорука

Каскад ранжирования оценивает каждый документ поточечно (pointwise) или попарно: «насколько этот URL релевантен запросу». Он не знает, что три верхних URL принадлежат одному сайту и рассказывают об одном и том же. Если просто взять топ-k, на коммерческом или информационном запросе легко получить выдачу, где первые 5 позиций — это разделы каталога одного крупного агрегатора.
Интуиция. Представьте полку в магазине: даже если у одного бренда товары объективно лучшие, продавец не заставит всю полку одним брендом — покупателю нужен выбор. Поисковая выдача — та же полка. Польза для пользователя от четвёртой страницы одного сайта почти нулевая: если первые три его не убедили, четвёртая не поможет, а вот результат с другого источника может закрыть его потребность.
Это проявление более общего принципа: полезность выдачи субаддитивна по похожим результатам. Второй почти-такой-же документ добавляет куда меньше, чем первый. Формально мы выйдем на это в главе 15.3 (субмодулярность); здесь — частный, но важнейший случай: похожесть «по принадлежности одному сайту».

Что такое «один сайт»: уровни группировки

«Ограничить число результатов с одного сайта» требует определить, что считать «одним сайтом». Есть несколько уровней, и их легко перепутать:

Код: Выделить всё

Уровень                            |  Ключ группировки   |  Пример: что схлопнётся вместе
-----------------------------------+---------------------+-----------------------------------------------------------
Полное имя хоста (FQDN)            |  shop.example.com   |  только страницы этого поддомена
Зарегистрированный домен (eTLD+1)  |  example.com        |  shop.example.com, blog.example.com, www.example.com
Логический сайт (site)             |  владелец/площадка  |  домен + его поддомены + связанные домены одного владельца
Здесь eTLD — эффективный домен верхнего уровня (effective top-level domain), он же «публичный суффикс»: не только .com, но и составные вроде .co.uk, .com.br, а также суффиксы платформ-хостингов вида user.blogplatform.io, где blogplatform.io — публичный суффикс. eTLD+1 — это публичный суффикс плюс одна метка слева: зарегистрированный домен, который реально кто-то купил.
Инженерная заметка. Для корректного выделения eTLD+1 нужна актуальная таблица публичных суффиксов (public suffix list). Без неё user1.blogplatform.io и user2.blogplatform.io ошибочно склеятся в один «сайт», хотя это разные независимые авторы на общем хостинге. Это типичная ошибка: наивное «взять два последних поля домена» ломается на co.uk и на платформенных суффиксах.
Заблуждение. «Группировка по хосту и по домену — одно и то же.» Нет. На уровне хоста m.example.com и www.example.com — разные сайты, и оба могут попасть в топ. На уровне eTLD+1 они схлопываются. Большинство систем группируют по зарегистрированному домену (eTLD+1), а внутри него ещё и по хосту, чтобы не пропустить мобильное зеркало как «другой источник».
Алгоритм схлопывания (host collapsing)

Базовый алгоритм с лимитом L результатов на сайт:

Код: Выделить всё

collapse(ranked_list, key_fn, L):
    seen = {}                      # ключ сайта -> сколько уже показано
    out = []
    overflow = {}                  # ключ сайта -> хвост (скрытые результаты)
    for doc in ranked_list:        # порядок = по убыванию релевантности
        site = key_fn(doc)         # eTLD+1 (+ опц. хост)
        c = seen.get(site, 0)
        if c < L:
            out.append(doc)
            seen[site] = c + 1
            if c == 0:
                doc.is_group_head = True   # первый — «голова» группы
        else:
            overflow.setdefault(site, []).append(doc)   # в «ещё с этого сайта»
    return out, overflow
Ключевое решение — что делать с «лишними» результатами сайта (overflow):
  1. Жёсткое отсечение (hard cap). Просто выбросить всё сверх лимита. Просто, но теряем потенциально полезные страницы.
  2. Схлопывание в блок (collapsing / indented results). Показать первый результат как «голову» группы, а остальные L-1 (или ссылку «ещё N с этого сайта →») — как вложенный блок под ним. Пользователь видит один логический элемент выдачи, но может развернуть серию.
  3. Перенос вниз (demotion / spreading). Не выбрасывать, а сдвинуть лишние результаты ниже по списку, разрешив им появиться, только когда более разнообразные кандидаты закончились.
Пример. Запрос «рецепт борща», L = 2 по eTLD+1. Ранжировщик выдал: kuhnya.ru/borsch-1 (скор 9.8), kuhnya.ru/borsch-2 (9.7), kuhnya.ru/borsch-3 (9.6), eda-doma.ru/borsch (9.5), povar.ru/borsch (9.4). При лимите 2 в финал попадут два с kuhnya.ru, затем по одному с eda-doma.ru и povar.ru. Третий kuhnya.ru/borsch-3 уходит в overflow — либо под «голову» как «ещё рецепты с kuhnya.ru», либо вниз, либо отбрасывается.
Зачем нужен добор кандидатов (overfetch)

Тонкий, но критичный инженерный момент. Схлопывание удаляет документы из топа. Если каскад вернул ровно k кандидатов, а половина из них — с одного сайта, после схлопывания финальная выдача окажется короче k — позиции просто опустеют.

Поэтому слой постранжирования должен запрашивать у ранжировщика больше документов, чем нужно показать: не топ-k, а топ-k·m, где m — коэффициент добора. Размер m зависит от ожидаемой «концентрации» по сайтам: чем чаще один сайт занимает много мест, тем больший запас нужен.
Инженерная заметка. Добор не бесплатен: расширение глубины с k до k·m увеличивает нагрузку на дорогие верхние стадии каскада (L2/L3 в Модуле 12). На практике m подбирают эмпирически (часто m ≈ 2…4 для лимита L=2…3) и иногда делают адаптивным: добирать ещё, только если после первого прохода схлопывания топ не заполнился. Это компромисс между латентностью и риском «дыр» в выдаче.
Внимание. Порядок стадий важен: схлопывание по сайту должно идти до дедупликации по сервису (15.2) и до вставки спецблоков (15.4), иначе спецблок может занять слот, который потом отнимут у схлопывания, и арифметика позиций «поедет». Конкретный порядок — инженерное решение, но он должен быть зафиксирован и единообразен.
Связь с метриками качества

Лимит на сайт нельзя выбрать «из головы» — его калибруют по метрикам полезности всей выдачи (Модуль 19): насколько часто пользователь находит ответ, не уходя на вторую страницу; растёт ли удовлетворённость при L=2 против L=3. Слишком жёсткий лимит вредит, когда сайт объективно — лучший источник по запросу (например, официальный сайт организации по навигационному запросу к ней). Поэтому лимит часто зависит от класса запроса: для навигационных запросов он мягче (логично показать несколько страниц искомого сайта), для широких информационных — жёстче.

Частые заблуждения
Заблуждение. «Схлопывание — это то же, что дедупликация.» Нет. Дедупликация (15.2) убирает результаты, которые по сути одинаковы (один контент, зеркала, дубль-URL). Схлопывание ограничивает количество разных, но однохостовых результатов. Три разные статьи одного сайта — не дубли, но схлопыванию подлежат.
Заблуждение. «Если мой сайт лучший, я займу весь топ.» Лимит на сайт не даст. Даже идеальные по релевантности страницы сверх лимита уйдут в свёрнутый блок или вниз. Это и есть SEO-следствие ниже.
Лаба / практика

Дан ранжированный список из 12 кандидатов с полями (url, score, host). Реализуйте collapse(...) с лимитом L=2 по eTLD+1 (используйте мини-таблицу публичных суффиксов: .com, .ru, .co.uk, blogplatform.io). Затем добавьте overfetch: исходно ранжировщик «отдаёт» только топ-6; покажите, что после схлопывания финальный топ-5 не заполняется, и реализуйте адаптивный добор остальных кандидатов до заполнения. Сравните три политики overflow (отсечение / блок / перенос вниз) на одном входе.

Ожидаемый результат: финальный топ-5 без более чем 2 URL с одного домена; корректное выделение eTLD+1 для user.blogplatform.io; продемонстрированная «дыра» без добора и её закрытие с добором. Время ~50 мин. Критерий «сделано»: для эталонного входа выдача совпала, объяснено, почему наивное «два поля домена» ломается на co.uk.

Контрольные вопросы
  1. Чем группировка по хосту отличается от группировки по eTLD+1? Приведите пару URL, которые склеятся в одном случае и нет в другом.
  2. Почему для выделения «зарегистрированного домена» недостаточно взять две последние метки имени хоста?
  3. Что такое overfetch и почему без него после схлопывания в топе появляются пустые позиции?
  4. Опишите три политики обращения с «лишними» результатами сайта и их компромиссы.
  5. Почему лимит на сайт иногда делают зависящим от класса запроса? Приведите пример запроса, где мягкий лимит уместен.
  6. Где в пайплайне постранжирования должно стоять схлопывание относительно дедупликации и вставки спецблоков, и почему порядок важен?
  7. Как связан лимит на сайт с понятием субаддитивности полезности выдачи (предвосхищая 15.3)?
Глава 15.2. Дедупликация на выдаче (по URL, хосту, сервису) (средний)

Цели обучения

После главы студент сможет:
  • Разграничить дедупликацию на выдаче и дедупликацию на индексе/каноникализации (Модуль 3) — что и где происходит.
  • Описать три уровня дедупликации выдачи: точный URL, контентный дубль, сервис-источник.
  • Выбрать корректный ключ дедупликации для каждого уровня и объяснить риск ложного склеивания.
  • Реализовать дедупликацию near-duplicate на выдаче поверх кластеров/сигнатур, пришедших из индекса.
Конспект

Где проходит граница: индекс vs выдача

Большая часть устранения дублей происходит раньше — на стадии каноникализации (Модуль 3): зеркала склеиваются в каноническую форму URL, near-duplicate-документы кластеризуются по сигнатурам (shingling, SimHash/MinHash), в индекс попадает представитель кластера. Тогда зачем дедуплицировать ещё и на выдаче?

Потому что каноникализация не идеальна и работает на уровне всего корпуса, а не конкретного запроса:
  1. Остаточные дубли. Сигнатурная кластеризация имеет ошибки; два URL, не склеенные в индексе, могут оказаться рядом в топе по конкретному запросу — и только здесь их сходство становится видимым и вредным.
  2. Запросо-зависимая близость. Два документа могут быть «не дублями» в целом, но по данному запросу их сниппеты и релевантная часть совпадают (например, одна и та же новость в перепечатке).
  3. Федерация источников. В выдачу подмешиваются результаты из разных вертикалей/сервисов (15.4), и одна и та же сущность (организация, товар) может прийти из нескольких источников.
Интуиция. Каноникализация — это «уборка склада» (один раз, для всех). Дедупликация на выдаче — «последняя проверка перед подачей»: даже на чистом складе на одну тарелку могло попасть две одинаковые ложки именно для этого заказа.
Три уровня дедупликации выдачи

Код: Выделить всё

Уровень                               |  Что устраняем                                                 |  Ключ                                     |  Риск
--------------------------------------+----------------------------------------------------------------+-------------------------------------------+-----------------------------------------
1. Точный URL                         |  один и тот же адрес дважды (после федерации/слияния списков)  |  нормализованный URL                      |  почти нулевой
2. Контентный дубль (near-duplicate)  |  разные URL, одинаковый по сути контент                        |  сигнатура контента / id кластера дублей  |  ложное склеивание разных страниц
3. Сервис / сущность                  |  одна сущность от разных источников                            |  id сущности / ключ сервиса               |  склеивание похожих, но разных сущностей
Уровень 1 — точный URL. Самый простой и обязательный. После слияния нескольких списков-кандидатов (органика + вертикали) один и тот же URL может прийти дважды. Дедуп по нормализованному URL (та же нормализация, что в каноникализации: схема, регистр хоста, сортировка параметров, отсечение трекинговых меток).

Уровень 2 — контентный дубль. Опирается на сигнатуры/кластеры из индекса. Каждый кандидат несёт cluster_id (идентификатор кластера near-duplicate) или сигнатуру (SimHash). На выдаче оставляем одного представителя на кластер — того, что выше по релевантности.

Код: Выделить всё

dedup_near(list):
    seen_clusters = set()
    out = []
    for doc in list:                       # по убыванию релевантности
        cid = doc.cluster_id or simhash_bucket(doc.signature)
        if cid in seen_clusters:
            continue                        # дубль уже представлен выше
        seen_clusters.add(cid)
        out.append(doc)
    return out
Инженерная заметка. Если cluster_id из индекса доступен — используйте его (он точнее, считался на полном корпусе). Сравнение SimHash «на лету» (по расстоянию Хэмминга в пределах порога) — запасной вариант для остаточных случаев и для свежедобавленных документов, которые ещё не прошли полную кластеризацию.
Уровень 3 — сервис/сущность. Самый тонкий. В федеративной выдаче (15.4) одна сущность — например, организация — может прийти как органический результат (её сайт), как карточка из справочника, как объект на карте. Это не дубли по URL и не дубли по контенту, но показывать три раза одну организацию избыточно. Дедупликация по entity_id (если сущности разрешены/слинкованы) либо по ключу сервиса (не более одного результата от данного сервиса на сущность).
Заблуждение. «Дедупликация на выдаче не нужна, ведь есть каноникализация.» Каноникализация устраняет дубли в индексе на уровне всего корпуса. Запросо-зависимые совпадения, ошибки кластеризации и федеративные повторы видны только на выдаче — поэтому финальная проверка обязательна.
Внимание. Главный риск дедупликации — ложное склеивание (false merge): агрессивный ключ убьёт разные полезные результаты. Две карточки товара с почти одинаковым названием, но разными характеристиками — не дубли. Порог сходства и выбор ключа калибруют так, чтобы цена ложного склеивания (потеря полезного) не превысила выигрыш от удаления повтора.
Взаимодействие со схлопыванием

Дедупликация и схлопывание (15.1) решают разные задачи, но порядок их применения влияет на результат. Обычно: сначала дедуплицируют точные и контентные дубли (чтобы они не «съедали» лимит сайта впустую), затем применяют схлопывание по сайту, затем — дедуп по сущности/сервису уже на почти финальном списке.
SEO-врезка. Параметрические URL (?utm=…, ?sort=…, сессионные id), HTTP/HTTPS- и www/non-www-зеркала, AMP/мобильные версии и «копии» страниц не дают дополнительных позиций: они схлопываются каноникализацией и финальной дедупликацией в один результат. Размножение почти-одинакового контента ради «занять больше места» не работает и тратит краулинговый бюджет (Модуль 2). Полезнее консолидировать сигналы на одной канонической странице.
Частые заблуждения
Заблуждение. «Раз страницы на разных доменах — это точно не дубли.» Контентный дубль не зависит от домена: один и тот же текст на двух разных сайтах (перепечатка, синдикация) — near-duplicate, и на выдаче останется один представитель.
Заблуждение. «Дедуп по URL ловит зеркала.» Только если URL нормализован одинаково. http://x.com/a и https://www.x.com/a/ — это один контент, но без нормализации (схема, www, слеш) ключи разные. Нормализация — обязательная часть ключа.
Лаба / практика

Дан список из 10 кандидатов: часть отличается только трекинг-параметрами, часть — это разные URL с одинаковым cluster_id, часть — одна организация из трёх источников (entity_id совпадает). Реализуйте трёхуровневую дедупликацию: (1) нормализация + дедуп по URL, (2) дедуп по cluster_id, (3) дедуп по entity_id с лимитом 1 результат на сущность. Затем введите «ловушку»: два разных товара с почти одинаковым названием — покажите, что дедуп по названию (плохой ключ) их ошибочно склеивает, а дедуп по entity_id/sku — нет.

Ожидаемый результат: из 10 кандидатов остаётся корректное число уникальных; продемонстрирован вред слишком агрессивного ключа (ложное склеивание). Время ~40 мин. Критерий «сделано»: ни один настоящий дубль не остался, ни один не-дубль не удалён; объяснён выбор ключа на каждом уровне.

Контрольные вопросы
  1. Чем дедупликация на выдаче отличается от каноникализации в индексе? Назовите три причины, по которым первая нужна несмотря на вторую.
  2. Перечислите три уровня дедупликации выдачи и подходящий ключ для каждого.
  3. Почему нормализация URL — обязательная часть ключа дедупликации первого уровня?
  4. Что такое ложное склеивание и какой ценой оборачивается слишком агрессивный ключ?
  5. Когда два документа на разных доменах являются дублями для целей выдачи?
  6. В каком порядке разумно применять дедуп-уровни и схлопывание по сайту? Обоснуйте.
  7. Почему размножение параметрических URL не даёт сайту дополнительных позиций?
Глава 15.3. Разнообразие выдачи (diversity), интентное покрытие, MMR-подобные подходы (продвинутый)

Цели обучения

После главы студент сможет:
  • Объяснить проблему неоднозначных и многоинтентных запросов и почему «лучшие по релевантности» документы не дают лучшую выдачу.
  • Сформулировать диверсификацию как оптимизацию полезности всей выдачи и связать её с субмодулярностью.
  • Вывести и реализовать MMR (Maximal Marginal Relevance) и объяснить роль параметра λ.
  • Описать интентное покрытие (intent coverage) и алгоритмы покрытия аспектов (например, IA-подобные подходы).
  • Обосновать гарантию 1 − 1/e жадного алгоритма на монотонной субмодулярной функции и оценить стоимость диверсификации.
Конспект

Проблема: неоднозначность и многоинтентность

Запрос редко имеет ровно один смысл. «Ягуар» — это и автомобиль, и животное, и ОС, и спортклуб. «Питон» — змея и язык программирования. Даже однозначный по теме запрос имеет разные интенты (intents): «купить», «отзывы», «инструкция», «официальный сайт». Ранжировщик, оптимизирующий поточечную релевантность, поставит наверх документы доминирующего смысла — и пользователь редкого смысла уйдёт ни с чем.
Интуиция. Если 70% спрашивающих «ягуар» имеют в виду машину, а 30% — животное, то выдача из 10 ссылок только про машины обслуживает 70% и полностью проваливает 30%. А выдача 7 про машину + 3 про животное почти не теряет в первой группе и резко выигрывает во второй. Разнообразие — это страховка от неопределённости интента.
Формально: система не знает истинный интент конкретного пользователя, она знает лишь распределение P(intent | query). Хорошая выдача максимизирует ожидаемую полезность по этому распределению, а не полезность для самого вероятного интента.

Полезность выдачи субмодулярна

Ключевая идея, объединяющая весь модуль. Пусть f(S) — полезность множества показанных результатов S. Эта функция обладает двумя свойствами:
  1. Монотонность: добавление результата не уменьшает полезность — f(S ∪ {d}) ≥ f(S).
  2. Субмодулярность (убывающая отдача, diminishing returns): ценность нового результата тем меньше, чем больше похожего уже показано. Формально для A ⊆ B:

Код: Выделить всё

f(A ∪ {d}) − f(A)  ≥  f(B ∪ {d}) − f(B)
Интуиция. Первая ссылка про «ягуар-животное» закрывает целый непокрытый интент — огромный прирост. Третья ссылка про то же — почти ничего. Это и есть убывающая отдача: предельная (marginal) польза результата падает по мере роста множества похожих на него. Схлопывание по сайту (15.1) и дедупликация (15.2) — частные случаи: однохостовость и одинаковость контента — это формы похожести, гасящие предельную пользу до нуля.
Задача диверсификации: выбрать S размера k, максимизирующее f(S). В общем виде максимизация субмодулярной функции при ограничении на размер — NP-трудна. Но есть спасение.

Жадный алгоритм и гарантия 1 − 1/e

Для монотонной субмодулярной функции простой жадный алгоритм даёт строгую гарантию:

Код: Выделить всё

greedy_diversify(candidates, k, f):
    S = []
    while len(S) < k:
        d* = argmax_{d ∉ S} ( f(S ∪ {d}) − f(S) )   # макс. предельный прирост
        S.append(d*)
    return S
На каждом шаге берём кандидата с наибольшим предельным приростом полезности. Классический результат (Nemhauser–Wolsey–Fisher): такой жадный выбор достигает не менее (1 − 1/e) ≈ 0.632 от оптимума. То есть «жадность, учитывающая уже выбранное» гарантированно близка к недостижимому идеалу — редкая ситуация, когда у простого алгоритма есть твёрдая теоретическая гарантия.
Инженерная заметка. 1 − 1/e ≈ 63% — это худший случай; на реальных выдачах жадный алгоритм почти всегда заметно ближе к оптимуму. Важна не сама цифра, а вывод: не нужно искать оптимальное подмножество перебором — жадная вставка по убыванию предельной пользы достаточно хороша и работает за O(k · n) оценок f.
MMR: Maximal Marginal Relevance

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

Код: Выделить всё

MMR-выбор:
d* = argmax_{d ∉ S} [ λ · Rel(d, q)  −  (1 − λ) · max_{s ∈ S} Sim(d, s) ]
где Rel(d, q) — релевантность документа запросу (скор ранжировщика), Sim(d, s) — сходство документа с уже выбранным, λ ∈ [0,1] — ручка баланса.
  • λ = 1 — чистая релевантность, диверсификации нет (исходная сортировка).
  • λ = 0 — чистая новизна, релевантность игнорируется (можно набрать разнообразный мусор).
  • λ ≈ 0.7…0.8 — типичный рабочий диапазон: релевантность главенствует, новизна корректирует.
Пример. Запрос «ягуар», кандидаты по релевантности: авто-1 (0.95), авто-2 (0.93), авто-3 (0.92), животное-1 (0.85), ОС-1 (0.70). При λ=0.75 и высоком Sim между всеми «авто-*»: после выбора авто-1 предельная польза авто-2 падает (штраф за сходство), и на каком-то шаге животное-1, несмотря на меньшую Rel, обгоняет авто-3 — потому что не похоже ни на что выбранное. Итог: авто-1, авто-2, животное-1, авто-3, ОС-1 вместо авто-1..3 подряд.
Внимание. MMR требует меры сходства Sim(d, s). Её качество критично: плохая Sim (например, только по совпадению слов) не уловит, что два по-разному написанных текста об одном и том же — похожи. На практике Sim берут из эмбеддингов (нейропредставлений, Модуль 10) или из тематических меток.
Интентное покрытие (intent coverage) и IA-подходы

MMR оперирует попарным сходством, но не «знает» про интенты явно. Альтернативное (и часто комбинируемое) семейство — покрытие аспектов/интентов. Идея: у запроса есть набор интентов {c} с весами P(c | q); у каждого документа — вероятность покрыть интент c, то есть P(d релевантен | c). Полезность выдачи S — это ожидаемая доля «удовлетворённых» пользователей:

Код: Выделить всё

U(S) = Σ_c  P(c | q) · [ 1 − Π_{d ∈ S} (1 − P(d удовлетворяет | c)) ]
Внутренняя скобка — вероятность, что хотя бы один документ из S закрыл интент c (единица минус вероятность, что никто не закрыл). Это монотонная субмодулярная функция — значит, тот же жадный алгоритм с гарантией 1 − 1/e применим. Такой подход (в литературе — семейство IA, intent-aware) явно «добивает» непокрытые интенты: документ ценен ровно настолько, насколько он закрывает ещё не закрытые смыслы.
Интуиция. MMR штрафует «похожесть на уже показанное». Intent-coverage поощряет «закрытие ещё не закрытого спроса». Часто это две стороны одной монеты, но intent-модель явнее и позволяет управлять покрытием по весам P(c|q) — показать редкий интент пропорционально его доле, а не выкинуть совсем.
Сколько диверсифицировать: цена и риск

Диверсификация — это сознательное смещение от чистой релевантности. Если переборщить, мы понизим объективно лучший результат ради «разнообразия» и навредим большинству. Поэтому:
  • Сила диверсификации (λ или вес покрытия) зависит от неоднозначности запроса: чем выше энтропия P(intent|q), тем агрессивнее диверсифицируем; для однозначных навигационных запросов диверсификацию почти отключают.
  • Эффект измеряют диверсити-чувствительными метриками (Модуль 19): не плоский nDCG, а его интентно-взвешенные варианты (например, α-nDCG, ERR-IA), которые вознаграждают покрытие аспектов и штрафуют избыточность.
SEO-врезка. Диверсификация — ещё одна причина, по которой нельзя «занять весь топ» одной интерпретацией запроса. Если ваш контент покрывает доминирующий интент, на менее частые интенты система всё равно поднимет других. Практический вывод: чтобы ранжироваться по неоднозначному запросу, бейте в конкретный интент и закрывайте его исчерпывающе, а не пытайтесь покрыть всё разом размытой страницей — диверсификатор предпочтёт чёткого специалиста по нужному аспекту.
Частые заблуждения
Заблуждение. «Разнообразие — это просто не показывать похожее.» Это половина правды (так делает MMR через штраф Sim). Вторая половина — покрытие интентов: цель не «непохожесть ради непохожести», а максимизация ожидаемой полезности по распределению намерений. Можно набрать разнообразный, но бесполезный набор.
Заблуждение. «Жадный алгоритм даёт лишь грубое приближение, надо искать оптимум.» Для монотонной субмодулярной функции жадность гарантированно даёт ≥63% оптимума в худшем случае и обычно гораздо ближе, а оптимум NP-труден. Перебор не оправдан.
Заблуждение. «Чем больше λ к нулю — тем лучше выдача разнообразнее.» При λ→0 релевантность игнорируется, и в топ полезут новые, но нерелевантные документы. Разнообразие без релевантности бесполезно; рабочая зона λ — ближе к релевантности.
Лаба / практика

Дан запрос с 6 кандидатами: каждый помечен интентом (auto/animal/os) и имеет Rel(d,q). Заданы попарные Sim (высокие внутри интента, низкие между). (1) Реализуйте MMR и постройте топ-4 для λ ∈ {1.0, 0.7, 0.3}; покажите, как меняется состав. (2) Реализуйте intent-coverage U(S) с весами P(c|q) = {auto:0.6, animal:0.3, os:0.1} и жадно постройте топ-4; сравните с MMR. (3) Посчитайте простой α-nDCG-подобный показатель для обеих выдач и для исходной сортировки по Rel.

Ожидаемый результат: при λ=1 — три auto подряд; при λ=0.7 — animal поднимается в топ; intent-coverage явно резервирует слот под animal пропорционально весу. Время ~70 мин. Критерий «сделано»: показано влияние λ, продемонстрирована убывающая отдача (предельный прирост второго auto меньше первого animal), интентно-взвешенная метрика выше у диверсифицированной выдачи.

Контрольные вопросы
  1. Почему сортировка по поточечной релевантности плоха на неоднозначном запросе? Сформулируйте через ожидаемую полезность по P(intent|q).
  2. Что значит «полезность выдачи субмодулярна»? Запишите неравенство убывающей отдачи.
  3. Какую гарантию даёт жадный алгоритм на монотонной субмодулярной функции и почему это практически важно?
  4. Выпишите формулу выбора MMR и объясните роль каждого слагаемого и параметра λ.
  5. Что произойдёт с выдачей при λ=1 и при λ=0? Почему ни та, ни другая крайность не годится?
  6. Чем intent-coverage отличается от MMR по постановке? Что даёт явная модель интентов?
  7. Почему силу диверсификации привязывают к неоднозначности запроса и какими метриками её измеряют?
  8. Покажите, что схлопывание по сайту (15.1) — частный случай субмодулярной диверсификации.
Глава 15.4. Управление позициями и вставка спецблоков (средний)

Цели обучения

После главы студент сможет:
  • Описать слотовую модель выдачи и роль движка федерации (federation/blending) в сборке финальной страницы.
  • Объяснить, как и по каким условиям вертикальные результаты (картинки, видео, карта, быстрый ответ) вставляются между органическими.
  • Реализовать простой blending: решение о включении спецблока и выборе его позиции.
  • Оценить влияние спецблоков на видимость органики и связать это с измерением (CTR по позициям).
Конспект

Выдача — это не один список, а собранная страница

До сих пор мы говорили об одном ранжированном списке (органика). Но реальная SERP — это федерация нескольких источников: основной веб-индекс плюс вертикали (verticals) — специализированные индексы (картинки, видео, новости, товары, карта/местные результаты, быстрые ответы/прямые ответы). За их совмещение отвечает движок федерации (federation / blending engine).

Архитектурно это слотовая модель: финальная страница — последовательность слотов (позиций), и каждый слот занимает либо органический результат, либо спецблок. Спецблок может занимать один слот или быть «толстым» (карусель картинок на ширину нескольких органических позиций).

Код: Выделить всё

SERP = [ slot_1, slot_2, ..., slot_n ]
каждый slot ← {органический результат} ∪ {спецблок вертикали}
Интуиция. Думайте о выдаче как о вёрстке газетной полосы: есть основная колонка (органика) и врезки (фото, врезка-карта, инфоблок). Редактор решает, стоит ли врезка этого запроса и куда её поставить, чтобы помочь читателю, а не мешать.
Два решения федерации: включать и куда ставить

Для каждой вертикали движок решает две вещи:
  1. Триггер (включать ли). Нужна ли эта вертикаль данному запросу? «Погода в Москве» → блок погоды (да). «Купить дрель» → товарная галерея (да). «Теорема Пифагора» → быстрый ответ (да), а картинки/карта — вряд ли. Решение принимает классификатор по запросу (предсказанный интент, Модуль 5) и по «уверенности» вертикали в своих результатах.
  2. Позиция (куда ставить). Спецблок вставляется на позицию, пропорциональную его предсказанной полезности относительно органики на той же позиции. Сильный спецблок (явный интент картинок) идёт наверх; слабый — ниже или вовсе подавляется.
Упрощённо решение о позиции — это сравнение «ценности слота»:

Код: Выделить всё

blend(organic, specials):
    page = []
    pos = 0
    while собираем страницу:
        best_organic = organic.peek()           # лучший оставшийся орг. результат
        best_special = argmax_v specials[v].value_at(pos)
        if best_special and best_special.value > best_organic.value * threshold(pos):
            page.append(best_special); pos += best_special.height
            specials.consume(best_special)
        else:
            page.append(best_organic); pos += 1
            organic.consume()
Здесь value спецблока и органики приведены к общей шкале (это нетривиально — калибровка разнотипных источников к сопоставимой «ожидаемой полезности на позиции»), а threshold(pos) отражает, что наверху планка для вытеснения органики выше.
Инженерная заметка. Калибровка ценности между источниками — центральная сложность федерации. Скор картиночной вертикали и текстовый скор несравнимы напрямую; их сводят к общей метрике (например, предсказанной вероятности клика/удовлетворения на данной позиции) на обучающих данных. Без калибровки спецблоки либо лезут всюду, либо не появляются.
Внимание. Спецблоки и органика делят слотовый бюджет. Если вертикаль заняла верхние слоты, органических позиций «над сгибом» становится меньше. Поэтому решения федерации, схлопывания (15.1) и диверсификации (15.3) нельзя принимать независимо — итоговая полезность страницы зависит от их совокупности. Хорошие реализации оценивают полезность всей собранной страницы, а не каждого слота изолированно.
Спецблоки и быстрые ответы

Особый случай — прямой/быстрый ответ (direct answer / answer box): блок, отвечающий на запрос прямо на странице (факт, определение, расчёт, расписание). Он экономит пользователю клик, но меняет поведение: часть запросов становится «без клика» (zero-click). Это влияет и на измерение (клик перестаёт быть сигналом удовлетворённости — Модуль 11 о сложностях клик-метрик), и на органику (её видимость снижается).

Влияние на измерение и эксперименты

Любое изменение состава/позиций меняет CTR по позициям и наблюдаемое поведение. Поэтому решения федерации калибруют и валидируют через A/B (Модуль 19), отслеживая не локальный CTR спецблока, а полезность сессии: не выросло ли число переформулировок и отказов из-за того, что спецблок вытеснил нужную органику.
SEO-врезка. Спецблоки и быстрые ответы сдвигают органику вниз и часть кликов забирают себе (zero-click). Практические следствия: (1) «позиция 1 в органике» уже не равна «первому, что видит пользователь» — над ней могут быть галерея и ответ-блок; (2) попадание в спецблок (товарная галерея, видео, локальная карточка, источник быстрого ответа) часто ценнее высокой органической позиции — оптимизировать стоит под формат, которого требует интент запроса; (3) для запросов с быстрым ответом органический трафик структурно ниже — это надо учитывать в прогнозах, а не списывать на «падение позиций».
Частые заблуждения
Заблуждение. «Спецблоки вставляются всегда на фиксированные позиции.» Нет: и факт включения, и позиция — результат решения федерации по конкретному запросу. На одном запросе галерея картинок наверху, на другом её нет вовсе.
Заблуждение. «Главное — максимизировать клики по спецблоку.» Локальный CTR блока обманчив: блок может перетягивать клики, ухудшая исход сессии (пользователь не нашёл нужное и переформулировал). Оптимизируют полезность всей страницы/сессии, а не отдельный блок.
Лаба / практика

Дано: органический список (5 результатов со скором, приведённым к общей шкале) и три вертикали (images, video, answer), каждая со своей value_at(pos) и высотой (images занимает 1 «толстый» слот высотой 2). Реализуйте blend(...) с порогом threshold(pos), убывающим с позицией. Прогоните три запроса: навигационный (вертикали слабые), «как выглядит X» (сильные картинки), «сколько будет 2+2» (сильный answer наверху). Покажите, как меняется сборка и сколько органических позиций осталось «над сгибом» (первые 4 слота).

Ожидаемый результат: для навигационного запроса спецблоки подавлены; для «как выглядит» галерея наверху и вытеснила органику; для арифметики answer-box занял слот 1. Время ~50 мин. Критерий «сделано»: корректная арифметика позиций (с учётом высоты толстого блока), продемонстрировано вытеснение органики и зависимость от запроса.

Контрольные вопросы
  1. Что такое слотовая модель выдачи и какова роль движка федерации?
  2. Какие два решения принимает федерация для каждой вертикали? От чего зависит каждое?
  3. Почему калибровка ценности между разнотипными источниками — главная сложность blending?
  4. Как «толстый» спецблок влияет на арифметику позиций и слотовый бюджет?
  5. Что такое быстрый ответ (zero-click) и как он влияет на измерение и на органику?
  6. Почему нельзя оптимизировать спецблок по его локальному CTR в отрыве от исхода сессии?
  7. Сформулируйте для SEO, почему «первая позиция в органике» больше не гарантирует первое внимание пользователя.
Итоги модуля
  1. Постранжирование оптимизирует выдачу целиком, а не отдельный документ. Между отсортированным списком и показом лежит слой, который схлопывает, дедуплицирует, диверсифицирует и собирает страницу из источников. Цель — полезность всей SERP, а не сумма поточечных скоров.
  2. Схлопывание по сайту (host collapsing) ограничивает число результатов с одного хоста/домена (eTLD+1). Требует корректного выделения зарегистрированного домена через таблицу публичных суффиксов и добора кандидатов (overfetch), иначе в топе появляются пустые позиции.
  3. Дедупликация на выдаче работает в три уровня — точный URL, контентный near-duplicate (по кластеру/сигнатуре из индекса), сущность/сервис — и дополняет каноникализацию там, где сходство видно только запросо-зависимо. Главный риск — ложное склеивание разных полезных результатов.
  4. Полезность выдачи монотонна и субмодулярна (убывающая отдача от похожих результатов). Схлопывание и дедупликация — частные случаи: однохостовость и одинаковость гасят предельную пользу.
  5. Диверсификация страхует от неопределённости интента: максимизирует ожидаемую полезность по P(intent|q). Реализуется жадным алгоритмом с гарантией 1 − 1/e от оптимума.
  6. MMR балансирует релевантность и новизну через λ (рабочая зона ближе к релевантности, λ≈0.7…0.8); intent-coverage явно закрывает непокрытые интенты пропорционально их весам. Силу диверсификации привязывают к неоднозначности запроса и измеряют интентно-взвешенными метриками.
  7. Финальная SERP — федерация источников по слотовой модели. Движок blending решает, включать ли вертикаль и куда её поставить, приводя разнотипные источники к общей шкале полезности. Спецблоки и быстрые ответы делят слотовый бюджет с органикой и сдвигают её вниз.
  8. Главное: схлопывание, дедупликация, диверсификация и федерация — взаимозависимы и должны оцениваться по полезности всей собранной страницы и сессии, а не по локальным метрикам отдельных слотов.
Глоссарий модуля
  • Постранжирование (post-ranking, re-ranking layer) — слой между сортировкой по релевантности и показом, формирующий состав и структуру выдачи.
  • Выдача (SERP, search engine results page) — финальная страница результатов, собранная из органики и спецблоков.
  • Группировка / схлопывание по сайту (host collapsing) — ограничение числа результатов с одного хоста/домена с переносом «лишних» в свёрнутый блок, вниз или в отброс.
  • eTLD / публичный суффикс (public suffix) — эффективный домен верхнего уровня, включая составные (.co.uk) и платформенные (blogplatform.io).
  • eTLD+1 (зарегистрированный домен) — публичный суффикс плюс одна метка слева; «реально купленный» домен.
  • Добор кандидатов (overfetch) — запрос у ранжировщика большего числа документов, чем нужно показать, чтобы компенсировать удаления при схлопывании/дедупликации.
  • Дедупликация на выдаче — финальное устранение повторов по URL, контенту (near-duplicate) и сущности/сервису.
  • Контентный дубль (near-duplicate) — разные URL с по сути одинаковым контентом; кластеризуются по сигнатурам (SimHash/MinHash, shingling).
  • Ложное склеивание (false merge) — ошибочное удаление разных полезных результатов слишком агрессивным ключом дедупликации.
  • Разнообразие / диверсификация (diversity) — формирование выдачи, покрывающей разные интенты/аспекты запроса.
  • Интент (intent) — намерение за запросом; P(intent|q) — распределение намерений по запросу.
  • Субмодулярность (submodularity) — свойство убывающей предельной отдачи: новый похожий результат добавляет тем меньше, чем больше похожего уже показано.
  • Жадная аппроксимация 1 − 1/e — гарантия жадного алгоритма на монотонной субмодулярной функции (≈63% оптимума в худшем случае).
  • MMR (Maximal Marginal Relevance) — жадный отбор, балансирующий релевантность Rel(d,q) и новизну (штраф Sim) через параметр λ.
  • Интентное покрытие (intent coverage, IA-подходы) — диверсификация через явную максимизацию ожидаемой доли удовлетворённых интентов.
  • α-nDCG / ERR-IA — интентно-взвешенные метрики качества, вознаграждающие покрытие аспектов и штрафующие избыточность.
  • Федерация / blending — совмещение органики и вертикалей в единую выдачу.
  • Вертикаль (vertical) — специализированный источник/индекс (картинки, видео, новости, товары, карта, быстрый ответ).
  • Слотовая модель — представление SERP как последовательности позиций-слотов, занимаемых органикой или спецблоками.
  • Триггер вертикали — решение, включать ли спецблок данной вертикали для запроса.
  • Быстрый/прямой ответ (direct answer, zero-click) — блок с ответом прямо на странице, нередко без перехода на сайт.
Связи с другими модулями
  • Опирается на Модуль 19 (оценка и эксперименты: метрики и A/B) — лимиты, λ, пороги федерации калибруют по метрикам полезности выдачи и сессии; диверсити-чувствительные метрики (α-nDCG, ERR-IA) родом оттуда (базовые метрики nDCG/MAP — Модуль 1).
  • Принимает вход от Модуля 12 (каскад L0-L3 и serving) — упорядоченный список кандидатов с признаками и предсказанным интентом (сам интент — из Модуля 5); overfetch нагружает верхние стадии каскада.
  • Опирается на Модуль 3 (каноникализация) — дедупликация выдачи дополняет индексную каноникализацию остаточными и запросо-зависимыми случаями; ключи нормализации общие.
  • Использует кластеры/сигнатуры дублей — cluster_id/SimHash приходят из стадии индексирования и каноникализации.
  • Связан с Модулем 10 (нейропоиск, эмбеддинги) — мера сходства Sim(d,s) для MMR/диверсификации часто строится на эмбеддингах.
  • Перетекает в Модуль 16 (антиспам) — манипуляции, нацеленные на захват выдачи (doorway-страницы, размножение зеркал ради позиций), нейтрализуются совместно схлопыванием/дедупликацией и антиспам-сигналами.
Материалы для углубления
  • Классические работы по диверсификации результатов поиска (MMR; intent-aware подходы и покрытие аспектов).
  • Литература по максимизации монотонных субмодулярных функций и жадным алгоритмам с гарантией 1 − 1/e (Nemhauser–Wolsey–Fisher).
  • Обзоры по диверсити-чувствительным метрикам оценки (α-nDCG, ERR-IA, intent-взвешенный nDCG).
  • Работы по обнаружению near-duplicate документов (shingling, SimHash, MinHash) и оценке порогов сходства.
  • Материалы по таблицам публичных суффиксов и корректному выделению зарегистрированного домена.
  • Литература по федеративному/агрегированному поиску (federated/aggregated search, vertical selection, result presentation) и калибровке разнотипных источников к общей шкале полезности.
👍3 ❤️ 🔥2 😄 🤔
Аватара пользователя
rabbit_geek
Сообщения: 1
Зарегистрирован: 27 май 2026, 22:26

Re: Группировка, схлопывание, разнообразие

Сообщение rabbit_geek »

вопрос про схлопывание дублей: на каком этапе вы детектите near-duplicate? если уже после ранжирования, то тяжелая модель зря посчитала скоры для пяти копий одной статьи. мы пробовали симхеш еще на стадии кандидатов и сэкономили кучу инференса
👍1 ❤️ 🔥1 😄 🤔
Аватара пользователя
Jaymor
Сообщения: 1
Зарегистрирован: 29 май 2026, 03:34

Re: Группировка, схлопывание, разнообразие

Сообщение Jaymor »

наконец понял в чем разница между группировкой и диверсификацией. группировка это про показать один результат с домена и спрятать остальные под кат, а разнообразие про разные интенты в топе. путал их потому что оба режут похожее, но цели разные
👍1 ❤️1 🔥1 😄 🤔
Аватара пользователя
torsre
Сообщения: 1
Зарегистрирован: 17 май 2026, 04:53

Re: Группировка, схлопывание, разнообразие

Сообщение torsre »

не соглашусь что MMR это золотой стандарт для diversity. лямбду подбирать руками боль, на навигационных запросах он наоборот вредит и разбавляет очевидный нужный ответ. мы по типу запроса включали диверсификацию выборочно, а не на всем трафике
👍 ❤️1 🔥3 😄 🤔
Ответить
← Предыдущая глава
Метапоиск и федерация источников
Следующая глава →
Постранжирование, антиспам и качество выдачи

Все главы курса «Поисковые системы: индексирование, факторы ранжирования и формирование выдачи»

Поделиться темой: ✈ Telegram VK

Вернуться в «Поисковые системы: индекс, факторы, выдача»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость