做网页检索系统的时候,当时还想加给它加上一个拼写纠错的功能(当然,只适合英文...),后来找到了个效果不错的方法给大家分享一下。
拼写纠错、校正是一个提高搜索引擎用户体验的很关键的一项能力。如我们在Google搜索 saferi,然后会看到它自动帮助我们纠正了输错的单词。
仔细想一想为什么它会知道我们输错的单词就是safari,我们会发现主要原因有两个;
1. 错写的单词与正确单词的拼写相似,容易错写;这里safari是否容易错写成saferi需要统计数据的支持;为了简化问题,我们认为字形越相近的错写率越高,用编辑距离来表示。字形相近要求单词之间编辑距离小于等于2,这里saferi与safari编辑距离为1,后面我们再具体了解编辑距离的定义。
2. 正确单词有很多,除去语义因素外最有可能的单词,也就是这个单词的使用频率了。所以我们确认的标准还有一项就是,单词使用频率。
下面介绍一个机器学习拼写检查方法,基于贝叶斯定理的拼写检查法,主要思想就是上面2条,列举所有可能的正确拼写,根据编辑距离以及词频从中选取可能性最大的用于校正。
原理:
用户输入的错误的单词记做w,用户想要输入的拼写正确的单词记做c,则
P(c | w) : 用户输错成w时,想要的单词是c的概率。
P(w | c) : 用户将c错写成w的概率,与编辑距离有关。
P(c) : 正确词是c的概率,可以认为是c的使用频率,需要数据训练。
根据贝叶斯公式
P(c | w) = P(w | c) * P(c) / P(w)
因为同一次纠正中w是不变的,所以公式中我们不必理会P(w),它是一个常量。比较 P(c | w) 就是比较 P(w | c) * P(c) 的大小。
一、P(c)
P(c)替换成“使用频率”,我们从足够大的文本库(词典)点击打开链接中统计出各个单词的出现频率,也可以将频率归一化缩小方便比较。
二、P(w | c)
P(w | c)替换成常数lambda * editDist
editDist编辑距离只计算editDist = 1与editDist = 2的,
editDist1,编辑距离为1的有下面几种情况:
(1)splits:将word依次按照每一位分割成前后两半。比如,'abc'会被分割成 [('', 'abc'), ('a', 'bc'), ('ab', 'c'), ('abc', '')] 。
(2)beletes:依次删除word的每一位后、所形成的所有新词。比如,'abc'对应的deletes就是 ['bc', 'ac', 'ab'] 。
(3)transposes:依次交换word的邻近两位,所形成的所有新词。比如,'abc'对应的transposes就是 ['bac', 'acb'] 。
(4)replaces:将word的每一位依次替换成其他25个字母,所形成的所有新词。比如,'abc'对应的re