Pinecone支持将稀疏向量和密集向量结合使用,让可以在同一查询中执行语义搜索和关键字搜索,从而提高搜索结果的相关性。本文主要介绍有关Pinecone中稀疏-密集(sparse-dense)向量的工作原理的详细介绍。
一、稀疏-密集向量优势
使用Pinecone的稀疏-密集(sparse-dense)向量,可以实现关键词感知的语义搜索。这种方法对于涉及不同领域的查询尤其有效,因为它可以结合语义搜索和关键字搜索的优点,从而提高搜索结果的相关性。
Pinecone允许创建自己的稀疏向量,让可以使用稀疏-密集(sparse-dense)查询解决各种实际问题,例如基于SPLADE的文本检索新用例。
二、稀疏-密集工作流程
使用稀疏-密集(sparse-dense)向量的一般步骤如下:
1、使用外部嵌入模型生成密集向量。
2、使用外部模型生成稀疏向量。
3、创建支持稀疏-密集(sparse-dense)向量的索引(选择s1或p1索引,并使用点积(dotproduct)度量)。
4、将密集向量和稀疏向量插入索引。
5、使用稀疏-密集(sparse-dense)向量对索引进行搜索。
3、Pinecone将返回稀疏-密集(sparse-dense)向量的搜索结果。
三、Pinecone稀疏向量和密集向量
在Pinecone中,稠密向量和稀疏向量可以作为单一向量进行嵌入。密集向量用于语义搜索,能够根据语义距离返回最相似的结果,而稀疏向量则用于关键字搜索,每个稀疏向量表示一个文档,其中维度对应于字典中的单词,值表示这些单词在文档中的重要性。
1、创建稀疏向量嵌入
稀疏向量的生成可以通过文档向量表示来实现。Pinecone索引接受的是稀疏向量,而不是原始文档。可以通过控制生成稀疏向量的方式来优化文档表示。有关稀疏向量生成的示例,请参考SPLADE生成笔记本和BM25生成笔记本。
注意: Pinecone支持最多1000个非零值的稀疏向量。
2、在Pinecone中处理稀疏-密集向量
在Pinecone中,每个向量由密集向量和可选的稀疏向量组成。Pinecone不支持仅具有稀疏值的向量。p1和s1索引使用“点积”(dotproduct)距离度量支持稀疏-密集(sparse-dense)向量。请注意,2023年2月22日之前创建的索引不支持稀疏值。
四、稀疏-密集查询
要查询稀疏-密集(sparse-dense)向量,需要提供一个包含稀疏和密集值的查询向量。Pinecone通过对整个向量的点积进行计算,考虑密集值和稀疏值的组合来对索引中的向量进行排名。得分是密集值与查询的密集部分点积和稀疏值与查询的稀疏部分点积之和。
1、稀疏-密集向量格式
Pinecone将稀疏值表示为两个数组的字典:indices和values。可以将这些值插入到一个向量参数中,以创建稀疏-密集(sparse-dense)向量。
示例:
插入具有稀疏和密集值的向量:
import pinecone index = pinecone.Index('example-index') upsert_response = index.upsert( vectors=[ {'id': 'vec1', 'values': [0.1, 0.2, 0.3], 'metadata': {'genre': 'drama'}, 'sparse_values': { 'indices': [10, 45, 16], 'values': [0.5, 0.5, 0.2] }}, {'id': 'vec2', 'values': [0.2, 0.3, 0.4], 'metadata': {'genre': 'action'}, 'sparse_values': { 'indices': [15, 40, 11], 'values': [0.4, 0.5, 0.2] }} ], namespace='example-namespace' )
使用稀疏-密集(sparse-dense)向量查询索引:
query_response = index.query( namespace="example-namespace", top_k=10, vector=[0.1, 0.2, 0.3], sparse_vector={ 'indices': [10, 45, 16], 'values': [0.5, 0.5, 0.2] } )
五、稀疏-密集查询的显式加权
由于Pinecone将稀疏-密集(sparse-dense)向量视为一个整体,索引不提供用于调整密集部分与稀疏部分权重的内置参数。可以通过自定义查询向量来实现线性加权方案,如下所示:
def hybrid_score_norm(dense, sparse, alpha: float): """Hybrid score using a convex combination alpha * dense + (1 - alpha) * sparse Args: dense: Array of floats representing dense vector sparse: a dict of `indices` and `values` representing sparse vector alpha: scale between 0 and 1 """ if alpha < 0 or alpha > 1: raise ValueError("Alpha must be between 0 and 1") hs = { 'indices': sparse['indices'], 'values': [v * (1 - alpha) for v in sparse['values']] } return [v * alpha for v in dense], hs # 使用该函数转换向量 sparse_vector = { 'indices': [10, 45, 16], 'values': [0.5, 0.5, 0.2] } dense_vector = [0.1, 0.2, 0.3] hdense, hsparse = hybrid_score_norm(dense_vector, sparse_vector, alpha=0.75) query_response = index.query( namespace="example-namespace", top_k=10, vector=hdense, sparse_vector=hsparse )
通过这些步骤,可以有效地使用Pinecone的稀疏-密集(sparse-dense)向量进行更高效的搜索和数据检索。