← 返回博客
跳至主要内容

解锁混合搜索的力量 - Weaviate 的融合算法深度解析

·11 分钟阅读
Dirk Kulawiak
Joon-Pil (JP) Hwang

Hybrid search hero image - shows a combination of results from vector and keyword search

重点
  • Weaviate 中有两种融合算法可用:rankedFusionrelativeScoreFusion
  • rankedFusion 一直是默认算法,直到 1.24 版本。
  • relativeScoreFusion 是较新的算法,于 1.20 版本引入,并在 1.24 版本中成为默认算法,并且可能是大多数情况下的更好选择。
  • 我们非常希望收到您对混合搜索的反馈。请填写 此简短调查

如您所知,Weaviate 可以执行多种不同类型的搜索,包括向量搜索和关键词搜索。向量搜索基于输入含义的相似性,而关键词搜索基于输入词语在结果中出现的频率。

基于向量和关键词的搜索各有其优缺点,这些优缺点源于这种差异,其中向量搜索在语义上更宽容,而关键词搜索更精确。混合搜索使用这两种搜索类型,从而实现“两全其美”的能力。

这可能听起来很简单。但是,您知道 混合搜索如何 组合这些结果吗?以及 Weaviate 最近是否添加了一种新的算法来执行此操作?

在这篇文章中,我们将深入探讨混合搜索的世界,讨论其工作原理、结果生成方式、使用的算法等等。让我们开始吧!

信息
  • 向量搜索和关键词搜索也分别被称为稠密向量搜索和稀疏向量搜索。
  • 关键词搜索在 Weaviate 中也称为 BM25 搜索,因为它基于 BM25F 评分算法。

混合搜索究竟是如何工作的?

Hybrid search main image - a figurative image of Weaviate bot combining results from vector and keyword search to produce hybrid search

这是一个混合搜索的例子

response = (
client.query
.get("JeopardyQuestion", ["question", "answer"])
.with_hybrid(query="food", alpha=0.5)
.with_limit(5)
.do()
)

如前所述,混合搜索实际上是在底层执行两种搜索。它执行向量搜索(类似于 Weaviate 中的 nearTextnearVector)以找到与查询向量最相似的对象。与此同时,它还执行关键词搜索,根据查询词在结果中出现的频率对结果进行排名。

换句话说,混合搜索执行这两种搜索并将结果组合起来。

response = (
client.query
.get("JeopardyQuestion", ["question", "answer"])
.with_near_text({"concepts": ["food"]})
.with_limit(5)
.do()
)

这些搜索中的每一个都会产生类似以下的結果

{
"data": {
"Get": {
"JeopardyQuestion": [
{
"answer": "a closer grocer",
"question": "A nearer food merchant"
},
{
"answer": "Famine",
"question": "From the Latin for \"hunger\", it's a period when food is extremely scarce"
},
{
"answer": "Tofu",
"question": "A popular health food, this soybean curd is used to make a variety of dishes & an ice cream substitute"
},
{
"answer": "gastronomy",
"question": "This word for the art & science of good eating goes back to Greek for \"belly\""
},
{
"answer": "devour flour",
"question": "Voraciously eat an \"all-purpose\" baking ingredient"
}
]
}
}
}

如上例所示,向量搜索和关键词搜索产生的結果对象顺序不同,甚至对象本身也可能不同。如果您检查我们的等效混合查询的结果,您会注意到来自 vectorkeyword 搜索的结果。

{
"data": {
"Get": {
"JeopardyQuestion": [
{
"answer": "a closer grocer",
"question": "A nearer food merchant"
},
{
"answer": "food stores (supermarkets)",
"question": "This type of retail store sells more shampoo & makeup than any other"
},
{
"answer": "cake",
"question": "Devil's food & angel food are types of this dessert"
},
{
"answer": "Famine",
"question": "From the Latin for \"hunger\", it's a period when food is extremely scarce"
},
{
"answer": "Tofu",
"question": "A popular health food, this soybean curd is used to make a variety of dishes & an ice cream substitute"
}
]
}
}
}

那么,它们是如何到达那里的?

简而言之,Weaviate 为每个对象计算一个加权分数,使用两个结果集。但鉴于这两种搜索类型非常不同,我们如何组合来自每个搜索的数值输出?由于这两种搜索类型产生不同的指标,这并非易事。在某种程度上,这是关键所在,因此这里的实现是混合搜索故事的重要组成部分。

加权分数

混合搜索可以“加权”,以赋予向量搜索或关键词搜索更大的权重。这使用 alpha 参数完成。您可以在 此处 了解更多信息。

融合算法

Hybrid relativeScoreFusion algorithm depicted as two judges holding up two scores Hybrid relativeScoreFusion algorithm depicted as two judges holding up two scores

这两个搜索(向量和关键词)中的每一个都会返回包含其自身分数的結果集。然后,这些分数会交给选定的融合算法。融合算法的任务是准备来自每个搜索的分数,使其相互兼容,以便可以对其进行加权和相加,并呈现给用户。

截至 1.20,有两种算法可用 - 一种称为 rankedFusion(默认值直到 1.24),另一种称为 relativeScoreFusion,从 1.24 开始成为默认值。

rankedFusion

rankedFusion 算法是 Weaviate 中混合搜索启动以来一直可用的原始混合融合算法。

在此算法中,每个对象根据其在给定搜索的结果中的位置进行评分,从排名最高的对象的最高分开始,并按顺序递减。总分是通过将来自向量和关键词搜索的基于排名的分数相加来计算的。

现在,让我们来看看更新的 relativeScoreFusion 算法。

relativeScoreFusion

relativeScoreFusion 算法是在 Weaviate 1.20 版本中添加的。

