数据准备

import faiss
import numpy as np d = 512          # 维数
# 向量集合
n_data = 2000
np.random.seed(0)
data = []
mu = 3
sigma = 0.1
for i in range(n_data):data.append(np.random.normal(mu, sigma, d))
data = np.array(data).astype('float32')# query 向量
n_query = 10
np.random.seed(12)
query = []
for i in range(n_query):query.append(np.random.normal(mu, sigma, d))
query = np.array(query).astype('float32')

精确搜索-L2距离(Exact Search for L2)

baseline

index = faiss.IndexFlatL2(d)  # L2距离
# index = faiss.index_factory(d, "Flat")  # 两种定义方式
index.add(data)
dis, ind = index.search(query, 10)
print(dis)
print(ind)
[[8.61838   8.782156  8.782816  8.832027  8.837635  8.8484955 8.8979788.9166355 8.919006  8.937399 ][9.033302  9.038906  9.091706  9.155842  9.164592  9.200113  9.2018859.220333  9.279479  9.312859 ][8.063819  8.211029  8.306456  8.373353  8.459253  8.459894  8.4985568.546466  8.555407  8.621424 ][8.193895  8.211957  8.34701   8.446963  8.45299   8.45486   8.4735728.504771  8.513636  8.530685 ][8.369623  8.549446  8.704066  8.736764  8.760081  8.777317  8.8313458.835485  8.858271  8.860057 ][8.299071  8.432397  8.434382  8.457373  8.539217  8.562357  8.5790338.618738  8.630859  8.6433935][8.615003  8.615164  8.72604   8.730944  8.762621  8.796932  8.7970668.797366  8.813984  8.834725 ][8.377228  8.522776  8.711159  8.724562  8.745737  8.763845  8.76868.7728    8.786858  8.828223 ][8.3429165 8.488056  8.655106  8.662771  8.701336  8.741288  8.74360758.770506  8.786265  8.8490505][8.522163  8.575702  8.684618  8.767246  8.782908  8.850494  8.8837328.903692  8.909395  8.917681 ]][[1269 1525 1723 1160 1694   48 1075 1028  544  916][1035  259 1279 1116 1398  879  289  882 1420 1927][ 327  345 1401  389 1904 1992 1612  106  981 1179][1259  112  351  804 1412 1987 1377  250 1624  133][1666  854 1135  616   94  280   30   99 1212    3][ 574 1523  366  766 1046   91  456  649   46  896][1945  944  244  655 1686  981  256 1555 1280 1969][ 879 1025  390  269 1115 1662 1831  610   11  191][ 156  154   99   31 1237  289  769 1524   56  661][ 427  182  375 1826  610 1384 1299  750    2 1430]]

精确搜索-点乘距离(Exact Search for Inner Product)

当数据库向量是标准化的,计算返回的distance就是余弦相似度

index = faiss.IndexFlatIP(d)  # 点乘
index.add(data)
dis, ind = index.search(query, 10)
print(dis)
print(ind)
[[4621.75   4621.5464 4619.745  4619.381  4619.176  4618.0625 4617.1694617.057  4617.048  4616.6304][4637.3965 4637.289  4635.3677 4635.2446 4634.881  4633.6074 4633.0214632.7646 4632.5596 4632.373 ][4621.755  4621.47   4619.748  4619.562  4619.423  4618.0186 4616.9924616.962  4616.9014 4616.735 ][4623.608  4623.5596 4621.3965 4621.1577 4620.9062 4619.838  4618.97564618.913  4618.7695 4618.4775][4625.553  4625.064  4623.461  4623.1963 4622.957  4621.337  4620.73634620.717  4620.5645 4620.248 ][4628.489  4628.449  4626.4917 4626.4873 4625.6406 4624.615  4624.294623.999  4623.7524 4623.618 ][4637.746  4637.338  4635.3047 4635.126  4634.7476 4633.0137 4632.86334632.58   4632.3027 4632.233 ][4630.4717 4630.334  4628.2646 4627.9375 4627.7383 4626.8975 4625.81354625.7227 4625.445  4625.0913][4635.7725 4635.4893 4633.6904 4633.5674 4632.658  4631.4634 4631.43074631.101  4630.99   4630.3066][4625.6763 4625.558  4623.454  4623.3916 4623.324  4622.2827 4621.77834621.1147 4620.9043 4620.8545]][[1562   27  681  169 1262  942 1566   31 1207  252][  27 1562  169  681 1262  942 1566 1392   31  252][1562   27  681  169 1262  942 1566  252   31 1392][1562   27  681  169 1262  942  252 1566   31 1207][1562   27  681  169 1262  942 1566  252   31 1513][1562   27  169  681 1262  942  252   31 1566  911][1562   27  169  681 1262 1566  942  252   31 1392][1562   27  681  169 1262  942 1566   31  252 1207][  27 1562  169  681 1262  942   31  252 1566 1392][1562   27 1262  681  169  942 1566   31 1207  252]]

