【发布时间】:2015-07-25 10:46:50
【问题描述】:
我想存储一个 n 维特征向量,例如<1.00, 0.34, 0.22, ..., 0>,每个文档,然后提供另一个特征向量作为查询,结果按余弦相似度排序。使用 Elastic Search 可以做到这一点吗?
【问题讨论】:
标签: elasticsearch information-retrieval feature-extraction
我想存储一个 n 维特征向量,例如<1.00, 0.34, 0.22, ..., 0>,每个文档,然后提供另一个特征向量作为查询,结果按余弦相似度排序。使用 Elastic Search 可以做到这一点吗?
【问题讨论】:
标签: elasticsearch information-retrieval feature-extraction
我没有专门针对 Elastic Search 的答案,因为我从未使用过它(我使用的是构建 Elastic 搜索的 Lucene)。但是,我试图对您的问题给出一个通用的答案。 在给定查询向量的情况下,有两种标准方法可以获取最近的向量,如下所述。
K-d 树
第一种方法是借助支持最近邻查询的数据结构将向量存储在内存中,例如k-d 树。 k-d tree 是二叉搜索树的概括,因为二叉搜索树的每一层都将 k 维中的一个划分为两部分。如果您有足够的空间来加载内存中的所有点,则可以在 k-d 树上应用 nearest neighbour search algorithm 以获得按余弦相似度值排序的检索向量列表。这种方法的明显缺点是它不能扩展到信息检索中经常遇到的大量点集。
反向量化向量
第二种方法是使用反向量化向量。一个简单的基于范围的量化将 pseudo-terms 或 labels 分配给向量的实数,以便以后可以通过 Lucene(或就此而言,弹性搜索)。
例如,我们可以将标签A分配给范围[0, 0.1),B分配给范围[ 0.1, 0.2) 等等...然后将您问题中的样本向量编码为 (J,D,C,..A)。 (因为 [.9,1] 是 J,[0.3,0.4) 是 D 等等)。
因此,实数向量因此被转换为字符串(可以被视为文档),因此可以使用标准信息检索 (IR) 工具进行索引。查询向量也被转换成一袋伪词,因此可以计算集合中与当前向量最相似(在余弦相似度或其他度量方面)的一组其他相似向量。
这种方法的主要优点是它可以很好地扩展大量实数向量的集合。主要缺点是计算出的相似度值仅仅是对真实余弦相似度的近似值(由于量化中遇到的损失)。较小的量化范围以增加索引大小为代价实现更好的性能。
【讨论】:
elasticsearch 7.4 版本实际上内置了向量比较函数,包括余弦相似度。请参阅:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-dsl-script-score-query.html#vector-functions。
【讨论】: