Nmslib高维空间最近邻逼近搜索算法介绍
业务场景
上一次介绍图像搜索的基本原理,现在记录下使用的数据包的问题。
查询图片先进行特征提取,使用一个向量来表示,之后使用该向量与数据库中所有的商品向量进行计算相似度指标,比如cos距离,欧式距离,汉明距离。
具体的取决于向量的形式,有的先用cnn提取特征向量,可以计算其cos距离,有的提取之后对其进行哈希编码,先用汉明距离进行粗排,之后按照欧式距离进行重排。
这里就面临这样的一个问题:
- 特征向量一般都是高维,使用暴力算法计算相似度的话会非常耗时,满足不了实际应用场景;
没有等你算完,使用者的心就哇凉哇凉的,没有耐心等待的,而使用淘宝拍立淘的时候,响应速度非常快,用户体验很好!
这个时候就需要考虑使用一些快速计算的方法——ANN。
ANN
一看到ANN,第一反应应该是人工神经网络,这里是Approximate Nearest Neighbor,近似邻居算法。
关于这方面的算法有很多,比如Annoy
, scikit-learn
,hnswlib
, nmslib
等等。
几乎所有的ANN方法都是对全空间的划分,大多数使用的树模型,详细的介绍可以上网查询一下,这里介绍本人使用过的nmslib
包讲解。
NMSLIB
项目地址:https://github.com/nmslib/nmslib
非度量空间库(NMSLIB)是一种高效的跨平台相似性搜索库和用于评估相似性搜索方法的工具包。核心库并没有任何第三方依赖。
NMSLIB是一个可扩展的库,这意味着可以添加新的搜索方法和距离函数。NMSLIB可以直接在C ++和Python中使用。此外,还可以构建一个查询服务器,可以从Java(或Apache Thrift支持的其他语言)中使用。
这里介绍python的使用方法。
实例
import nmslib as nms ## 构建索引 index = nms.init(method='hnsw', space='cosinesimil') __index = {} product_dict_path = JSON_PATH + '/product_cv.json' with open(product_dict_path, 'r') as f: for line in f: pid, feat = line.strip('\n').split('\t') # init knn data frame __index.setdefault(pid, json.loads(feat)) index.addDataPoint(pid, json.loads(feat)) # set knn parameter INDEX_TIME_PARAMS = { 'indexThreadQty': 10, 'M': 100, 'efConstruction': 2000, 'post': 2} index.createIndex(self.INDEX_TIME_PARAMS) ## 使用 pids_index, distance = index.knnQuery(q_feat, k)
上述代码只是片段,详细讲解下各个参数的设置
-
method
: `hnsw'方法; -
space
: 'cosinesimil'空间; -
INDEX_TIME_PARAMS
: 详细参数
关于参数的设置可以见
参考
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
python中的树数据结构
线性数据中的典型顺序表和链表已经讲完: 《顺序表数据结构在python中的应用》 《python实现单向链表数据结构及其基本方法》 《python实现单向循环链表数据结构及其方法》 《python实现双向链表基本结构及其基本方法》 《python实现双向循环链表基本结构及其基本方法》 《python实现堆栈数据结构及其基本方法》 《Python实现双端队列数据结构及其基本方法》 下面将说图形结构中的典型数据机构:树;是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构,很象自然界中的树那样。 树的一些基础概念: 节点的度:一个节点含有的子树的个数称为该节点的度; 树的度:一棵树中,最大的节点的度称为树的度; 叶节点或终端节点:度为零的节点; 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推; 树的高
- 下一篇
现代C++之理解decltype
现代C++之理解decltype decltype用于生成变量名或者表达式的类型,其生成的结果有的是显而易见的,可以预测的,容易理解,有些则不容易理解。大多数情况下,与使用模板和auto时进行的类型推断相比,decltype作用于变量名或者表达式只是重复了一次变量名或者表达式的确切类型: const int i = 0; // decltype(i) 为 const int bool f(const Widget& w); // decltype(w) 为 const Widget& // decltype(f) 为 bool(const Widget&) struct Point { int x, y; // decltype(Point::x) 为 int }; // decltype(Point::y) 为 int Widget w; // decltype(w) 为 Widget if (f(w)) … // decltype(f(w)) 为 bool template<typename T> // std::vector 的简易实现 cla...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Mario游戏-低调大师作品
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用