IndexFlatL2、IndexIVFFlat、IndexIVFPQ三种索引方式示例
上文针对Faiss安装和一些原理做了简单说明,本文针对标题所列三种索引方式进行编码验证。
首先生成数据集,这里采用100万条数据,每条50维,生成数据做本地化保存,代码如下:
import numpy as np # 构造数据
import time
d = 50 # dimension
nb = 1000000 # database size
# nq = 1000000 # nb of queries
np.random.seed(1234) # make reproducible
xb = np.random.random((nb, d)).astype('float32')
xb[:, 0] += np.arange(nb) / 1000.
# xq = np.random.random((nq, d)).astype('float32')
# xq[:, 0] += np.arange(nq) / 1000. print(xb[:1]) # 写入文件中
# file = open('data.txt', 'w')
np.savetxt('data.txt', xb)
在上述训练集的基础上,做自身查询,即本身即是Faiss的训练集也是查寻集,三个索引的查询方式在一个文件内,如下示例代码:
import numpy as np
import faiss # 读取文件形成numpy矩阵
data = []
with open('data.txt', 'rb') as f:
for line in f:
temp = line.split()
data.append(temp)
print(data[0])
# 训练与需要计算的数据
dataArray = np.array(data).astype('float32') # print(dataArray[0])
# print(dataArray.shape[1])
# 获取数据的维度
d = dataArray.shape[1] # IndexFlatL2索引方式
# # 为向量集构建IndexFlatL2索引,它是最简单的索引类型,只执行强力L2距离搜索
# index = faiss.IndexFlatL2(d) # build the index
# index.add(dataArray) # add vectors to the index
#
# # we want to see 4 nearest neighbors
# k = 11
# # search
# D, I = index.search(dataArray, k)
#
# # neighbors of the 5 first queries
# print(I[:5]) # IndexIVFFlat索引方式
# nlist = 100 # 单元格数
# k = 11
# quantizer = faiss.IndexFlatL2(d) # the other index d是向量维度
# index = faiss.IndexIVFFlat(quantizer, d, nlist, faiss.METRIC_L2)
# # here we specify METRIC_L2, by default it performs inner-product search
#
# assert not index.is_trained
# index.train(dataArray)
# assert index.is_trained
# index.add(dataArray) # add may be a bit slower as well
# index.nprobe = 10 # 执行搜索访问的单元格数(nlist以外) # default nprobe is 1, try a few more
# D, I = index.search(dataArray, k) # actual search
#
# print(I[:5]) # neighbors of the 5 last queries # IndexIVFPQ索引方式
nlist = 100
m = 5
k = 11
quantizer = faiss.IndexFlatL2(d) # this remains the same
# 为了扩展到非常大的数据集,Faiss提供了基于产品量化器的有损压缩来压缩存储的向量的变体。压缩的方法基于乘积量化。
# 损失了一定精度为代价, 自身距离也不为0, 这是由于有损压缩。
index = faiss.IndexIVFPQ(quantizer, d, nlist, m, 8)
# 8 specifies that each sub-vector is encoded as 8 bits
index.train(dataArray)
index.add(dataArray)
# D, I = index.search(xb[:5], k) # sanity check
# print(I)
# print(D)
index.nprobe = 10 # make comparable with experiment above
D, I = index.search(dataArray, k) # search
print(I[:5])
三种索引的结果和运行时长统计如下图所示:

