检索与重排
在语义搜索中,我们展示了如何使用 SentenceTransformer 为查询、句子和段落计算嵌入,以及如何将其用于语义搜索。对于复杂的搜索任务,例如问答检索,使用**检索与重排** (Retrieve & Re-Rank) 可以显著改善搜索效果。
检索与重排流程
以下用于信息检索/问答检索的流程效果非常好。本文档提供并解释了所有组件。
给定一个搜索查询,我们首先使用一个**检索系统**来检索一个大的列表,例如100个可能与查询相关的命中结果。对于检索,我们可以使用词法搜索(例如,使用像Elasticsearch这样的向量引擎),或者我们可以使用带有SentenceTransformer
(又名单向编码器 bi-encoder)的密集检索。然而,检索系统可能会检索到与搜索查询不太相关的文档。因此,在第二阶段,我们使用一个基于CrossEncoder
的**重排器**来为给定的搜索查询对所有候选项的相关性进行评分。输出将是一个可以呈现给用户的命中结果的排序列表。
检索:双编码器(Bi-Encoder)
对于候选项集的检索,我们可以使用词法搜索(例如Elasticsearch),或者我们可以使用在Sentence Transformers中实现的双编码器。
词法搜索在您的文档集合中查找查询词的字面匹配。它无法识别同义词、缩写词或拼写变体。相比之下,语义搜索(或密集检索)将搜索查询编码到向量空间中,并检索在向量空间中相近的文档嵌入。
语义搜索克服了词法搜索的缺点,可以识别同义词和缩写词。请参阅语义搜索文章,了解实现语义搜索的不同选项。
重排器:交叉编码器(Cross-Encoder)
对于包含数百万条目的大型文档集合,检索器必须高效。然而,它可能会返回不相关的候选项。基于交叉编码器的重排器可以显著改善给用户的最终结果。查询和可能的文档被同时传递给Transformer网络,然后网络输出一个介于0和1之间的单一分数,表示该文档对于给定查询的相关性。
交叉编码器的优势在于其更高的性能,因为它们在查询和文档之间执行注意力机制。对成千上万或数百万个(查询,文档)对进行评分会相当慢。因此,我们使用检索器创建一个例如100个可能候选项的集合,然后由交叉编码器进行重排。
示例脚本
retrieve_rerank_simple_wikipedia.ipynb [ Colab 版本 ]:此脚本使用较小的简单英语维基百科作为文档集合,为用户问题/搜索查询提供答案。首先,我们将所有维基百科文章分割成段落,并用双编码器对它们进行编码。当输入新的查询/问题时,它由同一个双编码器编码,并检索具有最高余弦相似度的段落(见语义搜索)。接下来,由交叉编码器重排器对检索到的候选项进行评分,并将交叉编码器评分最高的5个段落呈现给用户。
in_document_search_crossencoder.py: 如果你只有一小部分段落,我们就不进行检索阶段。例如,当你想在单个文档内执行搜索时就是这种情况。在这个例子中,我们 lấy了关于欧洲的维基百科文章并将其分割成段落。然后,使用交叉编码器重排器对搜索查询/问题和所有段落进行评分。返回与查询最相关的段落。
预训练的双编码器(检索)
双编码器为您的段落和搜索查询独立生成嵌入。您可以像这样使用它
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("multi-qa-mpnet-base-dot-v1")
docs = [
"My first paragraph. That contains information",
"Python is a programming language.",
]
document_embeddings = model.encode(docs)
query = "What is Python?"
query_embedding = model.encode(query)
有关如何比较嵌入的更多细节,请参阅语义搜索。
我们提供基于以下数据的预训练模型
MS MARCO: 来自必应搜索引擎的50万个真实用户查询。请参阅MS MARCO 模型
预训练的交叉编码器(重排器)
对于预训练的交叉编码器模型,请参阅:MS MARCO 交叉编码器