Обзор Decay RankerCompatible with Milvus 2.6.x
В традиционном векторном поиске результаты ранжируются исключительно по векторному сходству - насколько близко векторы совпадают в математическом пространстве. Но в реальных приложениях то, что делает контент действительно релевантным, часто зависит не только от семантического сходства.
Рассмотрим эти повседневные сценарии:
Поиск новостей, в котором вчерашняя статья должна занимать более высокое место, чем аналогичная статья трехлетней давности.
Система поиска ресторанов, которая отдает предпочтение заведениям, расположенным в 5 минутах езды, а не тем, до которых нужно ехать 30 минут.
Платформа электронной коммерции, которая продвигает трендовые товары, даже если они чуть менее похожи на поисковый запрос.
Все эти сценарии объединяет общая потребность: сбалансировать векторное сходство с другими числовыми факторами, такими как время, расстояние или популярность.
Ранжировщики распада в Milvus решают эту задачу, корректируя рейтинги поиска на основе значений числовых полей. Они позволяют сбалансировать векторное сходство со "свежестью", "близостью" или другими числовыми свойствами ваших данных, создавая более интуитивный и контекстуально релевантный опыт поиска.
Примечания по использованию
Ранжирование по распаду нельзя использовать при поиске по группам.
Поле, используемое для ранжирования по распаду, должно быть числовым (
INT8,INT16,INT32,INT64,FLOATилиDOUBLE).Каждый ранжировщик распада может использовать только одно числовое поле.
Согласованность единиц времени: При использовании ранжирования по времени единицы измерения для параметров
origin,scaleиoffsetдолжны соответствовать единицам измерения, используемым в данных вашей коллекции:Если в коллекции хранятся временные метки в секундах, используйте секунды для всех параметров.
Если в коллекции хранятся временные метки в миллисекундах, используйте миллисекунды для всех параметров
Если ваша коллекция хранит временные метки в микросекундах, используйте микросекунды для всех параметров.
Как это работает
Ранжирование по распаду расширяет возможности традиционного векторного поиска за счет включения в процесс ранжирования таких числовых факторов, как время или географическое расстояние. Весь процесс проходит по следующим этапам:
Этап 1: Вычисление нормализованных баллов сходства
Сначала Milvus рассчитывает и нормализует баллы сходства векторов, чтобы обеспечить последовательное сравнение:
Для метрик расстояния L2 и JACCARD (где меньшие значения указывают на большую схожесть):
normalized_score = 1.0 - (2 × arctan(score))/πРасстояния преобразуются в баллы сходства от 0 до 1, где большее значение лучше.
Для метрик IP, COSINE и BM25 (где более высокие значения уже указывают на лучшее сходство): Баллы используются напрямую без нормализации.
Этап 2: Расчет оценок распада
Далее Milvus рассчитывает оценку распада на основе значения числового поля (например, временной метки или расстояния), используя выбранный вами ранжировщик распада:
Каждый ранжировщик распада преобразует необработанные числовые значения в нормализованные оценки релевантности в диапазоне от 0 до 1.
Балл распада отражает степень релевантности элемента в зависимости от его "расстояния" до идеальной точки.
Формула расчета зависит от типа ранжировщика распада. Подробнее о том, как рассчитать балл распада, читайте на страницах, посвященных гауссову распаду, экспоненциальному распаду и линейному распаду.
Этап 3: Вычисление итоговых оценок
Наконец, Milvus объединяет нормализованный балл сходства и балл распада, чтобы получить итоговый балл ранжирования:
final_score = normalized_similarity_score × decay_score
В случае гибридного поиска (сочетающего несколько векторных полей) Milvus берет максимальный нормализованный балл сходства среди поисковых запросов:
final_score = max([normalized_score₁, normalized_score₂, ..., normalized_scoreₙ]) × decay_score
Например, если научная статья получила 0,82 балла за векторное сходство и 0,91 балла за поиск текста на основе BM25 в гибридном поиске, Milvus использует 0,91 балла в качестве базового балла сходства перед применением коэффициента распада.
Ранжирование по распаду в действии
Давайте посмотрим на ранжирование по распаду в практическом сценарии - поиск "исследовательских работ по искусственному интеллекту" с распадом по времени:
В этом примере показатели распада отражают, как релевантность уменьшается со временем - более новые статьи получают оценки ближе к 1,0, более старые - ниже. Эти значения рассчитываются с помощью специального ранжировщика распада. Подробнее см. в разделе Выбор правильного ранжировщика распада.
Статья |
Векторное сходство |
Нормализованный балл сходства |
Дата публикации |
Оценка распада |
Итоговый балл |
Итоговый ранг |
|---|---|---|---|---|---|---|
Бумага A |
Высокий |
0,85 ( |
2 недели назад |
0.80 |
0.68 |
2 |
Бумага B |
Очень высокий |
0,92 ( |
6 месяцев назад |
0.45 |
0.41 |
3 |
Бумага C |
Средний |
0.75 ( |
1 день назад |
0.98 |
0.74 |
1 |
Бумага D |
Средне-высокий |
0.76 ( |
3 недели назад |
0.70 |
0.53 |
4 |
Без ранжирования по распаду бумага B заняла бы самое высокое место на основе чистого векторного сходства (0,92). Однако с применением ранжирования по распаду:
Работа C поднимается на позицию №1, несмотря на среднее сходство, потому что она очень свежая (опубликована вчера).
Работа B опускается на позицию № 3, несмотря на отличное сходство, потому что она относительно старая.
Работа D использует расстояние L2 (где меньше - лучше), поэтому ее оценка нормализуется с 1,2 до 0,76 перед применением распада
Выберите правильный ранжировщик распада
Milvus предлагает различные ранжировщики распада - gauss, exp, linear, каждый из которых предназначен для конкретных случаев использования:
Ранжировщик распада |
Характеристики |
Идеальные сценарии использования |
Пример сценария |
|---|---|---|---|
Гаусс ( |
Естественный постепенный спад, который умеренно расширяется |
|
При поиске ресторана качественные заведения, расположенные на расстоянии 3 км, остаются доступными для обнаружения, хотя и ранжируются ниже, чем близлежащие варианты |
Экспоненциальный ( |
Сначала быстро снижается, но потом сохраняет длинный хвост |
|
В новостном приложении вчерашние статьи ранжируются гораздо выше, чем материалы недельной давности, но высоко релевантные старые статьи все равно могут появляться |
Линейный ( |
Последовательный, предсказуемый спад с четкой границей |
|
В системе поиска событий события, выходящие за рамки двухнедельного будущего, просто не отображаются. |
Подробную информацию о том, как каждый ранжировщик распада рассчитывает баллы и конкретные модели распада, см. в специальной документации:
Пример реализации
Ранжировщики распада могут применяться как к стандартному векторному поиску, так и к гибридным операциям поиска в Milvus. Ниже приведены ключевые фрагменты кода для реализации этой возможности.
Перед использованием функций распада необходимо создать коллекцию с соответствующими числовыми полями (например, временными метками, расстояниями и т. д.), которые будут использоваться для расчетов распада. Полные рабочие примеры, включающие настройку коллекции, определение схемы и вставку данных, см. в разделе Учебник: Реализация ранжирования по времени в Milvus.
Создание ранжировщика распада
Чтобы реализовать ранжирование по распаду, сначала определите объект Function с соответствующей конфигурацией:
from pymilvus import Function, FunctionType
# Create a decay function for timestamp-based decay
# Note: All time parameters must use the same unit as your collection data
decay_ranker = Function(
name="time_decay", # Function identifier
input_field_names=["timestamp"], # Numeric field to use for decay
function_type=FunctionType.RERANK, # Must be set to RERANK for decay rankers
params={
"reranker": "decay", # Specify decay reranker. Must be "decay"
"function": "gauss", # Choose decay function type: "gauss", "exp", or "linear"
"origin": int(datetime.datetime(2025, 1, 15).timestamp()), # Reference point (seconds)
"scale": 7 * 24 * 60 * 60, # 7 days in seconds (must match collection data unit)
"offset": 24 * 60 * 60, # 1 day no-decay zone (must match collection data unit)
"decay": 0.5 # Half score at scale distance
}
)
import io.milvus.v2.service.vector.request.ranker.DecayRanker;
import java.time.ZoneId;
import java.time.ZonedDateTime;
ZonedDateTime zdt = ZonedDateTime.of(2025, 1, 25, 0, 0, 0, 0, ZoneId.systemDefault());
DecayRanker ranker = DecayRanker.builder()
.name("time_decay")
.inputFieldNames(Collections.singletonList("timestamp"))
.function("gauss")
.origin(zdt.toInstant().toEpochMilli())
.scale(7 * 24 * 60 * 60)
.offset(24 * 60 * 60)
.decay(0.5)
.build();
import {FunctionType } from "@zilliz/milvus2-sdk-node";
const decayRanker = {
name: "time_decay",
input_field_names: ["timestamp"],
function_type: FunctionType.RERANK,
params: {
reranker: "decay",
function: "gauss",
origin: new Date(2025, 1, 15).getTime(),
scale: 7 * 24 * 60 * 60,
offset: 24 * 60 * 60,
decay: 0.5,
},
};
// go
# restful
Параметр |
Требуемый? |
Описание |
Значение/пример |
|---|---|---|---|
|
Да |
Идентификатор вашей функции, используемый при выполнении поиска. Выберите описательное имя, соответствующее вашему сценарию использования. |
|
|
Да |
Числовое поле для расчета показателя распада. Определяет, какой атрибут данных будет использоваться для вычисления распада (например, временные метки для распада на основе времени, координаты для распада на основе местоположения). Это должно быть поле в вашей коллекции, содержащее соответствующие числовые значения. Поддерживаются INT8/16/32/64, FLOAT, DOUBLE. |
|
|
Да |
Указывает тип создаваемой функции. Должно быть установлено значение |
|
|
Да |
Указывает используемый метод ранжирования. Должно быть установлено значение |
|
|
Да |
Указывает, какой математический ранжировщик распада следует применить. Определяет форму кривой снижения релевантности. Рекомендации по выбору подходящей функции см. в разделе Выбор правильного ранжировщика распада. |
|
|
Да |
Точка отсчета, от которой рассчитывается балл распада. Элементы, находящиеся на этом значении, получают максимальные баллы релевантности. Для распада, основанного на времени, единица измерения времени должна соответствовать данным коллекции. |
|
|
Да |
Расстояние или время, за которое релевантность снижается до значения Для снижения релевантности на основе времени единица измерения времени должна соответствовать данным вашей коллекции. Большие значения создают более постепенное снижение релевантности; меньшие значения создают более резкое снижение. |
|
|
Нет |
Создает "зону без распада" вокруг Для распада, основанного на времени, единица времени должна соответствовать данным вашей коллекции. Предметы в этом диапазоне |
|
|
Нет |
Значение балла на расстоянии Должно быть от 0 до 1. |
|
Применить к стандартному векторному поиску
Определив свой ранжировщик распада, вы можете применить его в процессе поиска, передав параметр ranker:
# Use the decay function in standard vector search
results = milvus_client.search(
collection_name,
data=[your_query_vector], # Replace with your query vector
anns_field="vector_field",
limit=10,
output_fields=["document", "timestamp"], # Include the decay field in outputs to see values
ranker=decay_ranker, # Apply the decay ranker here
consistency_level="Strong"
)
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
SearchReq searchReq = SearchReq.builder()
.collectionName(COLLECTION_NAME)
.data(Collections.singletonList(new EmbeddedText("search query")))
.annsField("vector_field")
.limit(10)
.outputFields(Arrays.asList("document", "timestamp"))
.functionScore(FunctionScore.builder()
.addFunction(ranker)
.build())
.build();
SearchResp searchResp = client.search(searchReq);
const result = await milvusClient.search({
collection_name: "collection_name",
data: [your_query_vector], // Replace with your query vector
anns_field: "dense",
limit: 10,
output_fields: ["document", "timestamp"],
rerank: ranker,
consistency_level: "Strong",
});
// go
# restful