我有一个大阵列,其中有数百万个全都是24个字符的DNA序列。 DNA序列应该是随机的,并且只能包含A,T,G,C,N。我正在尝试查找彼此之间有一定汉明距离的字符串。
我的第一种方法是计算每个字符串之间的汉明距离,但这会花费很长的时间。
我的第二种方法是使用屏蔽方法来创建字符串的所有可能变体,并将其存储在字典中,然后检查是否发现此变体的次数超过1次。在海明距离为1的情况下,此方法工作非常快(20分钟),但是占用大量内存,因此在海明距离为2或3时将不可行。
第二种方法的Python 2.7实现。
sequences = []
masks = {}
for sequence in sequences:
for i in range(len(sequence)):
try:
masks[sequence[:i] + '?' + sequence[i + 1:]].append(sequence[i])
except KeyError:
masks[sequence[:i] + '?' + sequence[i + 1:]] = [sequence[i], ]
matches = {}
for mask in masks:
if len(masks[mask]) > 1:
matches[mask] = masks[mask]
我正在寻找一种更有效的方法。我遇到了特里树,KD树,n元语法和索引,但是我迷失了解决该问题的最佳方法。
答案 0 :(得分:0)
一种方法是本地敏感哈希
首先,您应该注意,此方法不一定会返回所有对,而是会以很高的概率返回所有对(或大多数对)。
位置敏感散列可以概括为:彼此 close 的数据点被映射到相似的哈希(在同一存储桶中很有可能)。检查此link以获得更多详细信息。
您的问题可以用数学方式重铸为:
给定N
向量v ∈ R^{24}, N<<5^24
和最大汉明距离d
,返回汉明距离最大为d
的对。
您将解决此问题的方法是在K
中随机生成{P_1,P_2,...,P_K}
平面R^{24}
; K
是您必须试验的参数。对于每个数据点v
,您将定义v
的哈希作为元组Hash(v)=(a_1,a_2,...,a_K)
,其中a_i∈{0,1}
表示v
是在平面之上还是在平面之下。您可以证明(我将省略证明),如果两个向量之间的汉明距离很小,那么它们的哈希值接近的可能性就很高。
因此,对于任何给定的数据点,您无需检查序列中的所有数据点,而只需检查“闭合”哈希值箱中的数据点。
请注意,这些都是基于启发式的,需要您尝试K
以及如何从每个哈希中搜索“关闭”。随着K
的增加,垃圾箱数量随之成倍增加,但是相似的可能性也会增加。
从您所说的来看,您似乎拥有一个巨大的数据集,所以我想我可以考虑一下。
答案 1 :(得分:0)
在这里找到我的解决方案:http://www.cs.princeton.edu/~rs/strings/
这使用三元搜索树,仅花费了几分钟和大约1GB的内存。我修改了demo.c文件以适合我的用例。