一个句子的词级编辑距离

24

是否存在一种算法可以找到两个句子之间的单词级编辑距离? 例如,"A Big Fat Dog" 和 "The Big House with the Fat Dog" 之间有1个替换和3个插入。

6个回答

12
一般而言,这被称为序列比对问题。实际上,无论您要对齐什么实体 - 位、字符、单词或DNA碱基 - 只要算法适用于一种类型的项目,它就会适用于其他所有项目。重要的是,您是否希望进行全局本地比对。 全局比对试图对每个序列中的每个残基进行比对,在序列相似且大小大致相等时最有用。一个通用的全局比对技术是基于 动态规划Needleman-Wunsch算法算法。当人们谈论Levinstain距离时,通常指的是全局比对。该算法非常简单,很多人都独立发现了它,并且有时您可能会遇到Wagner-Fischer算法,它本质上是相同的东西,但更经常在字符两个字符串之间编辑距离的上下文中提到。

本地比对更适用于不相似的序列,这些序列被怀疑包含相似区域或类似的序列模体在其较大的序列上下文中。Smith-Waterman算法是一种基于动态规划的通用本地比对方法。它在自然语言处理中很少使用,更多地用于生物信息学。


9
您可以使用与查找字符串编辑距离相同的算法来查找句子中的编辑距离。您可以将句子视为从字母表中提取的字符串,其中每个字符都是英语单词(假设空格用于标记一个“字符”开始和下一个结束的位置)。任何标准的计算编辑距离的算法,例如用于计算Levenshtein距离的标准动态规划方法,都可以适应解决此问题。

1

0
这是@templatetypedef的想法在ActionScript中的一个示例实现(对我来说效果很好),它计算规范化的Levenshtein距离(或者换句话说,给出一个值在[0..1]范围内)。
  private function nlevenshtein(s1:String, s2:String):Number {
     var tokens1:Array = s1.split(" ");
     var tokens2:Array = s2.split(" ");
     const len1:uint = tokens1.length, len2:uint = tokens2.length;
     var d:Vector.<Vector.<uint> >=new Vector.<Vector.<uint> >(len1+1);
     for(i=0; i<=len1; ++i)
        d[i] = new Vector.<uint>(len2+1);

     d[0][0]=0;

     var i:int;
     var j:int;

     for(i=1; i<=len1; ++i) d[i][0]=i; 
     for(i=1; i<=len2; ++i) d[0][i]=i;

     for(i = 1; i <= len1; ++i)
        for(j = 1; j <= len2; ++j)
           d[i][j] = Math.min( Math.min(d[i - 1][j] + 1,d[i][j - 1] + 1),
              d[i - 1][j - 1] + (tokens1[i - 1] == tokens2[j - 1] ? 0 : 1) );

     var nlevenshteinDist:Number = (d[len1][len2]) / (Math.max(len1, len2));

     return nlevenshteinDist;
  }

希望这能帮到你!


0

0

这里是使用动态规划方法实现的Java编辑距离算法句子。

public class EditDistance {

    public int editDistanceDP(String sentence1, String sentence2) {
        String[] s1 = sentence1.split(" ");
        String[] s2 = sentence2.split(" ");
        int[][] solution = new int[s1.length + 1][s2.length + 1];

        for (int i = 0; i <= s2.length; i++) {
            solution[0][i] = i;
        }

        for (int i = 0; i <= s1.length; i++) {
            solution[i][0] = i;
        }

        int m = s1.length;
        int n = s2.length;
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (s1[i - 1].equals(s2[j - 1]))
                    solution[i][j] = solution[i - 1][j - 1];
                else
                    solution[i][j] = 1
                            + Math.min(solution[i][j - 1], Math.min(solution[i - 1][j], solution[i - 1][j - 1]));
            }
        }
        return solution[s1.length][s2.length];
    }

    public static void main(String[] args) {
        String sentence1 = "first second third";
        String sentence2 = "second";
        EditDistance ed = new EditDistance();
        System.out.println("Edit Distance: " + ed.editDistanceDP(sentence1, sentence2));
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接