是否可以在 Excel 中进行 Levenshtein 距离而不必求助于宏?

Posted

技术标签:

【中文标题】是否可以在 Excel 中进行 Levenshtein 距离而不必求助于宏?【英文标题】:Is it possible to do a Levenshtein distance in Excel without having to resort to Macros? 【发布时间】:2012-07-05 21:34:26 【问题描述】:

让我解释一下。

我要为一家公司做一些模糊匹配,所以 ATM 我用了一个 levenshtein 距离计算器,然后计算两个词的相似度百分比。如果术语相似度超过 80%,Fuzzymatch 将返回“TRUE”。

我的问题是我正在实习,马上就要离开了。将继续这样做的人不知道如何将 excel 与宏一起使用,并希望我尽我所能实现我所做的。

所以我的问题是:无论函数效率如何,有什么方法可以在 Excel 中创建一个标准函数来计算我之前所做的,而不使用宏?

谢谢。

【问题讨论】:

【参考方案1】:

如果你在谷歌上搜索类似 levenshtein distance google sheets

我把这个和来自milot-midia 的代码注释放在了一起(https://gist.github.com/andrei-m/982927 - MIT 许可下的代码)

来自标题菜单中的工作表,Tools -> Script Editor 为项目命名 函数的名称(不是项目)会让你使用函数 粘贴以下代码

function Levenshtein(a, b) 
  if(a.length == 0) return b.length; 
  if(b.length == 0) return a.length;

  // swap to save some memory O(min(a,b)) instead of O(a)
  if(a.length > b.length) 
    var tmp = a;
    a = b;
    b = tmp;
  

  var row = [];
  // init the row
  for(var i = 0; i <= a.length; i++)
    row[i] = i;
  

  // fill in the rest
  for(var i = 1; i <= b.length; i++)
    var prev = i;
    for(var j = 1; j <= a.length; j++)
      var val;
      if(b.charAt(i-1) == a.charAt(j-1))
        val = row[j-1]; // match
       else 
        val = Math.min(row[j-1] + 1, // substitution
                       prev + 1,     // insertion
                       row[j] + 1);  // deletion
      
      row[j - 1] = prev;
      prev = val;
    
    row[a.length] = prev;
  

  return row[a.length];

您应该能够使用

从电子表格中运行它

=Levenshtein(cell_1,cell_2)

【讨论】:

【参考方案2】:

虽然对于任何大小合理的字符串都无法在单个公式中完成,但您可以单独使用公式来使用工作表计算字符串之间的 Levenshtein 距离。

这是一个可以处理最多 15 个字符的字符串的示例,它可以轻松扩展为更多:

https://docs.google.com/spreadsheet/ccc?key=0AkZy12yffb5YdFNybkNJaE5hTG9VYkNpdW5ZOWowSFE&usp=sharing

这对于除了临时比较之外的任何事情都不实用,但它确实很好地展示了算法的工作原理。

【讨论】:

【参考方案3】:

查看之前计算 Levenshtein 距离的答案,我认为不可能将其创建为公式。

看看代码here

【讨论】:

我已经有密码了,谢谢。实际上我有多个,因为我编写了一个,找到了你链接的那个,在 MrExcel 论坛上找到了一个,然后从 FuzzyVlookup 中提取了一个。我只是希望它可以用作公式...如果没有,我想我将不得不找到另一种方法。【参考方案4】:

实际上,我想我刚刚找到了解决方法。我在代码的错误部分添加了它...

添加这一行

   else if(b.charAt(i-1)==a.charAt(j) && b.charAt(i)==a.charAt(j-1))
    val = row[j-1]-0.33;  //transposition

现在是这样的

  if(b.charAt(i-1) == a.charAt(j-1))
    val = row[j-1]; // match
   else if(b.charAt(i-1)==a.charAt(j) && b.charAt(i)==a.charAt(j-1))
    val = row[j-1]-0.33;  //transposition
   else 
    val = Math.min(row[j-1] + 1, // substitution
                   prev + 1,     // insertion
                   row[j] + 1);  // deletion 
   

似乎可以解决问题。现在“biulding”的准确率为 92%,“bilding”的准确率为 88%。 (而原始公式“建筑”只有 75%……尽管更接近正确的建筑拼写)

【讨论】:

以上是关于是否可以在 Excel 中进行 Levenshtein 距离而不必求助于宏?的主要内容,如果未能解决你的问题,请参考以下文章

Excel小技巧-你是否只知道表格按列排序?其实也可以按行排序!excel数据按行排序

是否可以在 Excel 2007 中看到超过 65536 行? [关闭]

如何用2007WPS excel 进行数据分析?如何安装啥加载项,

是否可以在 Excel UDF 中使用反斜杠 `\` 字符?

在 Excel 中打包和重用 VBA 代码

如何在 Excel VBA 中对字符串进行 URL 编码?