提示:
词典及容错性检索【拼写校正(词项独立校正(编辑距离和回溯路径计算,k-gram索引)及上下文敏感校正方法)】
本节最重要的内容是:

(1)词典快速查找的数据结构
(2)非精确查询
(3)自动校正技术

希望大家学到:

(1)了解词典查找的数据结构
(2)理解通配符查询的思想
(3)掌握编辑距离的计算
(4)理解自动校正技术的思路



文章目录

  • 拼写校正
  • 校正基本原则
  • 编辑距离
  • ※编辑距离计算
  • ※回溯路径
  • 基于编辑距离的拼写校正
  • 拼写校正中的k-gram 索引
  • 基于k-gram重合度
  • 上下文敏感的校正
  • 基于发音的校正技术



拼写校正

校正基本原则

kibana 关联索引到discover_程序人生

编辑距离

kibana 关联索引到discover_字符串_02

※编辑距离计算

采用动态规划的方法,将字符串s1,s2使用数组的方式存放。
时间复杂度:O(|s1|*|s2|).
自然语言表达:cafe->coffee的编辑距离:
       cafe->caffe->coffe->coffee
建表6*8的表格(取决于两个字符串长度+2)
编辑距离的表格绘制非常简单,不要被表象迷惑!

首先,根据两个字符串建表,填入数据,如下图所示:

c

o

f

f

e

e

0

1

2

3

4

5

6

c

1

a

2

f

3

e

4

然后,从(3,3)位置开始计算,填入以下三值中最小值
(填入的数字就是对应操作数,上表填入的数字算是最复杂的情况,每个数字都替换或增添,我们希望最小操作数当然是填最小值)

(1)如果该位置最上方数字和最左方数字相同,选取该位置左上方数据;如果不相同,选取左上方数字+1。
(2)左方数字+1。
(3)上方数字+1。

以(3,3)位置为例,最上方和最作方对应的都是c,是相同的,那么候选数字选左上方数字0;左方数字1+1=2;上方数字1+1=2;选三者最小0填入。以此类推即可。

c

o

f

f

e

e

0

1

2

3

4

5

6

c

1

0

1

2

3

4

5

a

2

1

1

2

3

4

5

f

3

2

2

1

2

3

4

e

4

3

3

2

2

2

3

编辑距离呢就是最右下角的那个了!

简简单单吧,位置解读一下:

kibana 关联索引到discover_字符串_03

kibana 关联索引到discover_操作数_04


if s1[i] == s2[j]:

啥都别做(skip)

i, j 同时向前移动

else:

三选一:

插入(insert)

删除(delete)

替换(replace)

def minDistance(s1, s2) -> int:

    def dp(i, j):# 返回 s1[0..i] 和 s2[0..j] 的最小编辑距离
        # base case
        if i == -1: return j + 1
        if j == -1: return i + 1

        if s1[i] == s2[j]:
            return dp(i - 1, j - 1)  # 啥都不做
# 本来就相等,不需要任何操作
# s1[0..i] 和 s2[0..j] 的最小编辑距离等于s1[0..i-1] 和 s2[0..j-1] 的最小编辑距离
# 也就是说 dp(i, j) 等于 dp(i-1, j-1)
        else:
            return min(
                dp(i, j - 1) + 1,    # 插入:直接在 s1[i] 插入一个和 s2[j] 一样的字符,那么 s2[j] 就被匹配了,前移 j,继续跟 i 对比,后面的+1是操作数加一
                dp(i - 1, j) + 1,    # 删除:直接把 s[i] 这个字符删掉,前移 i,继续跟 j 对比
                dp(i - 1, j - 1) + 1 # 替换:直接把 s1[i] 替换成 s2[j],这样它俩就匹配了,同时前移 i,j 继续对比
            )

    # i,j 初始化指向最后一个索引
    return dp(len(s1) - 1, len(s2) - 1)

>>算法讲解参考讲解非常详细。

※回溯路径

回溯路径的话借鉴一个更好讲述的例子

kibana 关联索引到discover_操作数_05


回溯路径就是从表右下角出发,寻找合适操作(就是左,左上,和上三条路选择最小的那条),反过来就是想要的最简操作路径。

编辑过程:

原始字符串:

str2=a b c d e f b c d

str1=b c d a b c d e f

以下方向是回溯反向之后的

操作

含义

向右走

删除

向左走

插入

斜向下且数值不变

不做处理

斜向下且数值加1

替换

kibana 关联索引到discover_操作数_06


例子具体操作:

1、向右走,即 d[ 1,1] = d[ 1-1,1 ]+1 , str2 要删除第一个字符,变为 bcdefbcd

2、斜向下,且值未变,说明相同,不用操作

str2 =b c d e f b c f

str1 =b c d a b c d e f

3、 d 之后向右,即删除 e

4、斜向下,且值加1,表示替换,将f换为a

str2 =b c d a b c f

str1 =b c d a b c d e f

5、最后两步向下,表示添加,此处添加 e, f

str2 = b c d a b c f e f

str1 = b c d a b c d e f

基于编辑距离的拼写校正

kibana 关联索引到discover_操作数_07


说白了,就是在一堆字符串里找和目标字符串编辑距离最小的呗。

拼写校正中的k-gram 索引

kibana 关联索引到discover_操作数_08


设阈值,找尽可能多含有与目标字符串有共同字符序列的字符串。

还是不够精准:示例查询bord,阈值2个2-gram词项。

下图中boardroom就含有与bord共同的字符序列bo,rd。那么这个字符串符合输出条件,显然差距较大。

kibana 关联索引到discover_信息检索_09

基于k-gram重合度

kibana 关联索引到discover_程序人生_10

上下文敏感的校正

kibana 关联索引到discover_操作数_11

基于发音的校正技术

kibana 关联索引到discover_编辑距离_12