我正在寻找一个数据结构来处理包含512个二进制值的二进制字符串。
我的目标是向结构发送查询并获取包含距离较远的所有数据的结果集。
我的第一个想法是使用kd树。但是这些树木的高度非常慢。 我的第二个想法是使用lsh方法(minHash / superbit)lsh。但为此,我还必须有一个结构来执行有效的搜索
如何处理这些大数据?
**更新** 一些细节说明:
答案 0 :(得分:3)
如果不了解您的搜索参数,就很难进行过优化。也就是说,我认为一个好的方法是构建一个B或T树,然后针对数据的二进制特性优化该结构。
具体来说,您有64个字节的数据作为512个元素的位串。您的估计是您将获得“bilions”记录。那是2 32 值的数量级,那么1/16 th 的空间是满的吗? (这是否符合您的期望?)
无论如何,尝试将数据分成字节,让每个字节成为关键级别。如果设置位的概率是均匀的,则可以压缩级别记录。 (如果不是,如果设置位更有可能位于密钥的前面,那么您可能只想分配256个下一级指针并使一些为空。这并不值得。)
所有级别都相同 - 它们将代表字符串的8位。因此,计算一个表,该表为一个字节映射距该字节距离S
内的所有字节值,0 <= S <= 8.此外,计算将两个字节映射到距离的表他们之间的E,hamming(a,b)
。
要遍历树,请将搜索距离设为SD。设置D = SD。阅读顶级块。从查询中查找小于距离min(8, D)
的块中的所有8位值。对于每个值,计算精确距离hamming(query, value)
并递归到下一个块,并为该子树递归D = D - hamming(query, value)
。
答案 1 :(得分:1)
我在这里看到的最大的设计问题是闭包要求:我们需要在给定向量的距离 N 内返回所有项,任意 N < / strong>即可。数据空间稀少:&#34;数十亿&#34;大约是2 ^ 33,但我们有512位信息,因此每2 ^(512-33)种可能只有1个条目。对于随机分布的密钥,任意两个节点之间的预期距离为256;预期的最近邻距离大约是180度。
这使我期望您的搜索将依赖于非随机数据集群,并且通过识别该集群来促进您的搜索。这对初始数据来说是一个有点痛苦的预处理步骤,但应该非常值得。
我的一般方法是首先以一些快速的方式识别这些集群。从散列函数开始,该函数返回非常一般的距离度量。例如,对于任何矢量,计算到一组正交参考矢量中的每一个的距离。对于16位,您可以采用以下设置(以十六进制列出):0000,00FF,0F0F,3333,5555,连续&#34; grain&#34;交替位#34;将此哈希作为一个简单的元组返回4位距离,总共20位(长矢量实际节省,其中一个大小为2 ^(2 ^ N))。
现在,这个哈希元组允许您粗略估计汉明距离,这样您就可以更容易地对向量进行聚类:类似的向量必须具有相似的哈希值。
在每个群集中,找到一个中心元素,然后根据与该中心的距离来表征群集的每个元素。为了获得更高的速度,请为每个节点提供距离最近的邻居列表,所有这些邻居都在群集中。这为您提供了每个群集的图表。
同样连接所有集群中心,为更近的集群中心提供直接边缘。如果您的数据合理地适合搜索,那么我们将能够保证,对于具有集群中心Ac和Bc的任何两个节点A,B,我们将具有d(A,Ac)+ d(B,Bc) )&lt; d(A,B)。每个集群都是一个拓扑邻域。
查询过程现在有点快。对于目标矢量V,找到哈希值。找到足够接近的群集中心,其邻域中的某些内容可能匹配([实际距离] - [查询范围] - [群集半径])。这将允许您立即消除整个群集,并可能为您提供一整套&#34;点击&#34;。对于每个边缘集群(一些,但不是所有节点都符合条件),您需要找到一个通过接近强力的东西工作的节点(从集群中心可行距离的中间开始),以及然后对每个节点的邻居进行广度优先搜索。
我希望这能为您提供与最佳性能相媲美的东西。它还可以适当地适应添加和删除,只要这些添加和删除不足以更改其他节点的集群成员资格。
这组矢量很简单。写出16位情况的位模式:
0000 0000 0000 0000 16 0s
0000 0000 1111 1111 8 0s, 8 1s
0000 1111 0000 1111 4 0s, 4 1s, repeat
0011 0011 0011 0011 2 0s, 2 1s, repeat
0101 0101 0101 0101 1 0s, 1 1s, repeat