NLP学习(5)之Min-Edit-Distance

Mar 20, 2019


判断两个字符串的相似度的场景

  • 拼写检查纠错:
    用户输入: graffe
    哪个更接近: graf, graft, grail, giraffe
  • 计算生物学: 基因对齐比对

Edit Distance

  • 两个字符串最小的edit distance
  • 是最少的,使两个字符串变相同的操作数 :
    • 插入
    • 删除
    • 替换

如何求Min Edit Distance

等价于找到一个从初始字符串到目标字符串的最短变化路径

  • 初始状态: 我们要转化的字符串
  • 操作: 插入、删除、替换
  • 目标状态: 目标字符串
  • 路径花费: 操作数量

削减搜索空间方法:对于每个状态只保存最短路径

定义Min Edit Distance

初始两个字符串:
X – 长度为m
Y – 长度为n
定义D[i][j] = X[1…i]和Y[1…j]的edit distance,则X和Y的Min Edit Distance为D(n, m)

计算方法: Dynamic Programming

//初始化:
D[i][0] = i;
D[0][j] = j;

//循环:
for (int i = 1;i <= m;++i)
{
    for (int j = 1;j <= n;++j)
    {
        int sub = (X[i] != Y[i]) ? D[i - 1][j - 1] + 2 : D[i - 1][j - 1];
        D[i][j] = min(min(D[i - 1][j] + 1, D[i][j - 1] + 1), sub);
    }
}

//返回:
return D[n][m];

计算对齐(Computing alignments)

我们不仅需要知道Min Edit Distance, 还需要知道为了获得Min Edit Distance需要的操作步骤, 因此需要在上面算法中加入backtrace

//初始化:
D[i][0] = i;
D[0][j] = j;

//循环:
for (int i = 1;i <= m;++i)
{
    for (int j = 1;j <= n;++j)
    {
        int sub = (X[i] != Y[i]) ? D[i - 1][j - 1] + 2 : D[i - 1][j - 1];
        D[i][j] = min(min(D[i - 1][j] + 1, D[i][j - 1] + 1), sub);
        if (insertion)
            ptr[i][j] = LEFT;
        else if (deletion)
            ptr[i][j] = DOWN;
        else if (substitution)
            ptr[i][j] = DIAG;
    }
}

//返回:
return D[n][m];

带权重的Weighted Edit Distance

需要权重的原因: 在拼写检查中,一些字母比其他字母更容易出错
算法:

//初始化:
D[0][0] = 0;
D[i][0] = D[i - 1][0] + del[X[i]];
D[0][j] = D[0][j - 1] + ins[Y[i]];

//循环:
for (int i = 1;i <= m;++i)
{
    for (int j = 1;j <= n;++j)
    {
        D[i][j] = min(min(D[i - 1][j] + del[X[i]], D[i][j - 1] + ins[Y[i]]), D[i - 1][j - 1] + sub[X[i], Y[i]]);
    }
}

//返回:
return D[n][m];

上一篇博客:NLP学习(6)之语言模型
下一篇博客:NLP学习(4)之语句划分