HNSW(Hierarchical Navigable Small World graph exploration)

基于图近似方法获取返回的近似结果

index = faiss.IndexHNSWFlat(d, 16)
index.add(data)
dis, ind = index.search(query, 10)
print(dis)
print(ind)
[[8.61838   8.832027  8.8484955 8.897978  8.9166355 8.919006  8.9373998.9597    8.984709  8.998905 ][9.038906  9.164592  9.200113  9.201885  9.220333  9.312859  9.3443419.34485   9.416972  9.421429 ][8.063819  8.459253  8.459894  8.498556  8.555407  8.631897  8.713688.735945  8.770473  8.792957 ][8.193895  8.211957  8.34701   8.446963  8.45486   8.473572  8.5047718.513636  8.530685  8.545483 ][8.369623  8.760081  8.831345  8.860057  8.862643  8.93695   8.9722818.996923  9.065968  9.070428 ][8.299071  8.432397  8.434382  8.539217  8.562357  8.6433935 8.69831858.753673  8.768753  8.780443 ][8.762621  8.796932  8.797066  8.813984  8.860753  8.867388  8.9118128.922768  8.928856  8.942961 ][8.377228  8.522776  8.711159  8.724562  8.7728    8.828223  8.8794698.888437  8.914921  8.924161 ][8.3429165 8.488056  8.662771  8.741288  8.7436075 8.770506  8.8572548.893715  8.933592  8.960606 ][8.522163  8.575702  8.850494  8.903692  8.917681  8.936615  8.9616668.977329  9.009894  9.031724 ]][[1269   48 1075 1028  916  239  897 1627  120 1567][ 259 1398  879  289  882 1927   13   70 1023  121][1401 1904  106  981 1623 1393 1632  539 1143  366][1259  112  351  804 1987 1377  250 1624  133  879][1666   94 1212  277 1723  581  106  472  807  884][ 574 1523  366  766 1046   91  154  911  902  685][ 944 1686  981 1391  849  280 1337 1263   91 1540][ 879 1025  390  269 1115 1831  610   11  191 1686][ 154   31 1237  289  769 1524  661  426 1008 1727][ 182 1299 1430  511 1339 1010 1173 1457  664  529]]

倒排表搜索(Inverted file with exact post-verification)

