大规模向量检索方法

大规模向量检索通常的做法有两类,第一、通过构建索引,快速筛选和查询向量相关度较高的目标向量或快速过滤和查询向量相关度不大的非目标向量;第二、通过降维的方法,对高维向量先降维再检索。前者主要解决向量检索库数据过大的问题,常见的有二叉搜索树、KD树、B-tree、quad-tree等;后者主要为了解决向量维度过高的问题,常见的有LSH【local sensitive hashing 局部敏感哈希】算法等。

KD树原理

KD树,全称k-dimensions tree,原理就是对多维欧式空间进行分割后构造的二叉树。搜索阶段,依据非叶子节点中存储的分割维度以及中位数信息,自根节点开始,从上往下搜索,直到到达叶子节点。

详细步骤可以参考:Kd-tree原理与实现

局部敏感性哈希(LSH,Locality-sensitive-hashing)

核心思想:找到一个hash函数,希望原始数据空间相近的向量通过hash函数运算后,得到的签名一致【或者二进制表示下汉明距离很小】,不相邻的向量得到的签名不一致。

汉明距离定义:就是一组二进制数据变成另一组数据所需要的步骤数,显然这个数值可以衡量两张图片的差异,汉明距离越小,则代表相似度越高。假如,两组二进制数据分别为101和111,只需要将第二位数据变换下即可,所以两组数据的汉明距离就是1。

常见的LSH算法:

  • 随机超平面投影

在欧式空间,将高维空间投影到低维空间,距离相近的高维向量映射后,在低维空间仍然相近。

假设原始向量维度为k,经过如下公式计算:

通过这个计算,将原始的向量变成一个bit,实际应用中,为了有更好的召回率,会根据数据规模选择b个投影向量。在线使用时,将query经过同样变化,变换后的b维向量和向量库的向量如果一样,那么可以认为和原始的k维向量很相似。 

  • Simhash

simhash被用在google网页去重中,过程如下:

  1. 首先对原始的数据提前关键特征和特征对应的权重,在网页中特征就是关键词,权重就是tf-idf;
  2. 利用一个签名函数对一个原始数据的所有特征计算,得到二进制签名,这个签名函数就是一个普通的hash函数,比如crc16;
  3. 所有的特征签名逐位求差或和,若签名位是0则减去这个特征的权重,当签名位是1则加上这个特征的权重,最终得到一个和签名位数一样的一维向量;
  4. 将上步得到的向量转化为二进制,若向量某一维大于0,则最终二进制对应的bit为1,小于0对应的比特位为0

LSH可以做到无监督构建索引,无需重训练索引,可以做到在线实时添加。在线查询只需要简单的哈希查表,效率非常高。但是LSH在向量投影过程中,会存在信息损失,导致召回率下降。

近邻图算法

近邻图搜索在搜索前先需要构建一个近邻搜索图,其中最常用的有NSW和升级版HNSW算法,NSW图示如下:

在NSW近邻图中,有两种边:

  1. short-link。用于搜索最近向量
  2. long-link。在搜索初期提高搜索效率

NSW的构图过程

  1. 每次在图中插入节点v都寻找k个最近的节点x,让v和x之间产生边
  2. 插入时产生的边为为short-link
  3. 随着新的距离更近的节点逐渐加入,可能以前的short-link不再是距离最近的k个,这个时候short-link变成了long-link

HNSW算法,可参考:一文看懂HNSW算法理论的来龙去脉

乘积量化

乘积量化的核心思想是通过空间切分,将高维的向量通过预处理压缩到低维度,比较有代表性的有PQ算法,PQ和倒排索引结合的IVFPQ。

1.IPQ算法

PQ算法过程可以用下图解释

假设有N个1280维的向量,具体过程如下

  1. 选定一个向量分段数K,假设为10,那么每一段的维度就为1280/10=128
  2. 对原始的N个向量每128位分为一组,那么一共有10组,每组有N个向量
  3. 对10组的向量分别进行聚类,假设聚类的个数是256个,每个类的中心称为积中心,对每一组的积中心打上依次打上编号0~255
  4. 对于一个向量每一段128维来说,和这组的那个积中心距离最近,就把这段用这个积中心编号表示,这样原始每个向量就被表示为一个10位的向量,每位取值0~255

对所有的乘积向量,对一个新的查询向量q来说,查询过程如下:

  1. 将这个查询向量通过上边的分段算法转成10端128维向量
  2. 每一段和这个段的256个积中心算出距离,会得到一个10*256的矩阵M
  3. 对于索引库的一个向量v,假设其量化向量为[255,1,210,……](10个元素)对于第i个元素值为j,可以认为第i段与q的距离为Mij(ij为矩阵M索引),比如对于第一个元素255可以认为距离是M的第0行第255列的值
  4. 将10个段经过步骤3查询的10个距离求和得到s,可以认为s是vq的距离,从所有的向量距离中找出距离最近的k为查询结果

从上边的查询过程可以看出PQ的查询过程时间复杂度为O(M*K),当需要检索的向量数目变多时检索效率无法得到保证。针对PQ算法检索慢的问题,针对性将倒排索引和PQ结合起来,提出了新的IVFPQ

 2.IVFPQ算法

IVFPQ主要的改进思路如下:

  1. 预先对这N个向量聚类(原始向量上聚类),假设聚类数量为1000,那么每一个向量会归入自己所在的这个类
  2. 对每一聚类的向量进行PQ量化
  3. 在线查询来了先和每一类的中心比较,挑选距离较近的m个类,m至少为1,m越大速度越慢但是召回越高
  4. 从这个m个类中进行上边PQ查询

IVFPQ还可以进行优化,对每一聚类的向量进行PQ量化时,不再用原始向量,而是用原始向量减去这个聚类中心向量的残差进行计算,这样的召回率会更高。

乘积量化算法召回率很高,在工业界用的较多,但是量化算法也有较多缺点,如下:

  1. 首先要对原始向量进行聚类,没法做到从0开始插入数据
  2. 聚类后加入的向量若发生离群(离任何类中心都较远或者距离差不多),那么这些向量的召回会很低
  3. 量化因为主要原理是通过聚类将考得近的向量降维,所以如果原始向量分布很均匀,那么聚类效果很差所以最终的召回率很低

针对PQ量化算法,还有很多改进版本,这里不做具体阐述。虽然向量检索算法层出不穷,但是面对着工业界,超大规模的数据,要满足低延迟、低成本的进行向量搜索,依然会有很多挑战【13】

常见的向量检索库

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NLP_wendi

谢谢您的支持。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值