从上述结果可以看出,加聚类后运行速度比暴力搜索提升很多,结果准确度也基本一致,加聚类加量化运行速度更快,结果相比暴力搜索差距较大,在数据量不是很大、维度不高的情况下,建议选择加聚类的索引方式即可。
IndexFlatL2、IndexIVFFlat、IndexIVFPQ三种索引方式示例的更多相关文章
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 SignalR 简单示例 通过三个DEMO学会SignalR的三种实现方式 SignalR推送框架两个项目永久连接通讯使用 SignalR 集线器简单实例2 用SignalR创建实时永久长连接异步网络应用程序
SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 异常汇总:http://www ...
- 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)
摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...
- 通过三个DEMO学会SignalR的三种实现方式
一.理解SignalR ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息 ...
- js的三种继承方式及其优缺点
[转] 第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = ' ...
- Asp.Net中的三种分页方式
Asp.Net中的三种分页方式 通常分页有3种方法,分别是asp.net自带的数据显示空间如GridView等自带的分页,第三方分页控件如aspnetpager,存储过程分页等. 第一种:使用Grid ...
- 瀑布流的三种实现方式(原生js+jquery+css3)
前言 项目需求要弄个瀑布流的页面,用的是waterfall这个插件,感觉还是可以的,项目赶就没自己的动手写.最近闲来没事,就自己写个.大致思路理清楚,还是挺好实现的... 原生javascript版 ...
- Linq to Sql : 三种事务处理方式
原文:Linq to Sql : 三种事务处理方式 Linq to SQL支持三种事务处理模型:显式本地事务.显式可分发事务.隐式事务.(from MSDN: 事务 (LINQ to SQL)).M ...
- Android平台中实现对XML的三种解析方式
本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...
- C# 三种打印方式含代码
一:C#代码直接打印pdf文件(打印质保书pdf文件) 引用: 代码注释很详细了. private void btn_pdf_Click(object sender, RoutedEventArgs ...
随机推荐
- mysql练习题99
一.查询每个专业的学生人数 SELECT COUNT(*) FROM student GROUP BY majorid; 二.查询参加考试的学生中,每个学生的平均分.最高分 SELECT avg(sc ...
- Burp Suite Sequencer Modules - 定序器模块
Sequencer 主要用于处理和分析Tokens 目标网站:http://testaspnet.vulnweb.com/ (1)通过代理,拦截数据流. (2)Send to Sequencer,然后 ...
- C++算法 广搜
有一个同学推荐我写一下广搜,广搜在最短路(骗分)上确实也有突出贡献,普及组应该也会考到,我今天就给要考普及组的同学讲讲课,今天讲广搜. 广搜,把可以走到的地点存进队列,然后一个个走,所以他第一次走到一 ...
- vue :关于引用jquery的二三问题
webpack版本:3.6.0 首先是引用jquery. 有两个地方要改. 1 (项目地址)/build/webpack.base.conf.js 2 (项目地址)/src/main.js webpa ...
- BT面板安装教程
面板特点 一键配置服务器环境(LAMP/LNMP) 一键安全重启 一键创建管理网站.ftp.数据库 一键配置(定期备份.数据导入.伪静态.301.SSL.子目录.反向代理.切换PHP版本) 一键安装常 ...
- 最全JavaScript基础总结
JavaScript介绍 什么是JavaScript? Javascript是一门面向对象的,跨平台的脚本语言. JavaScript有什么特点? 解释性脚本语言 运行在浏览器(浏览器内核带有js解释 ...
- 题解 CF920F 【SUM and REPLACE】
可以事先打表观察每个数的约数个数,观察到如果进行替换,若干次后这个数便会被替换成1. 所以我们可以直接暴力的进行区间修改,若这个数已经到达1或2,则以后就不再修改,用并查集和树状数组进行维护. 这个方 ...
- hibearnate的一级缓存和二级缓存的功能
首先要明白缓存是干什么的,缓存就是要将一些经常使用的数据缓存到内存或者各种储存介质中,当再次使用时可以不用去数据库中查询,减少与数据库的交互,提高性能.再说明一级与二级缓存的作用:一级缓存是Sessi ...
- springboot(八)内置SpringMvc静态文件地址修改
参考:作者:恒宇少年链接:https://www.jianshu.com/p/c6ab1081fd5f 介绍: SpringMVC大家都不陌生,而被SpringBoot集成的SpringMVC除了 ...
- python socket函数详解
关于socket函数,每个的意义和基本功能都知道,但每次使用都会去百度,参数到底是什么,返回值代表什么意义,就是说用的少,也记得不够精确.每次都查半天,经常烦恼于此.索性都弄得清楚.通透,并记录下来, ...