quantizer = faiss.IndexFlatL2(d)  # 量化器
nlist = 50
index = faiss.IndexIVFFlat(quantizer, d, nlist, faiss.METRIC_L2)
index.train(data)
index.add(data)
index.nprobe = 30  # 选择nprobe个维诺空间进行索引
dis, ind = index.search(query, 10)
print(dis)
print(ind)
[[8.61838   8.782156  8.782816  8.832027  8.837635  8.8484955 8.8979788.9166355 8.919006  8.937399 ][9.033302  9.038906  9.091706  9.164592  9.200113  9.201885  9.2203339.279479  9.312859  9.344341 ][8.063819  8.211029  8.306456  8.373353  8.459253  8.459894  8.4985568.546466  8.555407  8.621424 ][8.193895  8.211957  8.34701   8.446963  8.45299   8.45486   8.4735728.504771  8.513636  8.530685 ][8.369623  8.549446  8.704066  8.736764  8.760081  8.777317  8.8313458.835485  8.858271  8.860057 ][8.299071  8.432397  8.434382  8.457373  8.539217  8.562357  8.5790338.618738  8.630859  8.6983185][8.615003  8.615164  8.72604   8.730944  8.762621  8.796932  8.7970668.797366  8.813984  8.834725 ][8.377228  8.522776  8.711159  8.724562  8.745737  8.763845  8.76868.7728    8.786858  8.828223 ][8.3429165 8.488056  8.655106  8.662771  8.701336  8.741288  8.74360758.770506  8.786265  8.8490505][8.522163  8.575702  8.684618  8.767246  8.782908  8.850494  8.8837328.903692  8.909395  8.917681 ]][[1269 1525 1723 1160 1694   48 1075 1028  544  916][1035  259 1279 1398  879  289  882 1420 1927   13][ 327  345 1401  389 1904 1992 1612  106  981 1179][1259  112  351  804 1412 1987 1377  250 1624  133][1666  854 1135  616   94  280   30   99 1212    3][ 574 1523  366  766 1046   91  456  649   46  154][1945  944  244  655 1686  981  256 1555 1280 1969][ 879 1025  390  269 1115 1662 1831  610   11  191][ 156  154   99   31 1237  289  769 1524   56  661][ 427  182  375 1826  610 1384 1299  750    2 1430]]

LSH(Locality-Sensitive Hashing (binary flat index))

nbits = 2 * d
index = faiss.IndexLSH(d, nbits)
index.train(data)
index.add(data)
dis, ind = index.search(query, 10)
print(dis)
print(ind)
[[ 8. 10. 10. 10. 10. 10. 10. 11. 11. 11.][ 7.  8.  9.  9.  9. 10. 10. 10. 10. 10.][ 7.  8.  8.  9.  9.  9.  9.  9.  9.  9.][ 9.  9. 10. 11. 12. 12. 12. 12. 12. 12.][ 6.  6.  6.  7.  7.  8.  8.  8.  8.  8.][ 8.  8.  8.  9.  9.  9.  9.  9. 10. 10.][ 6.  7.  8.  8.  9.  9.  9.  9.  9.  9.][ 9.  9.  9.  9.  9.  9.  9.  9.  9. 10.][ 7.  8.  8.  8.  8.  8.  8.  9.  9.  9.][ 9.  9.  9. 10. 10. 10. 10. 10. 10. 10.]][[1424  345 1544  760 1589 1043  668  492  148  666][1974 1436 1476   51  711  696   28  934  541 1125][1667 1356 1149  512 1592 1544 1677  309 1021 1018][ 708  107  606  243   18  612  598  615  269  250][1455  541 1142  843 1140  888  165  961  797 1003][1735  193  953 1071 1518 1109  449  263 1329 1216][1129 1231 1731  123  860  907  381  993  336 1071][1622  336 1970  845   70 1921 1973  980  331   42][1335  713 1589  395  263 1206  346  698  913  678][1395  279 1305  427 1707 1574 1710  226 1205 1160]]

SQ量化(Scalar quantizer (SQ) in flat mode)

