归一化处理器
2.10 版引入
normalization-processor
是一种搜索阶段结果处理器,它在搜索执行的查询和获取阶段之间运行。它拦截查询阶段的结果,然后对来自不同查询子句的文档分数进行归一化和组合,然后将文档传递给获取阶段。
分数归一化与组合
许多应用程序既需要关键词匹配,也需要语义理解。例如,BM25 能准确地为包含关键词的查询提供相关搜索结果,而神经网络在查询需要自然语言理解时表现良好。因此,你可能希望将 BM25 搜索结果与 k-NN 或神经网络搜索的结果结合起来。然而,BM25 和 k-NN 搜索使用不同的尺度来计算匹配文档的相关性分数。在组合来自多个查询的分数之前,对其进行归一化以使其处于同一尺度是有益的,如实验数据所示。有关分数归一化和组合的更多信息,包括基准测试和各种技术,请参阅这篇语义搜索博客文章。
先查询后获取
OpenSearch 支持两种搜索类型:query_then_fetch
和 dfs_query_then_fetch
。以下图表概述了先查询后获取(query-then-fetch)过程,其中包含了归一化处理器。
当你向一个节点发送搜索请求时,该节点成为一个协调节点。在搜索的第一阶段,即查询阶段,协调节点将搜索请求路由到索引中的所有分片,包括主分片和副本分片。然后,每个分片在本地运行搜索查询,并返回有关匹配文档的元数据,其中包括它们的文档 ID 和相关性分数。normalization-processor
接着对来自不同查询子句的分数进行归一化和组合。协调节点合并并排序本地结果列表,编译出一个与查询匹配的顶部文档的全局列表。之后,搜索执行进入获取阶段,在此阶段中,协调节点从文档所在的分片请求全局列表中的文档。每个分片将文档的 _source
返回给协调节点。最后,协调节点将包含结果的搜索响应发送给你。
请求正文字段
下表列出了所有可用的请求字段。
字段 | 数据类型 | 描述 |
---|---|---|
normalization.technique | 字符串 | 分数归一化的技术。有效值为 min_max 、l2 和 z_score 。可选。默认值为 min_max 。 |
normalization.parameters.lower_bounds | 对象数组 | 定义每个查询的下限值(最小阈值分数)。数组中对象的数量必须与查询的数量相同。可选。仅当归一化技术为 min_max 时适用。如果未提供,OpenSearch 不会对任何子查询应用下限,并使用检索结果中的实际最小分数进行归一化。 |
normalization.parameters.lower_bounds.mode | 字符串 | 指定下限如何应用于查询。有效值为 - apply : 使用 min_score 进行归一化,而不修改原始分数。公式:min_max_score = if (score < lowerBoundScore) then (score - minScore) / (maxScore - minScore) else (score - lowerBoundScore) / (maxScore - lowerBoundScore) 。- clip : 将低于下限的分数替换为 min_score 。公式:min_max_score = if (score < lowerBoundScore) then 0.0 else (score - lowerBoundScore) / (maxScore - lowerBoundScore) 。- ignore : 不对此查询应用下限,而是使用标准的 min_max 公式。可选。默认值为 apply 。 |
normalization.parameters.lower_bounds.min_score | 浮点型 | 下限阈值。有效值范围为 [-10000.0, 10000.0]。如果 mode 设置为 ignore ,则此值无效。可选。默认值为 0.0 。 |
combination.technique | 字符串 | 分数组合的技术。有效值为 arithmetic_mean 、geometric_mean 和 harmonic_mean 。可选。默认值为 arithmetic_mean 。z_score 仅支持 arithmetic_mean 。 |
combination.parameters.weights | 浮点值数组 | 指定每个查询的权重。有效值范围为 [0.0, 1.0],表示小数百分比。权重越接近 1.0,表示该查询的权重越大。weights 数组中的值数量必须等于查询的数量。数组中所有值的总和必须等于 1.0。可选。如果未提供,所有查询将获得相同的权重。 |
tag | 字符串 | 处理器的标识符。可选。 |
description | 字符串 | 处理器的描述。可选。 |
ignore_failure | 布尔型 | 对于此处理器,此值将被忽略。如果处理器失败,管道将始终失败并返回错误。 |
示例
以下示例演示了如何使用包含 normalization-processor
的搜索管道。
有关详细示例,请参阅语义和混合搜索入门。
创建搜索管道
以下请求创建了一个搜索管道,其中包含一个使用 min_max
归一化技术和 arithmetic_mean
组合技术的 normalization-processor
。该组合技术将第一个查询的权重分配为 30%,将第二个查询的权重分配为 70%。
PUT /_search/pipeline/nlp-search-pipeline
{
"description": "Post processor for hybrid search",
"phase_results_processors": [
{
"normalization-processor": {
"normalization": {
"technique": "min_max"
},
"combination": {
"technique": "arithmetic_mean",
"parameters": {
"weights": [
0.3,
0.7
]
}
}
}
}
]
}
以下示例演示了如何在 min_max
归一化技术中使用 lower_bounds
参数。它在组合技术中省略了 weights
参数,导致查询默认获得相同的权重。在此示例中,lower_bounds
参数用于为混合搜索中的每个查询设置不同的下限。对于第一个查询,应用了 0.5 的下限,而对于第二个查询,则忽略了下限。这允许在混合搜索中对每个独立查询的归一化过程进行微调。
PUT /_search/pipeline/nlp-search-pipeline
{
"description": "Post processor for hybrid search",
"phase_results_processors": [
{
"normalization-processor": {
"normalization": {
"technique": "min_max",
"parameters": {
"lower_bounds": [
{
"mode": "apply",
"min_score": 0.5
},
{
"mode": "ignore"
}
]
}
},
"combination": {
"technique": "arithmetic_mean"
}
}
}
]
}
使用搜索管道
在 hybrid
查询中提供你想要组合的查询子句,并应用上一节中创建的搜索管道,以便使用所选技术组合分数。
GET /my-nlp-index/_search?search_pipeline=nlp-search-pipeline
{
"_source": {
"exclude": [
"passage_embedding"
]
},
"query": {
"hybrid": {
"queries": [
{
"match": {
"text": {
"query": "horse"
}
}
},
{
"neural": {
"passage_embedding": {
"query_text": "wild west",
"model_id": "aVeif4oB5Vm0Tdw8zYO2",
"k": 5
}
}
}
]
}
}
}
有关设置混合搜索的更多信息,请参阅混合搜索。
搜索调优建议
为了提高搜索相关性,我们建议增加样本大小。
如果混合查询没有返回一些预期结果,可能是因为子查询返回的文档太少。normalization-processor
只转换每个子查询返回的结果;它不执行任何额外的采样。在我们的实验中,我们使用 nDCG@10 来衡量信息检索的质量,具体取决于返回的文档数量(即大小)。我们发现对于多达 10M 文档的数据集,大小在 [100, 200] 范围内效果最佳。我们不建议将大小增加到超出推荐值,因为更高的值不会提高搜索相关性,反而会增加搜索延迟。