Boost RankerCompatible with Milvus v2.6.2+
Вместо того чтобы полагаться исключительно на семантическое сходство, рассчитываемое на основе векторных расстояний, Boost Ranker позволяет влиять на результаты поиска значимым образом. Они идеально подходят для быстрой корректировки результатов поиска с помощью фильтрации метаданных.
Когда поисковый запрос включает функцию Boost Ranker, Milvus использует необязательное условие фильтрации в функции для поиска совпадений среди кандидатов на получение результатов поиска и повышает оценки этих совпадений, применяя указанный вес, что помогает повысить или понизить рейтинг сопоставленных сущностей в итоговом результате.
Когда использовать Boost Ranker
В отличие от других ранжировщиков, которые полагаются на кросс-кодировочные модели или алгоритмы слияния, Boost Ranker напрямую внедряет необязательные правила, управляемые метаданными, в процесс ранжирования, что делает его более подходящим для следующих сценариев.
Пример использования |
Примеры |
Почему Boost Ranker хорошо работает |
|---|---|---|
Приоритизация контента, ориентированная на бизнес |
|
Без необходимости перестраивать индексы или изменять модели встраивания векторов - операции, которые могут отнимать много времени, - вы можете мгновенно повышать или понижать позиции определенных элементов в результатах поиска, применяя дополнительные фильтры метаданных в режиме реального времени. Этот механизм обеспечивает гибкое, динамическое ранжирование поиска, которое легко адаптируется к изменяющимся требованиям бизнеса. |
Стратегическое понижение рейтинга контента |
|
Вы также можете объединить несколько Boost Ranker для реализации более динамичной и надежной стратегии ранжирования на основе веса.
Механизм работы Boost Ranker
Следующая схема иллюстрирует основной рабочий процесс Boost Rankers.
Механизм работы Boost Ranker
Когда вы вставляете данные, Milvus распределяет их по сегментам. Во время поиска каждый сегмент возвращает набор кандидатов, а Milvus ранжирует их по всем сегментам, чтобы получить окончательные результаты. Если поисковый запрос включает Boost Ranker, Milvus применяет его к результатам кандидатов из каждого сегмента, чтобы предотвратить потенциальную потерю точности и улучшить запоминание.
Перед окончательной обработкой результатов Milvus обрабатывает эти кандидаты с помощью Boost Ranker следующим образом:
Применяет необязательное выражение фильтрации, указанное в Boost Ranker, чтобы определить сущности, соответствующие выражению.
Применяет вес, указанный в Boost Ranker, чтобы повысить баллы идентифицированных сущностей.
Вы не можете использовать Boost Ranker в качестве ранжирующего элемента в многовекторном гибридном поиске. Однако его можно использовать в качестве ранжирующего элемента в любом из подзапросов (AnnSearchRequest).
Примеры использования Boost Ranker
Следующий пример иллюстрирует использование Boost Ranker в одновекторном поиске, который требует возврата пяти наиболее релевантных сущностей и добавления весов к оценкам сущностей с абстрактным типом doc.
Соберите кандидатов на результаты поиска в сегменты.
В следующей таблице предполагается, что Milvus распределяет сущности по двум сегментам(0001 и 0002), и каждый сегмент возвращает пять кандидатов.
ID
DocType
Оценка
Ранг
сегмент
117
абстрактный
0.344
1
0001
89
реферат
0.456
2
0001
257
тело
0.578
3
0001
358
заголовок
0.788
4
0001
168
тело
0.899
5
0001
46
тело
0.189
1
0002
48
тело
0265
2
0002
561
абстрактный
0.366
3
0002
344
реферат
0.444
4
0002
276
реферат
0.845
5
0002
Примените выражение фильтрации, указанное в Boost Ranker (
doctype='abstract').Как обозначено полем
DocTypeв следующей таблице, Milvus отметит для дальнейшей обработки все сущности, у которыхdoctypeустановлен наabstract.ИДЕНТИФИКАТОР
DocType
Оценка
Ранг
сегмент
117
абстрактный
0.344
1
0001
89
реферат
0.456
2
0001
257
тело
0.578
3
0001
358
заголовок
0.788
4
0001
168
тело
0.899
5
0001
46
тело
0.189
1
0002
48
тело
0265
2
0002
561
абстрактный
0.366
3
0002
344
реферат
0.444
4
0002
276
реферат
0.845
5
0002
Примените вес, указанный в Boost Ranker (
weight=0.5).Все сущности, идентифицированные на предыдущем шаге, будут умножены на вес, указанный в Boost Ranker, что приведет к изменению их рангов.
ID
DocType
Балл
Взвешенный балл
(= балл x вес)
Ранг
сегмент
117
абстрактный
0.344
0.172
1
0001
89
абстрактный
0.456
0.228
2
0001
257
тело
0.578
0.578
3
0001
358
название
0.788
0.788
4
0001
168
тело
0.899
0.899
5
0001
561
реферат
0.366
0.183
1
0002
46
тело
0.189
0.189
2
0002
344
абстрактный
0.444
0.222
3
0002
48
тело
0.265
0.265
4
0002
276
абстрактный
0.845
0.423
5
0002
Вес должен быть выбранным вами числом с плавающей точкой. В случаях, подобных приведенному выше, когда меньший балл указывает на большую значимость, используйте вес меньше 1. В противном случае используйте вес больше 1.
Для получения окончательных результатов объедините кандидатов из всех сегментов на основе взвешенных оценок.
ID
DocType
Оценка
Взвешенный балл
Ранг
сегмент
117
абстрактный
0.344
0.172
1
0001
561
абстрактный
0.366
0.183
2
0002
46
тело
0.189
0.189
3
0002
344
абстрактный
0.444
0.222
4
0002
89
абстрактный
0.456
0.228
5
0001
Использование Boost Ranker
В этом разделе вы увидите примеры использования Boost Ranker для влияния на результаты одновекторного поиска.
Создание Boost Ranker
Прежде чем передавать Boost Ranker в качестве ранжировщика поискового запроса, необходимо правильно определить Boost Ranker как функцию ранжирования, как показано ниже:
from pymilvus import Function, FunctionType
ranker = Function(
name="boost",
input_field_names=[], # Must be an empty list
function_type=FunctionType.RERANK,
params={
"reranker": "boost",
"filter": "doctype == 'abstract'",
"random_score": {
"seed": 126,
"field": "id"
},
"weight": 0.5
}
)
import io.milvus.v2.service.vector.request.ranker.BoostRanker;
BoostRanker ranker = BoostRanker.builder()
.name("boost")
.filter("doctype == \"abstract\"")
.weight(5.0f)
.randomScoreField("id")
.randomScoreSeed(126)
.build();
// go
import {FunctionType} from '@zilliz/milvus2-sdk-node';
const ranker = {
name: "boost",
input_field_names: [],
type: FunctionType.RERANK,
params: {
reranker: "boost",
filter: "doctype == 'abstract'",
random_score: {
seed: 126,
field: "id",
},
weight: 0.5,
},
};
# restful
Параметр |
Требуемый? |
Описание |
Значение/пример |
|---|---|---|---|
|
Да |
Уникальный идентификатор для данной функции |
|
|
Да |
Список векторных полей, к которым следует применить функцию (должен быть пустым для Boost Ranker) |
|
|
Да |
Тип вызываемой функции; используйте |
|
|
Да |
Указывает тип реранкера. Должно быть установлено значение |
|
|
Да |
Указывает вес, который будет умножен на оценки всех совпадающих сущностей в необработанных результатах поиска. Значение должно быть числом с плавающей точкой.
|
|
|
Нет |
Указывает выражение фильтра, которое будет использоваться для сопоставления сущностей в результатах поиска. Это может быть любое действительное базовое выражение фильтра, описанное в разделе "Объяснение фильтрации". Примечание: Используйте только базовые операторы, такие как |
|
|
Нет |
Указывает функцию random, которая случайным образом генерирует значение между
|
|
Поиск с помощью одного Boost Ranker
Когда функция Boost Ranker готова, вы можете ссылаться на нее в поисковом запросе. В следующем примере предполагается, что вы уже создали коллекцию со следующими полями: id, vector и doctype.
from pymilvus import MilvusClient
# Connect to the Milvus server
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus"
)
# Assume you have a collection set up
# Conduct a similarity search using the created ranker
client.search(
collection_name="my_collection",
data=[[-0.619954382375778, 0.4479436794798608, -0.17493894838751745, -0.4248030059917294, -0.8648452746018911]],
anns_field="vector",
params={},
output_field=["doctype"],
ranker=ranker
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.data.FloatVec;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.token("root:Milvus")
.build());
SearchResp searchReq = client.search(SearchReq.builder()
.collectionName("my_collection")
.data(Collections.singletonList(new FloatVec(new float[]{-0.619954f, 0.447943f, -0.174938f, -0.424803f, -0.864845f})))
.annsField("vector")
.outputFields(Collections.singletonList("doctype"))
.functionScore(FunctionScore.builder()
.addFunction(ranker)
.build())
.build());
SearchResp searchResp = client.search(searchReq);
// go
import { MilvusClient } from '@zilliz/milvus2-sdk-node';
// Connect to the Milvus server
const client = new MilvusClient({
address: 'localhost:19530',
token: 'root:Milvus'
});
// Assume you have a collection set up
// Conduct a similarity search
const searchResults = await client.search({
collection_name: 'my_collection',
data: [-0.619954382375778, 0.4479436794798608, -0.17493894838751745, -0.4248030059917294, -0.8648452746018911],
anns_field: 'vector',
output_fields: ['doctype'],
rerank: ranker,
});
console.log('Search results:', searchResults);
# restful
Поиск с помощью нескольких Boost Rankers
Вы можете объединить несколько Boost Rankers в одном поиске, чтобы повлиять на результаты поиска. Для этого создайте несколько Boost Rankers, ссылайтесь на них в экземпляре FunctionScore и используйте экземпляр FunctionScore в качестве ранжирующего элемента в поисковом запросе.
В следующем примере показано, как изменить оценки всех идентифицированных сущностей, применив вес между 0,8 и 1,2.
from pymilvus import MilvusClient, Function, FunctionType, FunctionScore
# Create a Boost Ranker with a fixed weight
fix_weight_ranker = Function(
name="boost",
input_field_names=[], # Must be an empty list
function_type=FunctionType.RERANK,
params={
"reranker": "boost",
"weight": 0.8
}
)
# Create a Boost Ranker with a randomly generated weight between 0 and 0.4
random_weight_ranker = Function(
name="boost",
input_field_names=[], # Must be an empty list
function_type=FunctionType.RERANK,
params={
"reranker": "boost",
"random_score": {
"seed": 126,
},
"weight": 0.4
}
)
# Create a Function Score
ranker = FunctionScore(
functions=[
fix_weight_ranker,
random_weight_ranker
],
params={
"boost_mode": "Multiply",
"function_mode": "Sum"
}
)
# Conduct a similarity search using the created Function Score
client.search(
collection_name="my_collection",
data=[[-0.619954382375778, 0.4479436794798608, -0.17493894838751745, -0.4248030059917294, -0.8648452746018911]],
anns_field="vector",
params={},
output_field=["doctype"],
ranker=ranker
)
import io.milvus.common.clientenum.FunctionType;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq.Function fixWeightRanker = CreateCollectionReq.Function.builder()
.functionType(FunctionType.RERANK)
.name("boost")
.param("reranker", "boost")
.param("weight", "0.8")
.build();
CreateCollectionReq.Function randomWeightRanker = CreateCollectionReq.Function.builder()
.functionType(FunctionType.RERANK)
.name("boost")
.param("reranker", "boost")
.param("weight", "0.4")
.param("random_score", "{\"seed\": 126}")
.build();
Map<String, String> params = new HashMap<>();
params.put("boost_mode","Multiply");
params.put("function_mode","Sum");
FunctionScore ranker = FunctionScore.builder()
.addFunction(fixWeightRanker)
.addFunction(randomWeightRanker)
.params(params)
.build()
SearchResp searchReq = client.search(SearchReq.builder()
.collectionName("my_collection")
.data(Collections.singletonList(new FloatVec(new float[]{-0.619954f, 0.447943f, -0.174938f, -0.424803f, -0.864845f})))
.annsField("vector")
.outputFields(Collections.singletonList("doctype"))
.addFunction(ranker)
.build());
SearchResp searchResp = client.search(searchReq);
// go
import {FunctionType} from '@zilliz/milvus2-sdk-node';
const fix_weight_ranker = {
name: "boost",
input_field_names: [],
type: FunctionType.RERANK,
params: {
reranker: "boost",
weight: 0.8,
},
};
const random_weight_ranker = {
name: "boost",
input_field_names: [],
type: FunctionType.RERANK,
params: {
reranker: "boost",
random_score: {
seed: 126,
},
weight: 0.4,
},
};
const ranker = {
functions: [fix_weight_ranker, random_weight_ranker],
params: {
boost_mode: "Multiply",
function_mode: "Sum",
},
};
await client.search({
collection_name: "my_collection",
data: [[-0.619954382375778, 0.4479436794798608, -0.17493894838751745, -0.4248030059917294, -0.8648452746018911]],
anns_field: "vector",
params: {},
output_field: ["doctype"],
ranker: ranker
});
# restful
В частности, есть два ранжировщика Boost: один применяет фиксированный вес ко всем найденным сущностям, а другой присваивает им случайный вес. Затем мы ссылаемся на эти два ранжировщика в функции FunctionScore, которая также определяет, как веса влияют на оценки найденных сущностей.
В следующей таблице перечислены параметры, необходимые для создания экземпляра FunctionScore.
Параметр |
Требуется? |
Описание |
Значение/пример |
|---|---|---|---|
|
Да |
Указывает имена целевых ранжиров в списке. |
|
|
Нет |
Указывает, как указанные веса влияют на оценки всех совпадающих сущностей. Возможные значения:
|
|
|
Нет |
Указывает, как обрабатываются взвешенные значения из различных Boost Rankers. Возможные значения:
|
|