单词级别编辑句子的距离

时间:2011-02-20 07:35:54

标签: string algorithm edit-distance

是否有一种算法可以让您找到2个句子之间的单词级编辑距离? 例如,“一只大肥狗”和“肥胖狗的大房子”有1个替代品,3个插入物

6 个答案:

答案 0 :(得分:9)

您可以使用相同的算法来查找字符串中的编辑距离,以查找句子中的编辑距离。您可以将句子视为从字母表中绘制的字符串,其中每个字符都是英语中的单词(假设空格用于标记一个“字符”开始和下一个结束的位置)。任何用于计算编辑距离的标准算法,例如用于计算Levenshtein距离的标准dynamic programming approach,都可以用来解决这个问题。

答案 1 :(得分:6)

通常,这称为sequence alignment problem。实际上,对齐哪些实体(位,字符,单词或DNA库)并不重要 - 只要该算法适用于一种类型的项目,它将适用于其他所有项目。重要的是您是否需要全局本地对齐。

全局比对,它尝试对齐每个序列中的每个残基,在序列相似且大小大致相同时最有用。一般的全局对齐技术是Needleman-Wunsch algorithm算法,它基于dynamic programming。当人们谈论Levinstain距离时,他们通常意味着全球一致。该算法非常简单,有几个人独立发现它,有时你可能遇到Wagner-Fischer algorithm这本质上是相同的东西,但在两个字符串之间的编辑距离的上下文中更常提到。

局部比对对于怀疑在其较大序列环境中包含相似区域或相似序列基序的不相似序列更有用。 Smith-Waterman algorithm是一种基于动态编程的通用局部对齐方法。它很少用于自然语言处理,更常用于生物信息学。

答案 2 :(得分:0)

以下是ActionScript中对@ templatetypedef的想法的一个示例实现(它对我来说非常有用),它计算了标准化的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;
  }

我希望这会有所帮助!

答案 3 :(得分:0)

D中的实现是在任何范围内推广的,因而是数组。因此,通过将句子分成字符串数组,可以运行算法并提供编辑编号。

https://dlang.org/library/std/algorithm/comparison/levenshtein_distance.html

答案 4 :(得分: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));
    }
}

答案 5 :(得分:0)

从nltk包中检出python中的AlignedSent函数。它将句子在单词级别对齐。

https://www.nltk.org/api/nltk.align.html