近似string匹配algorithm

在工作中,我们经常需要从string列表中find与其他inputstring最接近的string。 目前,我们正在使用Needleman-Wunschalgorithm。 该algorithm通常会返回大量的误报(如果我们将最小分数设置得太低),有时在它应该(当最小分数太高时)找不到匹配,并且大多数时候,我们需要手工检查结果。 我们认为我们应该尝试其他的select。

你有什么经验的algorithm? 你知道这些algorithm是如何相互比较的吗?

我真的很感激一些build议。

PS:我们用C#编写,但是你不应该关心它 – 我总是在问一些algorithm。


哦,对不起,我忘了提这个。

不,我们没有使用它来匹配重复的数据。 我们有一个我们正在寻找的string列表 – 我们称之为search列表。 然后,我们需要处理各种来源(如RSS提要,网站,论坛等)的文本 – 我们提取这些文本的一部分(有一整套的规则,但这是不相关的),我们需要匹配那些违反search列表。 如果string匹配search列表中的一个string – 我们需要做一些事情的进一步处理(这也是不相关的)。

我们不能进行正常的比较,因为从外部来源提取的string,大多数情况下,包括一些额外的单词等。

无论如何,这不是重复检测。

OK,Needleman-Wunsch(NW)是来自生物信息学文献的经典端对端(“全球”)对准器。 它很早以前就可以在FASTA软件包中“alignment”和“alignment”了。 不同之处在于,“0”版本并没有偏向于避免结束间隔,这往往允许有利于高质量的内部匹配。 史密斯沃特曼,我怀疑你知道,是一个本地alignment,是BLAST的原始基础。 FASTA也有自己的当地定位器,略有不同。 所有这些实质上都是启发式方法,用于估计与个别字符对的评分度量有关的Levenshtein距离(在生物信息学中,通常由Dayhoff /“PAM”,Henikoff&Henikoff或其他matrix给出,通常用更简单和更合理地反映替代的在应用于自然语言的语言词汇形态中)。

让我们对标签不是很珍贵:至less在实践中参考的Levenshtein距离基本上是编辑距离,你必须估计它,因为通常计算它是不可行的,即使在有趣的特殊情况下计算也是昂贵的:水在那里得到了深入的,因此我们有启发性的长期和良好的方法。

至于你自己的问题:几年前,我不得不根据已知的正确的参考序列检查短DNA阅读的准确性,并且提出了一些我称为“锚定比对”的东西。

这个想法是把你的引用string集合,并通过查找给定的N字符子string发生的所有位置“消化”它。 selectN,这样你创build的表不是太大,而且长度N的子串也不是太常见。 对于像DNA碱基这样的小字母,可以在N个字符的string上创build一个完美的哈希表,并在每个bin的链表中链接一个表。 列表条目必须标识映射到其列表中出现的bin的子string的序列和起始位置。 这些是要在NWalignment可能有用的searchstring列表中的“锚”。

在处理查询string时,您需要从查询string中的某个偏移量K处开始的N个字符,对它们进行哈希,查找它们的bin,如果该bin的列表不为空,则查看所有列表logging,并执行查询string和logging中引用的searchstring。 在执行这些alignment时,将查询string和searchstring排列锚点 ,并提取searchstring的子string,该string的长度与查询string的长度相同,并在相同的偏移量处包含该锚点。

如果select足够长的锚定长度N和一组合理的偏移量K(它们可以遍布查询string或被限制为低偏移量),则应该获得可能alignment的子集,并且通常会获得更清晰的获胜者。 通常情况下,您会希望使用较less的偏向alignment的alignmentNWalignment器。

这种方法试图通过限制它的input来提高NW的性能,这样做会带来性能上的提升,因为你做的比较less,而且它们更经常在相似的序列之间。 用NW对准器做的另一件好事是允许它在发生一定数量或长度的间隙后放弃,特别是如果你知道你不会看到或对中等质量的匹配感兴趣的话。

最后,这个方法被用在一个带有小字母的系统上,K被限制在查询string的前100个位置,并且查询string比查询字符要大得多(DNA读数大约是1000个碱基,searchstring是10000的顺序,所以我正在寻找特定的编辑距离的估计合理的近似子串匹配)。 将这种方法适应自然语言需要仔细考虑:如果查询string和searchstring的长度相似,则字符大小会丢失。

无论哪种方式,允许同时使用来自查询string的不同端的多于一个锚可能有助于进一步过滤到NW的数据。 如果你这样做,准备好可能发送重叠的string,每个包含一个锚到alignment器,然后协调alignment…或者可能进一步修改NW,以强调保持你的锚大多完好无损,algorithm的执行。

希望这有助于或至less有趣。

与Levenstein距离相关:您可能希望通过将结果除以较长的string的长度来对它进行归一化,以便始终得到一个介于0和1之间的数字,以便您可以比较有意义的string对的距离例如,expression式L(A,B)> L(A,C) – 除非将距离归一化,否则没有意义)。

可供select的algorithm有agrep ( Wikipedia entry on agrep ), FASTA和BLAST生物序列匹配algorithm。 这些都是近似string匹配的特殊情况,也在Stony Brookalgorithm存储中 。 如果可以指定string彼此不同的方式,则可以专注于定制的algorithm。 例如,aspell使用“类似于声音”(soundex-metaphone)距离的“变形”(“soundex-metaphone”)距离以及“键盘”距离来容纳不好的拼写器和错误的types。

我们正在使用Levenshtein距离方法来检查数据库中的重复客户。 它工作得很好。

使用带有回溯的FM索引 ,类似于Bowtie模糊校准器中的

为了尽量减less由于拼写的轻微变化或错误导致的不匹配,我使用了Metaphonealgorithm,然后使用Metaphone编码中的Levenshtein距离(以百分比匹配的比例缩放)进行度量。 这似乎工作得很好。

为了扩大Cd-MaN的答案,这听起来像是你正在面对一个正常化问题。 如何处理不同长度的alignment之间的分数并不明显。

鉴于你感兴趣的,你可能想获得p值为您的路线。 如果您使用Needleman-Wunsch,您可以使用Karlin-Altschul统计数据获得这些p值http://www.ncbi.nlm.nih.gov/BLAST/tutorial/Altschul-1.html

BLAST将会使用这些统计信息进行局部alignment和评估。 如果你关心速度,这将是一个很好的使用工具。

另一个select是使用HMMER。 HMMER使用Profile Hidden Markov模型来alignment序列。 就我个人而言,我认为这是一个更强大的方法,因为它也提供位置信息。 http://hmmer.janelia.org/