index = faiss.IndexScalarQuantizer(d, 4)
index.train(data)
index.add(data)
dis, ind = index.search(query, 10)
print(dis)
print(ind)
[[8.623228  8.777794  8.785317  8.828827  8.835491  8.845296  8.8968968.914822  8.922382  8.934984 ][9.028503  9.037548  9.099254  9.152615  9.16542   9.196389  9.2004979.224977  9.274048  9.305386 ][8.064029  8.213011  8.310526  8.376434  8.4578285 8.462004  8.5009698.550645  8.556992  8.624526 ][8.196653  8.210537  8.3464365 8.444774  8.452023  8.454119  8.4745258.4966135 8.510042  8.525611 ][8.370451  8.547961  8.704324  8.733618  8.763927  8.776734  8.829518.835646  8.857151  8.859047 ][8.29591   8.432422  8.435947  8.454732  8.542397  8.565366  8.5796858.621871  8.632036  8.64478  ][8.609016  8.612934  8.726631  8.734137  8.758858  8.797329  8.7979718.798654  8.815296  8.838221 ][8.37895   8.521536  8.710902  8.726156  8.748387  8.75966   8.7682178.769184  8.792372  8.834644 ][8.340463  8.489507  8.659348  8.664953  8.702758  8.741514  8.7419418.768995  8.781276  8.852154 ][8.520282  8.5749855 8.68346   8.769207  8.782043  8.851276  8.8811148.906744  8.907756  8.924014 ]][[1269 1723 1525 1160 1694   48 1075  544 1028  916][1035  259 1279 1116 1398  289  879  882 1420 1927][ 327  345 1401  389 1992 1904 1612  106  981 1179][1259  112  351  804 1987 1412 1377  250 1624  133][1666  854 1135  616   94  280   30   99    3 1212][ 574 1523  366  766 1046   91  456  649   46  896][ 944 1945  244  655 1686  256  981 1555 1280 1969][ 879 1025  390  269 1115 1662 1831  610   11  191][ 156  154   99   31 1237  289  769 1524   56  661][ 427  182  375 1826  610 1384 1299  750    2 1430]]

PQ量化(Product quantizer (PQ) in flat mode)

M = 8 # 必须是d的因数
nbits = 6  # 只能是8,12,16
index = faiss.IndexPQ(d, M, nbits)
index.train(data)
index.add(data)
dis, ind = index.search(query, 10)
print(dis)
print(ind)
[[5.3148193 5.33667   5.390381  5.3969727 5.4020996 5.402466  5.40881355.420532  5.4210205 5.4370117][5.694214  5.71875   5.7408447 5.7418213 5.743042  5.7543945 5.76110845.764282  5.786255  5.791748 ][4.880615  4.9449463 4.9451904 5.0146484 5.022583  5.0406494 5.04443365.0650635 5.06604   5.0666504][4.8305664 4.852661  4.8569336 4.87146   4.8901367 4.8969727 4.90039064.9073486 4.9093018 4.911743 ][5.2233887 5.3170166 5.3239746 5.338623  5.347534  5.356201  5.35998545.362915  5.387085  5.40271  ][5.024658  5.0458984 5.0463867 5.069214  5.1254883 5.1533203 5.15576175.17395   5.1887207 5.188843 ][5.070923  5.1273193 5.144409  5.1882324 5.1896973 5.194702  5.208135.223633  5.223633  5.242798 ][5.173218  5.2506104 5.26355   5.3077393 5.3099365 5.3240967 5.3245855.3448486 5.3449707 5.3479004][5.1730957 5.246826  5.2974854 5.319092  5.3239746 5.3275146 5.34094245.3464355 5.352051  5.364624 ][5.204468  5.27124   5.272217  5.324463  5.335449  5.348755  5.35314945.355713  5.359619  5.3670654]][[1000 1775 1651  702 1963 1063  249 1995  689 1075][ 243  532 1923   52  304 1212  449 1264 1092  622][1904  981  735  492  458 1810 1945  839  875  616][1307  148  250 1773  576  187  864  394 1920 1550][1135 1429  151  773  250  502 1945 1408  694 1849][1427 1463  816 1314 1096  896    8 1366 1673  939][ 244  854   85  560 1154 1473  951 1626  218  885][ 278 1176  787   70  235  326  190 1843  892 1756][  81  855  416 1545  145 1811  172  383 1856   90][ 902 1238  725 1141 1255  593 1507  596 1400 1434]]

倒排表乘积量化(IVFADC (coarse quantizer+PQ on residuals))

