Faiss(二)基础索引
参考链接:
Faiss入门及应用经验记录 - 知乎
Faiss indexes · facebookresearch/faiss Wiki · GitHub
Faiss提供了多种索引,本篇介绍一些基础索引。
Method | Class name | index_factory | Main param | Exhaustive | Comments |
精确搜索--L2 | IndexFlatL2 | "Flat" | d--向量维数 | 是 | 暴力搜索 |
精确搜索--内积(IP) | IndexFlatIP | "Flat" | d | 是 | 也可以将向量标准化后使用cosine相似度 |
Hierarchical Navigable Small World(HNSW)图搜索 | IndexHNSWFlat | "HNSWx,Flat" | d | 否 | x表示构建图索引时每个节点最多连接多少个节点 |
倒排索引(IVF) | IndexIVFFlat | "IVFx,Flat" | quantizer(量化器),d,nlists(聚类个数),metric(相似度度量) | 否 | x对应参数中的nlists,表示聚类个数 |
局部敏感哈希表(LSH) | IndexLSH | - | d,nbits | 是 | |
标量量化(SQ)(flat) | IndexScalarQuantizer | "SQx" | d | 是 | x表示编码位数,可以是4bits,6bits,8bits |
乘积量化(PQ)(flat) | IndexPQ |
"PQx", "PQ"x"x"nbits |
d,M,nbits | 是 | x对应参数中的M,表示将d维向量分成几个子向量,nbits表示用几个bit表示向量 |
IVF + SQ | IndexIVF-ScalarQuantizer |
"IVFx,SQ4" "IVFx,SQ8" |
quantizer.d. nlists,qtype |
否 | |
IVFADC(粗量化器+PQ残差) | IndexIVFPQ | "IVFx,PQ"y"x"nbits |
quantizer.d.nlists, M,nbits |
否 | |
IVFADC+R(与IVFADC相同,增加了重新排序-re-ranking) | IndexIVFPQR | "IVFx,PQy+z" |
quantizer.d. nlists,M,nbits, M_refine, nbits_refine |
否 |
|
(1)Flat---暴力检索
Flat indexes只是将向量编码为固定大小的代码,并将它们存储在ntotal * code_size字节数组中。
在搜索时,所有索引向量被顺序解码,并与查询向量进行比较。对于IndexPQ,比较是在压缩域中完成的,速度更快。
- 优点:该方法是Faiss所有index中最准确的,召回率最高的方法,没有之一;
- 缺点:速度慢,占内存大。
- 使用情况:向量候选集很少,在50万以内,并且内存不紧张。
代码示例:
param = 'Flat'
index = faiss.index_factory(dim, param, faiss.METRIC_L2)
index.is_trained # 输出为True
index.add(xb) # 向index中添加向量
(2)IVFx Flat---倒排暴力检索
采用一种像k-means的分区技术加快检索进程,但损失一定精确度。相应的算法有时被称为cell-probe方法。
- 优点:IVF主要利用倒排的思想,在文档检索场景下的倒排技术是指,一个kw后面挂上很多个包含该词的doc,由于kw数量远远小于doc,因此会大大减少了检索的时间。在向量中如何使用倒排呢?可以拿出每个聚类中心下的向量ID,每个中心ID后面挂上一堆非中心向量,每次查询向量的时候找到最近的几个中心ID,分别搜索这几个中心下的非中心向量。通过减小搜索范围,提升搜索效率。
- 缺点:速度也还不是很快。
- 使用情况:同Flat,
- 参数:IVFx中的x是k-means聚类中心的个数
代码示例:
param = 'IVF100, Flat' # 代表k-means聚类中心为100,
index = faiss.index_factory(dim, param, faiss.METRIC_L2 )
print(index.is_trained) # 此时输出为False,因为倒排索引需要训练k-means,
index.train(xb) # 因此需要先训练index,再add向量
index.add(xb)
(3)PQx---乘积量化
- 优点:利用乘积量化的方法,改进了普通检索,将一个向量的维度切成x段,每段分别进行检索,每段向量的检索结果取交集后得出最后的TopK。因此速度很快,而且占用内存较小,召回率也相对较高。
- 缺点:召回率相较于暴力检索,下降较多。
- 使用情况:内存及其稀缺,并且需要较快的检索速度,不那么在意召回率
- 参数:PQx中的x为将向量切分的段数,因此,x需要被向量维度整除,且x越大,切分越细致,时间复杂度越高;nbits表示用几个bit表示向量,只能取8,12,16。
代码示例:
param = 'PQ16'
index = faiss.index_factory(dim, param, faiss.METRIC_L2 )
print(index.is_trained) # 此时输出为False,因为倒排索引需要训练k-means,
index.train(xb) # 因此需要先训练index,再add向量
index.add(xb)
(4)IVFxPQy---倒排乘积量化
- 优点:工业界大量使用此方法,各项指标都均可以接受,利用乘积量化的方法,改进了IVF的k-means,将一个向量的维度切成x段,每段分别进行k-means再检索。
- 缺点:集百家之长,自然也集百家之短
- 使用情况:一般来说,各方面没啥特殊的极端要求的话,最推荐使用这种方法
- 参数:IVFx,PQy,其中的x和y同上
代码示例:
coarse_quantizer = faiss.IndexFlatL2 (d)
index = faiss.IndexIVFPQ (coarse_quantizer, d,ncentroids, code_size, 8)
index.nprobe = 5
(5)LSH---局部敏感哈希
- 原理:哈希对大家再熟悉不过,向量
- 也可以采用哈希来加速查找,我们这里说的哈希指的是局部敏感哈希(Locality Sensitive Hashing,LSH),不同于传统哈希尽量不产生碰撞,局部敏感哈希依赖碰撞来查找近邻。高维空间的两点若距离很近,那么设计一种哈希函数对这两点进行哈希值计算,使得他们哈希值有很大的概率是一样的,若两点之间的距离较远,他们哈希值相同的概率会很小。不同距离度量的哈希函数不同,不是所有距离度量(如内积)都能找到对应局部敏感哈希。摘自这篇文章。
- 优点:训练非常快,支持分批导入,index占内存很小,检索也比较快
- 缺点:召回率非常拉垮。在候选语料比较多的时候(亿级别),检索也不是特别快,大概是秒级别的。
- 使用情况:候选向量库非常大,离线检索,内存资源比较稀缺的情况
代码示例:
n_bits = 2 * d
lsh = faiss.IndexLSH (d, n_bits)
lsh.train (x_train)
lsh.add (x_base)
D, I = lsh.search (x_query, k)
(6)HNSWx
- 优点:该方法为基于图检索的改进方法,检索速度极快,10亿级别秒出检索结果,而且召回率几乎可以媲美Flat,能达到惊人的97%。检索的时间复杂度为loglogn,几乎可以无视候选向量的量级了。并且支持分批导入,极其适合线上任务,毫秒级别体验。
- 缺点:构建索引极慢,占用内存极大(是Faiss中最大的,大于原向量占用的内存大小)
- 参数:HNSWx中的x为构建图时每个点最多连接多少个节点,x越大,构图越复杂,查询越精确,当然构建index时间也就越慢,x取4~64中的任何一个整数。
- 使用情况:不在乎内存,并且有充裕的时间来构建index
- IndexHNSW支持的Flat索引有:
IndexHNSWFlat
(no encoding),IndexHNSWSQ
(scalar quantizer),IndexHNSWPQ
(product quantizer),IndexHNSW2Level
(two-level encoding).
代码示例:
param = 'HNSW64'
index = faiss.index_factory(dim, param, faiss.METRIC_L2 )
print(index.is_trained) # 此时输出为True
index.add(xb)
其中(1)(2)(3)(6)通过类构造器建立索引,(4)(5)通过index_factory建立索引,两种方式都可以。
Faiss(二)基础索引相关推荐
- 【Faiss】基础索引类型(六)
基础索引类型 数据准备 import numpy as np d = 512 #维数 n_data = 2000 np.random.seed(0) data = [] mu = 3 sigma = ...
- Lucene基础(二)--索引的操作
索引的操作 我们建立所有就是要达到快速检索的目的,对数据能够方面便的查找,和数据库类似,索引也有自己的相关增删改查的操作. 在索引的增删改查中,增删改属于写操作,主要是有IndexWrite提供的方 ...
- 下拉菜单实现树状结构_二叉索引树(树状数组)的原理
背景 了解到二叉索引树这个数据结构,是在 leetcode 的 307 题,题目是要求实现一个数据结构,可以返回数组任意区间的和以及更新数组的某个值. 307.Range Sum Query - Mu ...
- mysql 重复率高字段 索引_MySQL性能优化(二)索引优化
一.选择合适的列建立索引 1.在where从句,group by从句,order by从句,on从句中出现的列(select) 2.索引字段越小越好(表每页数据才会更多,IO效率会更高) 3.离散度大 ...
- 二叉索引树 -- 区间信息的维护与查询
二叉索引树,俗称树状数组,也叫Fenwick树. 例: 给定一个n个元素的数组A1, A2, A3, --, An, 设计一个数据结构,支持以下两种操作. 1.Add x y :让Ax ...
- kuangbin专题十二 基础DP
kuangbin专题十二 基础DP A - HDU1024 Max Sum Plus Plus B - HDU1029 Ignatius and the Princess IV C - HDU1069 ...
- 云计算设计模式(十二)——索引表模式
云计算设计模式(十二)--索引表模式 创建索引过的被查询条件经常被引用的数据存储等领域.这种模式可以通过允许应用程序更快速地定位数据来从数据存储中检索提高查询性能. 背景和问题 许多数据存储通过使用主 ...
- 什么是人们常用的计算机设备之一,计算机:复习二基础知识复习
<计算机:复习二基础知识复习>由会员分享,可在线阅读,更多相关<计算机:复习二基础知识复习(15页珍藏版)>请在人人文库网上搜索. 1.基础知识复习2,计算机系统,一.知识框图 ...
- 【Scheme】Scheme 编程学习 (二) —— 基础
[Scheme]Scheme 编程学习 (二) -- 基础 文接前一节内容 : [Scheme]Scheme 编程学习(一) -- 概述 本文章可以跟视频课程一起看,做了一些补充说明 原视频地址: B ...
最新文章
- 在word中插入目录
- re匹配正则字符串中的起始和结束元字符的使用方法
- 牛客网题目——不用四则运算符号,计算两个数字的和
- 再见了Python,Tableau数分工具确实牛逼!
- 为您的IIS6下的网站配置Rewrite伪静态组件
- 使用python turtle库绘制一个三角形和一个五角星_使用turtle库绘制一个五角星 如何采用Python语言绘制一个五角星...
- 你不知道的js——数组 join
- RubyOnRails杂记
- PQ分区工具超详细图文教程
- 【转】Xposed+JustTrustMe关闭SSL证书验证解决无法抓取https包问题
- POP3 SMTP 协议分析
- 个人技术博客的选择:CSDN、博客园、简书、知乎专栏、Github、新浪、个人建站等?
- 带宽与码元的关系_带宽和传输速率的关系是什么?
- aliases节点分析
- Mysql 新建用户并且授权用户的访问数据库权限以及可以对数据的操作类型
- 苹果吃鸡蓝牙耳机推荐
- 率土之滨服务器进备战区维护多久,率土之滨备战区维护,备战区为什么不拆战法...
- boost库在工作(25)任务之五
- 深度学习中参数量与计算量的理解
- U盘中毒之后打不开怎么办
热门文章
- win10安装sshpass_系统运维|sshpass:一个很棒的免交互 SSH 登录工具,但不要用在生产服务器上...
- 产品思考之:2B or 2C
- 【unity】ps动画转为单帧图片
- Linux操作系统实用功能,简单易操作 头歌实验一
- python 词表里的词不符合_教你背单词 | 利用python分析考研英语阅读并生成词频降序表...
- Unity3D 脚本3(旋转)
- selenium解决验证码的方法
- CString 中Releasebuffer GetBuffer 相关实现原理
- android 自定义时钟,Android自定义控件之圆形时钟(续)
- FLUENT+MESH计算扩散管内旋转湍流流动