我想存储一个n维特征向量,例如, <1.00, 0.34, 0.22, ..., 0>
,与每个文档一起,然后提供另一个特征向量作为查询,结果按余弦相似度的顺序排序。这是否可以使用弹性搜索?
答案 0 :(得分:6)
我没有特别针对弹性搜索的答案,因为我从未使用它(我使用的是构建弹性搜索的Lucene)。但是,我试图给出你的问题的通用答案。 给定查询向量有两种标准方法可以获得最近的向量,如下所述。
K-d树
第一种方法是借助于支持最近邻居查询的数据结构将向量存储在存储器中,例如, k-d trees 。 k-d tree是二叉搜索树的一般化,在某种意义上,二元搜索树的每个级别将 k 维度之一划分为两个部分。如果您有足够的空间来加载内存中的所有点,则可以在k-d树上应用nearest neighbour search algorithm以获取按余弦相似度值排序的检索向量列表。这种方法的明显缺点是它不能扩展到大量的点,就像在信息检索中经常遇到的那样。
反向量化向量
第二种方法是使用反向量化矢量。一个简单的基于范围的量化将伪术语或标签分配给一个向量的实数,以便以后可以通过Lucene对其进行索引(或者就此问题进行弹性搜索) )。
例如,我们可以将标签 A 分配到范围 [0,0.1), B 到范围 [ 0.1,0.2)等等...然后问题中的样本向量被编码为(J,D,C,.. A)。 (因为[.9,1]是J,[0.3,0.4]是D,依此类推)。
因此,实数的向量因此被转换为字符串(可以被视为文档)并因此用标准信息检索(IR)工具索引。查询向量也被转换为一组伪项,因此可以计算集合中与当前集合最相似(在余弦相似度或其他度量方面)的一组其他类似向量。
这种方法的主要优点是它可以很好地扩展到实际编号矢量的大量收集。关键的缺点是计算出的相似度值仅仅是真正的余弦相似度的近似值(由于量化中遇到的损失)。较小的量化范围以增加的索引大小为代价实现了更好的性能。
答案 1 :(得分:0)
elasticsearch的7.4版实际上具有内置的矢量比较功能,包括余弦相似度。参见:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-dsl-script-score-query.html#vector-functions。