M = 8
nbits = 4
nlist = 50
quantizer = faiss.IndexFlatL2(d)
index = faiss.IndexIVFPQ(quantizer, d, nlist, M, nbits)
index.train(data)
index.add(data)
dis, ind = index.search(query, 10)
print(dis)
print(ind)
[[5.1813607 5.213015  5.227062  5.240297  5.3074746 5.3143606 5.32094535.323071  5.3241897 5.3336196][5.531564  5.5329485 5.562758  5.563456  5.5912466 5.6556826 5.6729315.68467   5.6997647 5.702039 ][4.8162827 4.822724  4.8304024 4.8753777 4.885644  4.8879986 4.88815454.893022  4.8931584 4.900308 ][4.816623  4.83104   4.8495483 4.8536286 4.876833  4.877784  4.8800994.884579  4.8872194 4.891768 ][5.0868177 5.118717  5.1225142 5.1229815 5.1336117 5.1365952 5.14251855.1445856 5.1706796 5.1717625][4.896156  4.923249  4.941252  4.9426517 4.951362  4.9712415 4.97380264.9810586 4.9901094 4.991113 ][4.98639   4.9903703 4.9991083 5.0107374 5.011694  5.0129166 5.0165045.020243  5.0209174 5.024062 ][5.175429  5.175681  5.1776314 5.189157  5.1944485 5.222612  5.22329765.226807  5.236521  5.2451673][5.044052  5.080878  5.1016216 5.109776  5.1117053 5.124481  5.12564665.1480865 5.151196  5.1520753][5.129094  5.1587934 5.1708508 5.171063  5.18175   5.182567  5.19424345.1995926 5.201419  5.2037187]][[1962 1880  311 1897  666  201  647  283 1588  171][ 569  148  162   39  753 1032  983  934  560 1715][ 851  380 1322 1803 1678 1486 1504 1847 1206  306][ 960 1741  636  510 1568  880  866 1134  615  381][1799 1166  572 1631 1244  343 1212 1859  756 1630][ 816 1753  749 1621  444 1399  658  771  369  913][1902 1238  913 1546  654  969 1187  350  979 1251][ 464  839 1705  772   77  490 1976  998  968   57][1445  505  426  300 1220  122  806  755  100 1343][1432 1263 1198 1537 1816  263    1  430  598  260]]

cell-probe方法

为了加速索引过程,经常采用划分子类空间(如k-means)的方法,虽然这样无法保证最后返回的结果是完全正确的。先划分子类空间,再在部分子空间中搜索的方法,就是cell-probe方法。
具体流程为:

  • 数据集空间被划分为n个部分,在k-means中,表现为n个类;
  • 每个类中的向量保存在一个倒排表中,共有n个倒排表;
  • 查询时,选中nprobe个倒排表;
  • 将这几个倒排表中的向量与查询向量作对比。

在这种方法中,只需要排查数据库中的一部分向量,大约只有nprobe/n的数据,因为每个倒排表的长度并不一致(每个类中的向量个数不一定相等)

cell-probe粗量化

在一些索引类型中,需要一个Flat index作为粗量化器,如IndexIVFFlat,在训练的时候会将类中心保存在Flat index中,在addsearch阶段,会首先判定将其落入哪个类空间。在search阶段,nprobe参数需要调整以权衡检索精度与检索速度
实验表明,对高维数据,需要维持比较高的nprobe数值才能保证精度

与LSH的优劣

LSH也是一种cell-probe方法,与其相比,LSH有以下几点不足:

  • LSH需要大量的哈希方程,会带来额外的内存开销
  • 哈希函数不适合输入数据

参考

  • https://yongyuan.name/blog/scalar-quantization.html
  • https://github.com/liqima/faiss_note

