我有数十万个长度为32位的稀疏比特串.
我想对它们进行最近邻搜索,查找性能至关重要。我一直在研究各种算法,但它们似乎针对的是文本字符串而不是二进制字符串。我认为局部敏感哈希或谱哈希似乎是很好的选择,或者我可以研究压缩。这些方法中哪一个对我的比特串问题有效?任何方向或指导将不胜感激。
我有数十万个长度为32位的稀疏比特串.
我想对它们进行最近邻搜索,查找性能至关重要。我一直在研究各种算法,但它们似乎针对的是文本字符串而不是二进制字符串。我认为局部敏感哈希或谱哈希似乎是很好的选择,或者我可以研究压缩。这些方法中哪一个对我的比特串问题有效?任何方向或指导将不胜感激。
near(Uint q)
——> j,其中hammingdist(q,X[j])
很小X
中进行二分搜索q
,然后在其周围进行线性搜索。def near( q, X, Blocksize=100 ):
preprocess: sort X
Uint* p = binsearch( q, X ) # match q in leading bits
linear-search Blocksize words around p
return the hamming-nearest of these.
这很快 - 二分查找在1M个单词中+在100个大小的块中找到最近的汉明距离,只需要<10微秒就能在我的Mac ppc上完成。 (这高度依赖于缓存 - 您的里程表可能会有所不同。)
这与找到真正最接近的X[j]有多接近?
我只能做实验,无法进行数学计算:
对于1M个随机查询和1M个随机单词,
最接近的匹配平均相差4-5位,
而真正最接近的是3位(线性扫描所有1M)。
near32 N 1048576 Nquery 1048576 Blocksize 100
binary search, then nearest +- 50
7 usec
distance distribution: 0 4481 38137 185212 443211 337321 39979 235 0
near32 N 1048576 Nquery 100 Blocksize 1048576
linear scan all 1048576
38701 usec
distance distribution: 0 0 7 58 35 0
使用块大小为50和100运行数据,以查看匹配距离的下降情况。
X
并将上半字/下半字交换,创建一个名为Xswap
的副本,
并返回更好的结果。
near( q, X, Blocksize )
near( swap q, Xswap, Blocksize )
拥有大量的内存可以使用更多的位交换后的 X
副本,例如32个旋转。
我不知道性能如何随着Nshuffle和Blocksize的变化而变化-这是一个针对LSH理论家的问题。
nearest( query word 0, Sortedarray0, 100 ) -> min Hammingdist e.g. 42 of 320
nearest( query word 1, Sortedarray1, 100 ) -> min Hammingdist 37
nearest( query word 2, Sortedarray2, 100 ) -> min Hammingdist 50
...
-> e.g. the 37.
当然,这种方法会错过那些没有单个单词接近的近似匹配,
但它非常简单,并且sort和binsearch非常快速。
指针数组所占据的空间正好与数据位一样多。
100个字,3200个位可以完全以同样的方式工作。
但是:只有在0位和1位数量大致相等时才有效,
而不是99%的0位。