根据字母查找相似单词的算法

时间:2017-03-28 14:10:44

标签: algorithm machine-learning data-mining

我正在寻找一种基于共享字母检测单词(文本字符串)相似性的方法。

我正在研究Hash函数,尤其是Rabin-Karp算法,以便在更大的字符串中找到类似的单词。

但它对我想要的情况不起作用: 我考虑过的三个例子"类似的"在我的案例中,基于德国银行: 有德国银行"," Postbank"和" Landesbank"。这三个人都有" bank"在他们的名字里面,但只有德意志银行将它作为一个单独的词。 因此,基本上根据共享字符来衡量单词的相似性。 我认为应该有一个限制,如果可能的话,应该只考虑≥4个字符的相似之处。

如果我只是在找" bank"我会硬编码。但我正在寻找一种方法来找到这样的类似名称/字符串,而不是首先知道它。

4 个答案:

答案 0 :(得分:5)

如果我错了,请纠正我。从你的问题,我知道你需要找到所有有共同点的字符串。

我们可以在所有字符串之间找到常见的SubStrings。根据Substring的长度,我们可以给出一个分数。根据阈值,您可以决定字符串是否属于同一组。

答案 1 :(得分:1)

为了比较任何2个给定的字符串,我们可以根据超出阈值的每个子字符串的长度,得出一个表示匹配有多好的数字。

将给定的字符串与所有其他字符串进行比较并找到匹配数最多的字符串将为我们提供最多的"类似的"字符串。

我的方法假设子串匹配将按顺序排列。如果子串的顺序不重要,例如,这不会起作用。如果abcdXXefgh应与abcdYYefghefghYYabcd同等相似。虽然可以通过检查最后c的值并从那里计算匹配数来修改它。

如果你想考虑字符串的长度或其他因素,可以稍微调整一下。

我们可以使用类似于Levenshtein distance使用的动态编程方法的方法。

  

所有可能前缀的距离可能存储在数组d[][]中,其中d[i][j]是字符串i的第一个s字符与第一个j之间的距离1}}字符串t的字符。

我们可以有一个额外的数组c来跟踪当前子字符串匹配的长度。

然后任何给定的单元格值[i,j]将是最大值:

  • 当前子字符串匹配前的费用(d[i-length,j-length])加上当前匹配的费用(length < threshold为0,length = c[i,j]
  • 根据Levenshtein距离定义:(值直接复制,这些操作没有成本)
    • 插入(d[i, j-1]
    • 删除(d[i-1, j]
    • 替换(相同或不同的字符)(d[i-1, j-1]

伪代码:

set each cell in c and d to 0

threshold = 4     // shortest possible substring to consider

for j = 1 to n
for i = 1 to m
   currentSubstringCost = 0
   if s[i] == t[j]     // there's a matching substring
      c[i, j] = c[i-1, j-1]
      if c[i, j] >= threshold
          currentSubstringCost = d[i - c[i, j], j - c[i, j]]
                                 + calculateSubstringCost(c[i, j])
   d[i, j] = maximum(currentSubstringCost,      // substring match
                     d[i-1, j],                 // deletion
                     d[i, j-1],                 // insertion
                     d[i-1, j-1])               // substitution

return d[m, n]

您需要弄清楚如何计算任何给定子字符串(calculateSubstringCost)的成本。

一种简单的方法是取子串长度的平方,因此长度为4的子串将花费16,而长度为6的子串将花费36

您还可以通过使用另一个数组来优化此项,以便在当前子字符串匹配之前跟踪成本,这样我们只需要向后查看最多1行(请参阅above link例子)。

答案 2 :(得分:1)

抓取一个嵌入模型(有训练有素的word2vec或手套),它为你提供了一个单词语义的密集向量表示。

然后,通过嵌入向量表示,您可以通过单词之间的余弦距离轻松找到语义相似度。与通常的信息检索技术(如levenshtein或公共子串/单词重叠)相比,这里的重大改进是它实际上是基于这些词的抽象上下文的相似性。因此,Postbank非常接近BarclaysHSBC,而不仅仅是共享子字符串。

相反,一旦你通过嵌入有了单词的向量,你就可以使用任何聚类算法来找到共享语义相似性的单词集群,即使不知道描述这个集群的特定分类法确实存在。

答案 3 :(得分:1)

听起来像是Levenshtein Distance的一个很好的用例。简而言之,这计算了编辑的数量&#34;你需要做一个字符串到另一个字符串。通过添加模型中出现的编辑概率,您可以获得更好的效果,但这可能不是必需的。通常我发现2编辑限制有利于基本的拼写纠正。

维基页面:Levenshtein Distance