提示:
词典及容错性检索【拼写校正(词项独立校正(编辑距离和回溯路径计算,k-gram索引)及上下文敏感校正方法)】
本节最重要的内容是:
(1)词典快速查找的数据结构
(2)非精确查询
(3)自动校正技术
希望大家学到:
(1)了解词典查找的数据结构
(2)理解通配符查询的思想
(3)掌握编辑距离的计算
(4)理解自动校正技术的思路
文章目录
- 拼写校正
- 校正基本原则
- 编辑距离
- ※编辑距离计算
- ※回溯路径
- 基于编辑距离的拼写校正
- 拼写校正中的k-gram 索引
- 基于k-gram重合度
- 上下文敏感的校正
- 基于发音的校正技术
拼写校正
校正基本原则
编辑距离
※编辑距离计算
采用动态规划的方法,将字符串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 |
编辑距离呢就是最右下角的那个了!
简简单单吧,位置解读一下:
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)
>>算法讲解参考讲解非常详细。
※回溯路径
回溯路径的话借鉴一个更好讲述的例子
回溯路径就是从表右下角出发,寻找合适操作(就是左,左上,和上三条路选择最小的那条),反过来就是想要的最简操作路径。
编辑过程:
原始字符串:
str2=a b c d e f b c d
str1=b c d a b c d e f
以下方向是回溯反向之后的
操作 | 含义 |
向右走 | 删除 |
向左走 | 插入 |
斜向下且数值不变 | 不做处理 |
斜向下且数值加1 | 替换 |
例子具体操作:
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
基于编辑距离的拼写校正
说白了,就是在一堆字符串里找和目标字符串编辑距离最小的呗。
拼写校正中的k-gram 索引
设阈值,找尽可能多含有与目标字符串有共同字符序列的字符串。
还是不够精准:示例查询bord,阈值2个2-gram词项。
下图中boardroom就含有与bord共同的字符序列bo,rd。那么这个字符串符合输出条件,显然差距较大。
基于k-gram重合度
上下文敏感的校正
基于发音的校正技术