在工作中,我们经常需要从与其他输入字符串最匹配的字符串列表中查找字符串。目前,我们正在使用Needleman-Wunsch算法。该算法通常会返回大量误报(如果我们将最小分数设置得太低),有时它会找不到匹配(当最小分数太高时),并且大多数时候,我们需要手工检查结果。我们认为我们应该尝试其他替代方案。
您对算法有任何经验吗? 你知道算法如何相互比较吗?
我真的很感激一些建议。
PS:我们用C#编码,但你不应该关心它 - 我一般都在询问算法。
哦,对不起,我忘记提及了。
不,我们没有使用它来匹配重复数据。我们有一个我们正在寻找的字符串列表 - 我们称之为搜索列表。然后我们需要处理来自各种来源的文本(如RSS提要,网站,论坛等) - 我们提取这些文本的一部分(有完整的规则集,但这是无关紧要的)我们需要匹配那些反对搜索列表的人。如果字符串与search-list中的一个字符串匹配 - 我们需要对事物进行一些进一步的处理(这也是无关紧要的)。
我们无法执行常规比较,因为从外部源提取的字符串(大多数情况下)包含一些额外的单词等。
无论如何,这不是重复检测。
答案 0 :(得分:32)
好的,Needleman-Wunsch(NW)是来自生物信息学文献的经典端到端(“全球”)对准器。它很久以前在FASTA包中可用作“align”和“align0”。不同之处在于“0”版本并没有像避免端部间隙那样偏向,这通常会让高质量的内部匹配变得更容易。史密斯 - 沃特曼,我怀疑你知道,是当地的对准者,是BLAST的原始基础。 FASTA也有自己的本地对准器,但略有不同。所有这些都是用于估计与单个字符对的评分指标相关的Levenshtein距离的启发式方法(在生物信息学中,通常由Dayhoff /“PAM”,Henikoff& Henikoff或其他矩阵给出,并且通常被更简单且更合理地反射的东西取代应用于自然语言时语言词形态的替代品。)
让我们对标签不要珍惜:至少在实践中提到的Levenshtein距离基本上是编辑距离,你必须对它进行估计,因为一般来说计算它是不可行的,即使在有趣的特殊情况下计算也很昂贵:水在那里变得很快,因此我们有长期和良好声誉的启发式方法。
现在关于你自己的问题:几年前,我不得不检查短DNA读取对已知正确参考序列的准确性,我想出了一些我称之为“锚定比对”的东西。
我们的想法是通过查找发生给定N字符子字符串的所有位置来设置您的引用字符串并“消化”它。选择N,这样你构建的表不会太大,但也要使长度为N的子串不太常见。对于像DNA库这样的小字母,可以在N个字符的字符串上找到一个完美的哈希值,并在每个bin的链表中创建一个表并链接匹配。列表条目必须标识子字符串的序列和起始位置,该子字符串映射到它们出现在其列表中的bin。这些是要搜索的字符串列表中的“锚点”,NW对齐可能很有用。
处理查询字符串时,从查询字符串中的某个偏移量K开始取N个字符,哈希它们,查找它们的bin,如果该bin的列表是非空的,则遍历所有列表记录,执行查询字符串与记录中引用的搜索字符串之间的对齐。在进行这些对齐时,您将查询字符串和搜索字符串排在锚点,并提取搜索字符串的子字符串,该字符串与查询字符串的长度相同,并且包含该锚点的相同长度偏移,K。
如果您选择足够长的锚点长度N和一组合理的偏移量K值(它们可以分布在查询字符串中或限制为低偏移量),您应该获得可能的对齐的子集,并且通常会得到更清晰的赢家。通常,您会希望使用端部偏向的类似于对象的NW对齐器。
这种方法试图通过限制它的输入来增加NW,这有一个性能提升,因为你做的对齐较少,而且它们通常在相似的序列之间。与你的NW对准器有关的另一个好处是允许它在经过一定量或长度的间隙后放弃以降低成本,特别是如果你知道你不会看到或对中等质量的比赛感兴趣。
最后,此方法用于具有小字母的系统,其中K限制在查询字符串中的前100个左右位置,搜索字符串比查询大得多(DNA读数大约为1000个碱基并且搜索字符串大约是10000,所以我一直在寻找近似的子字符串匹配,特别是编辑距离的估计。将这种方法适用于自然语言需要仔细考虑:如果你的查询字符串和搜索字符串的长度相似,你就会失去字母大小。
无论哪种方式,允许同时使用来自查询字符串的不同端的多个锚可能有助于进一步过滤馈送到NW的数据。如果你这样做,准备好发送重叠的字符串,每个字符串包含两个锚点之一,然后调整对齐...或者可能进一步修改NW以强调在对齐过程中使用惩罚修改期间保持你的锚点大部分完好无损算法的执行。
希望这有用或至少有趣。
答案 1 :(得分:6)
与Levenstein距离相关:您可能希望通过将结果除以较长字符串的长度来对其进行标准化,以便始终获得介于0和1之间的数字,以便您可以比较字符串对的距离以一种有意义的方式(表达式L(A,B)> L(A,C) - 例如 - 除非你规范化距离,否则没有意义。)
答案 2 :(得分:5)
要查看的其他算法是agrep(Wikipedia entry on agrep), FASTA and BLAST生物序列匹配算法。这些是approximate string matching的特殊情况,也在Stony Brook algorithm repositry中。如果您可以指定字符串彼此不同的方式,则可以专注于定制算法。例如,aspell使用“soundlike”(soundex-metaphone)距离的一些变体与“键盘”距离相结合来容纳不良拼写者和糟糕的打字者。
答案 3 :(得分:4)
我们正在使用Levenshtein distance方法检查数据库中的重复客户。它运作得很好。
答案 4 :(得分:1)
答案 5 :(得分:1)
为了最大限度地减少由于拼写中的轻微变化或错误导致的不匹配,我使用了Metaphone算法,然后使用Levenshtein距离(在百分比匹配时缩放到0-100作为百分比匹配)来测量接近度。这似乎运作得相当好。
答案 6 :(得分:0)
为了扩展Cd-MaN的答案,听起来你正面临着一个规范化问题。如何处理不同长度的路线之间的分数并不是很明显。
鉴于您感兴趣的内容,您可能希望获得对齐的p值。如果您使用的是Needleman-Wunsch,则可以使用Karlin-Altschul统计数据http://www.ncbi.nlm.nih.gov/BLAST/tutorial/Altschul-1.html获取这些p值{/ p>
BLAST可以使用这些统计信息进行局部对齐并对其进行评估。如果您担心速度,这将是一个很好的工具。
另一种选择是使用HMMER。 HMMER使用Profile Hidden Markov模型来对齐序列。就个人而言,我认为这是一种更强大的方法,因为它也提供了位置信息。 http://hmmer.janelia.org/
答案 7 :(得分:-1)
我曾经使用过一些您会发现的最脏的数据。平均需要匹配的约5000行数据(相当于数十万美元)完全耗尽了。 我最初的模糊匹配经验是Excel先生用VBA编写的算法。 它存在一些一致性方面的问题,例如我期望为0%的情况并非完全为0%,相似度为60%的相似度看起来更像是90%,依此类推。 因此,我搬到了Levenshtein / Damerau-Levenshtein。这是一项重大改进,但在Excel中却相当缓慢。接下来,我跳过了Jaro-Winkler,但随后很快将其丢弃。 最后,在2016年,我编写了自己的文章(类似于n-gram),并在接下来的两年中对其进行了完善。 今天,它是一个名为Flookup的加载项;您可以在Google表格上获取它,并查看它如何保存。