faiss-7: 基础索引类型相关推荐

  1. 【Faiss】基础索引类型(六)

    基础索引类型 数据准备 import numpy as np d = 512 #维数 n_data = 2000 np.random.seed(0) data = [] mu = 3 sigma = ...

  2. Faiss(二)基础索引

    参考链接: Faiss入门及应用经验记录 - 知乎 Faiss indexes · facebookresearch/faiss Wiki · GitHub Faiss提供了多种索引,本篇介绍一些基础 ...

  3. mongodb安装_MongoDB索引策略和索引类型

    mongodb安装 1. MongoDB索引策略和索引类型–简介 MongoDB是一个开放源代码,面向文档的跨平台数据库,它使用C ++开发,并且是最流行和使用最广泛的NoSQL类型数据库之一. 它可 ...

  4. typescript索引类型_TypeScript的索引类型与映射类型,以及常用工具泛型的实现

    相信现在很多小伙伴都在使用 TypeScript(以下简称 TS),在 TS 中除了一些常用的基本类型外,还有一些稍微高级一点的类型,这些就是我本次文章要讲的内容:索引类型与映射类型,希望小伙伴们看过 ...

  5. Mysql-索引的基础和类型

    一.  索引的基础 索引类似于书籍的目录,要想找到一本书的某个特定主题,需要先查找书的目录,定位对应的页码. 存储引擎使用类似的方式进行数据查询,先去索引当中找到对应的值,然后根据匹配的索引找到对应的 ...

  6. MongoDB索引策略和索引类型

    1. MongoDB索引策略和索引类型–简介 MongoDB是一个开放源代码,面向文档的跨平台数据库,它使用C ++开发,并且是最流行和使用最广泛的NoSQL类型数据库之一. 它可在具有键-值对的类J ...

  7. postgreSQL源码分析——索引的建立与使用——各种索引类型的管理和操作(2)

    2021SC@SDUSC 目录 上层操作函数 index_open index_beginscan() index_create() indexcmd.c 下层接口函数 IndexScanDescDa ...

  8. [No0000B5]C# 类型基础 值类型和引用类型 及其 对象判等 深入研究1

    引言 本文之初的目的是讲述设计模式中的 Prototype(原型)模式,但是如果想较清楚地弄明白这个模式,需要了解对象克隆(Object Clone),Clone其实也就是对象复制.复制又分为了浅度复 ...

  9. [CLR via C#]4. 类型基础及类型、对象、栈和堆运行时的相互联系

    原文:[CLR via C#]4. 类型基础及类型.对象.栈和堆运行时的相互联系 CLR要求所有类型最终都要从System.Object派生.也就是所,下面的两个定义是完全相同的, //隐式派生自Sy ...

最新文章

  1. 使用Python PIL库实现简单验证码的去噪处理
  2. 【译】JavaScript 工厂函数 vs 构造函数
  3. 如何将模糊的图片变得清晰
  4. js null加法的处理
  5. python计算样本方差_Python计算库numpy进行方差/标准方差/样本标准方差/协方差的计算...
  6. 七乐彩中奖规则表_【开奖】双色球第2020094期开奖结果出炉!你中奖了吗?
  7. 多行文本溢出显示省略号(…) text-overflow: ellipsis
  8. 【转】C++从零实现神经网络
  9. 调用http_【学习充电】直观讲解一下 RPC 调用和 HTTP 调用的区别!
  10. 计算机在生活中应用视频,计算机在腐蚀防护中的应用教学视频
  11. 浏览器cookie那些事儿
  12. iOS上架app store下载步骤
  13. Java面试——多线程面试题
  14. Securing DevOps 免积分下载
  15. python图像的手绘效果代码_Python项目1:实现将图片转化为手绘效果
  16. 百度地图调用笔记:javascript版本2
  17. Arduino与Proteus仿真实例-74HC573锁存器驱动仿真
  18. LOMO+XQDA(2015CVPR)
  19. win10辅助准星教程
  20. 部署KVM 虚拟化平台

热门文章

  1. 魅族android面试题,魅族前端面试题 - 尝试做
  2. 728-MySQL索引篇
  3. 超级简单的EOS代币转账教程(EETH)
  4. 三星s4开机显示无服务器,三星s4稳压电源充电,造成手机无法开机故障维修一例...
  5. 数字营销分析理论之归因模型指南
  6. 解决iPhone连接Mac反复断开重连
  7. ISP IAP(转自EETOP)
  8. 李礼辉:警惕全球性数字货币,超主权或将导向金融颠覆(附全文)
  9. Xcode 安装Command Line Tools
  10. php输出json到表格,Vue如何导出json数据到Excel电子表格方法