最近邻搜索和近似最近邻搜索(NN和ANN)和库

Ann, Approximate Nearest Neighbor的缩写,就是近似最近邻搜索。

在机器学习领域,语义检索,图像识别,推荐系统等方向常涉及到的一个问题是:给定一个向量X=[x1,x2,x3...xn],需要从海量的向量库中找到最相似的前K个向量。通常这些向量的维度很高,对于在线服务用传统的方法查找是非常耗时的,容易使得时延上成为瓶颈,因此业界通用的方式就是将最相似的查找转换成Ann问题

这样查找返回的前K个向量并不一定是最相似的K个向量,衡量Ann算法好不好的一个依据是召回,每次Ann请求返回的K个结果与使用暴力查找的K个结果去比较,如果完全一致,说明是最好的。因为省了搜索时间却没有影响效果。

目前的Ann算法有基于图(hnswlib )的,基于树(pysparnn)的,基于哈希(NearPy这个库)等,并且有很多关于Ann算法的实现,开源的很多,如annoy, faiss,nmslib, falconn,FLANN等。

更详细的一些测试在这个网站有数据 http://ann-benchmarks.com。作者比较了不同的距离度量方式及在不同数据集的效果。

基于图的算法(hnsw)其实在评测上看起来是最好的, 但是其耗费比较多内存,树的方法在维度大时会变成暴力搜索,其它方法也有不同的特点。

我测试过的,一分为两类:稀疏向量和非稀疏向量

首先:稀疏向量是指维度比较多,而且向量的很多元素是0,啁密向量指零元素较少,向量的维度也就几十到几百。

如果上万维的一般是稀疏向量(一万个词语词库句子搜索),这样的PySpann最好。

其次是周密向量,那么faiss应该内存和速度比较均衡 。

 

pysparnn安装比较简单,下载源码python setup.py install

faiss的安装如下:

1 sudo apt-get install libopenblas-dev liblapack3 python-numpy python-dev
2 apt-get install libblas-dev libatlas-dev liblapack-dev

swig install
git clone https://github.com/swig/swig.git

cd swig
sudo apt-get install automake
./autogen.sh
./configure
sudo apt-get install bison flex
make
sudo make install

 

这样的算法成千上百,对此进行评测https://github.com/erikbern/ann-benchmarks

评测数据集如下

Dataset Dimensions Train size Test size Neighbors Distance Download
DEEP1B 96 9,990,000 10,000 100 Angular HDF5 (3.6GB)
Fashion-MNIST 784 60,000 10,000 100 Euclidean HDF5 (217MB)
GIST 960 1,000,000 1,000 100 Euclidean HDF5 (3.6GB)
GloVe 25 1,183,514 10,000 100 Angular HDF5 (121MB)
GloVe 50 1,183,514 10,000 100 Angular HDF5 (235MB)
GloVe 100 1,183,514 10,000 100 Angular HDF5 (463MB)
GloVe 200 1,183,514 10,000 100 Angular HDF5 (918MB)
Kosarak 27983 74,962 500 100 Jaccard HDF5 (2.0GB)
MNIST 784 60,000 10,000 100 Euclidean HDF5 (217MB)
NYTimes 256 290,000 10,000 100 Angular HDF5 (301MB)
SIFT 128 1,000,000 10,000 100 Euclidean HDF5 (501MB)

评估的实现

  • Annoy Spotify自家的C++库(提供Python绑定)。Annoy最突出的特性是支持使用静态索引文件,这意味着不同进程可以共享索引
  • FLANN 加拿大英属哥伦比亚大学出品的C++库,提供C、MATLAB、Python、Ruby绑定。
  • scikit-learn 知名的Python机器学习库scikit-learn提供了LSHForestKDTreeBallTree实现。
  • PANNS 纯Python实现。已“退休”,作者建议使用MRPT。
  • NearPy 纯Python实现。基于局部敏感哈希(Locality-sensitive hashing,简称LSH,一种降维方法)。
  • KGraph C++库,提供Python绑定。基于图(graph)算法。
  • NMSLIB (Non-Metric Space Library) C++库,提供Python绑定,并且支持通过Java或其他任何支持Apache Thrift协议的语言查询。提供了SWGraph、HNSW、BallTree、MPLSH实现。
  • hnswlib(NMSLIB项目的一部分) 相比当前NMSLIB版本,hnswlib内存占用更少。
  • RPForest 纯Python实现。主要特性是不需要在模型中储存所有索引的向量。
  • FAISS Facebook出品的C++库,提供可选的GPU支持(基于CUDA)和Python绑定。包含支持搜寻任意大小向量的算法(甚至包括可能无法在RAM中容纳的向量)。
  • DolphinnPy 纯Python实现。基于超平面局部敏感哈希算法。
  • Datasketch 纯Python实现。基于MinHash局部敏感哈希算法。
  • PyNNDescent 纯Python实现。基于k-近邻图构造(k-neighbor-graph construction)。
  • MRPT C++库,提供Python绑定。基于稀疏随机投影(sparse random projection)和投票(voting)。
  • NGT: C++库,提供了Python、Go绑定。提供了PANNG实现。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章