然而,与 rankedFusion 相比,relativeScoreFusion 通过标准化向量搜索和关键词搜索分别输出的指标来得出每个对象的得分。最高值变为 1,最低值变为 0,其他值根据此比例介于两者之间。因此,总分是通过缩放的向量相似度和标准化 BM25 分数的总和来计算的。

完整示例

在回顾每个算法之后,让我们通过一个完整的示例来演示它们之间的区别。

基本搜索结果

假设搜索返回 五个对象,具有 文档 ID(从 0 到 4),以及 关键词向量搜索分数按分数排序

搜索类型(id): 分数(id): 分数(id): 分数(id): 分数(id): 分数
关键词(1): 5(0): 2.6(2): 2.3(4): 0.2(3): 0.09
向量(2): 0.6(4): 0.598(0): 0.596(1): 0.594(3): 0.009

排名融合

分数取决于每个结果的排名,并根据 1/(RANK + 60) 计算,结果如下

搜索类型(id): 分数(id): 分数(id): 分数(id): 分数(id): 分数
关键词(1): 0.0154(0): 0.0160(2): 0.0161(4): 0.0167(3): 0.0166
向量(2): 0.016502(4): 0.016502(0): 0.016503(1): 0.016503(3): 0.016666

如您所见,无论输入分数如何,每个排名的结果都是相同的。

相对分数融合

在这里,我们标准化分数 - 将最大分数设置为 1,将最低分数设置为 0,所有介于两者之间的条目都根据其与 最大值最小值相对距离 进行缩放。

搜索类型(id): 分数(id): 分数(id): 分数(id): 分数(id): 分数
关键词(1): 1.0(0): 0.511(2): 0.450(4): 0.022(3): 0.0
向量(2): 1.0(4): 0.996(0): 0.993(1): 0.986(3): 0.0

在这里,分数反映了原始分数的相对分布。例如,向量搜索的前 4 个文档的分数几乎相同,这在标准化分数中仍然如此。

总结

在加权这些分数之前,它们会根据 alpha 参数进行加权。假设 alpha=0.5,这意味着两种搜索类型对最终结果的贡献相等,因此每个分数都乘以 0.5。

现在,我们可以将每个文档的分数相加并比较来自两种融合算法的结果。

算法类型(id): 分数(id): 分数(id): 分数(id): 分数(id): 分数
排名(2): 0.016301(1): 0.015952(0): 0.015952(4): 0.016600(3): 0.016630
相对(1): 0.993(0): 0.752(2): 0.725(4): 0.509(3): 0.0

我们能从这中学到什么?

对于向量搜索,前 4 个对象(ID 2、4、0、1)的分数几乎相同,并且它们都是好的结果。对于关键词搜索,一个对象(ID 1)比其他对象好得多。

这体现在最终的relativeScoreFusion结果中,该结果将对象ID 1识别为最佳结果。这是合理的,因为该文档在关键词搜索中表现最佳,与次优结果的得分差距很大,并且在向量搜索的顶级分组中。

相比之下,对于rankedFusion,对象ID 2是最佳结果,紧随其后的是对象ID 1ID 0

应该使用哪个?

现在你已经更多地了解了这两种算法,你可能想知道这个关键问题:应该使用哪个,以及何时使用?通常,我们认为relativeScoreFusion可能是一个不错的选择。

主要原因是relativeScoreFusion保留了来自原始搜索的更多信息,而rankedFusion仅保留了排名。更普遍地说,我们认为向量和关键词搜索指标中捕获的细微差别更有可能反映在相对分数融合产生的排名中。

关于这两点的补充说明

召回性能/基准测试

在开发这两种算法时,我们进行了一些内部基准测试,以测试标准(FIQA)数据集上的召回率。根据我们的内部基准测试,默认的relativeScoreFusion算法在召回率方面比rankedFusion方法提高了约6%。

这是一项非常显著的改进。因此,如果没有数据集的特定特征或需要保留与先前搜索的向后兼容性,relativeScoreFusion可能是一个不错的选择。

与 AutoCut 结合使用

1.20版本中,我们引入了AutoCut功能,它可以智能地从搜索中检索对象组。AutoCut依赖于存在自然的“集群”(具有接近分数的对象组)。

AutoCut与relativeScoreFusion配合使用效果很好,后者通常会产生AutoCut可以检测到的自然集群。

为什么选择默认?

v1.24起,默认方法是相对分数融合

鉴于我们之前的解释,你可能想知道为什么rankedFusion是默认算法。事实上,我们目前认为relativeScoreFusion更有可能成为表现更好的算法。

答案是rankedFusion是更早、更可靠的选择,并且运行良好。与此同时,我们一直在评估社区对relativeScoreFusion的反馈,并进行了一些小的调整,例如添加超搜索以使其更加健壮。

到目前为止,反应是积极的。但我们仍然处于评估阶段,并且非常希望收到来自我们用户的更多反馈。我们准备了这份简短的调查问卷。我们非常感谢你的意见。请告诉我们你的想法!

总结

Weaviate中的混合搜索融合了向量和关键词搜索的强大功能,利用两者的优势来提供语义丰富的搜索结果,同时尊重关键词搜索的精确性。

正如我们所探讨的,relativeScoreFusion的引入扩展了Weaviate的混合搜索能力,该能力最初始于rankedFusion算法。我们邀请你深入研究,尝试这些融合算法,并分享你的经验。

更多资源

准备开始构建了吗?

请查看 快速入门教程,或使用 Weaviate Cloud (WCD) 的免费试用版构建令人惊叹的应用程序。

不想错过另一篇博文?

注册我们的双周时事通讯以保持更新!


提交后,我同意 服务条款 隐私政策.