0


机器学习:基于朴素贝叶斯实现单词拼写修正器(附Python代码)

目录

0 写在前面

机器学习强基计划聚焦深度和广度,加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理;“广”在分析多个机器学习模型:决策树、支持向量机、贝叶斯与马尔科夫决策、强化学习等。

🚀详情:机器学习强基计划(附几十种经典模型源码合集)


在机器学习强基计划4-3:详解朴素贝叶斯分类原理(附例题+Python实现)中我们学习了朴素贝叶斯的概念:采用属性独立性假设对类后验概率建模,本节再次使用这个理论实现一个有趣的应用——单词拼写修正器,并梳理一些朴素贝叶斯原理中的细节,以期固本强基。

在这里插入图片描述

1 语言中的贝叶斯公式

我们的目标是找到原拼写错误单词

    w
   
  
  
   w
  
 
w的修正单词

 
  
   
    c
   
  
  
   c
  
 
c,一个事实是,我们没有办法给出确定性的答案,例如

例1:错误单词

lates

应该被修正为

late

latest

还是

lattes

…?

因此,我们要找的是一个

    w
   
  
  
   w
  
 
w所有潜在修正单词中可能性最大的那一个,用概率表示为

 
  
   
    
     
      c
     
     
      ∗
     
    
    
     =
    
    
     a
    
    
     r
    
    
     g
    
    
     m
    
    
     a
    
    
     
      x
     
     
      
       c
      
      
       ∈
      
      
       c
      
      
       a
      
      
       n
      
      
       d
      
      
       i
      
      
       d
      
      
       a
      
      
       t
      
      
       e
      
     
    
    
     P
    
    
     (
    
    
     c
    
    
     ∣
    
    
     w
    
    
     )
    
   
   
    c^*= argmax_{c\in candidate} P(c|w)
   
  
 c∗=argmaxc∈candidate​P(c∣w)

其中

candidate

就是所有候选单词的集合。根据贝叶斯公式,有

      c
     
     
      ∗
     
    
    
     =
    
    
     a
    
    
     r
    
    
     g
    
    
     m
    
    
     a
    
    
     
      x
     
     
      
       c
      
      
       ∈
      
      
       c
      
      
       a
      
      
       n
      
      
       d
      
      
       i
      
      
       d
      
      
       a
      
      
       t
      
      
       e
      
     
    
    
     
      
       P
      
      
       (
      
      
       w
      
      
       ∣
      
      
       c
      
      
       )
      
      
       P
      
      
       (
      
      
       c
      
      
       )
      
     
     
      
       P
      
      
       (
      
      
       w
      
      
       )
      
     
    
   
   
    c^*= argmax_{c\in candidate} \frac{P(w|c)P(c)}{P(w)}
   
  
 c∗=argmaxc∈candidate​P(w)P(w∣c)P(c)​

因为

    P
   
   
    (
   
   
    w
   
   
    )
   
  
  
   P(w)
  
 
P(w)对每个候选单词

 
  
   
    c
   
  
  
   c
  
 
c都相同,因此可以忽略,所以重点关注

 
  
   
    
     
      c
     
     
      ∗
     
    
    
     =
    
    
     a
    
    
     r
    
    
     g
    
    
     m
    
    
     a
    
    
     
      x
     
     
      
       c
      
      
       ∈
      
      
       c
      
      
       a
      
      
       n
      
      
       d
      
      
       i
      
      
       d
      
      
       a
      
      
       t
      
      
       e
      
     
    
    
     P
    
    
     (
    
    
     w
    
    
     ∣
    
    
     c
    
    
     )
    
    
     P
    
    
     (
    
    
     c
    
    
     )
    
   
   
    c^*= argmax_{c\in candidate} P(w|c)P(c)
   
  
 c∗=argmaxc∈candidate​P(w∣c)P(c)

其中

  •                                P                         (                         w                         ∣                         c                         )                              P(w|c)                  P(w∣c):称为**误差模型**,表示的是作者想打出单词                                   c                              c                  c却误写成单词                                   w                              w                  w的概率,例如                                   P                         (                         t                         e                         h                         ∣                         t                         h                         e                         )                              P(teh|the)                  P(teh∣the)把```the```打成```teh```的概率相对而言远大于                                   P                         (                         t                         h                         e                         e                         e                         x                         y                         z                         ∣                         t                         h                         e                         )                              P(theeexyz|the)                  P(theeexyz∣the)
    
  •                                P                         (                         c                         )                              P(c)                  P(c):称为**语言模型**,表示的是单词                                   c                              c                  c出现的概率,例如搜索引擎提供用户输入的所有文本中,单词```the```的占了7%,那么                                   P                         (                         t                         h                         e                         )                         =                         0.07                              P(the) = 0.07                  P(the)=0.07
    

一个很自然的问题是:**为什么要把简单的表达式

      P
     
     
      (
     
     
      c
     
     
      ∣
     
     
      w
     
     
      )
     
    
    
     P(c|w)
    
   
  P(c∣w)用一个更复杂的
  
   
    
     
      P
     
     
      (
     
     
      w
     
     
      ∣
     
     
      c
     
     
      )
     
     
      P
     
     
      (
     
     
      c
     
     
      )
     
    
    
     P(w|c)P(c)
    
   
  P(w∣c)P(c)来代替?**我相信这也是很多同学初学贝叶斯公式时的困惑,这里用实例说明。

答案很简单:后验概率

    P
   
   
    (
   
   
    c
   
   
    ∣
   
   
    w
   
   
    )
   
  
  
   P(c|w)
  
 
P(c∣w)无法直接计算,但是将其拆成两个因子后计算相对简便,而且可以透过现象看到其中的本质。

例2:考虑一个错误拼写的单词

w="thew"

,以及两个候选修正

c="the"

c="thaw"

,哪个有更高的

     P
    
    
     (
    
    
     c
    
    
     ∣
    
    
     w
    
    
     )
    
   
   
    P(c|w)
   
  
 P(c∣w)?
c="thaw"

似乎更可能,因为从

a

e

只是一个很小的变化,但另一方面,

c="the"

似乎可能性也很大,因为

the

是一个非常常用的单词(生僻字出现概率低,自然不容易误写)。从我们正常的分析思路就可以看出,这个后验概率其实包含两个部分,一个是从单词

    c
   
  
  
   c
  
 
c误写成

 
  
   
    w
   
  
  
   w
  
 
w的可能性,一个是单词

 
  
   
    c
   
  
  
   c
  
 
c是否常见。所以**贝叶斯公式抽丝剥茧地告诉了我们后验概率的内在逻辑**。

2 朴素贝叶斯建模

2.1 单词异化

包含四个异化操作产生候选单词集合

candidate
  • 删除word中的某个字母deletes
  • word中相邻字母交换顺序transposes
  • word中字母突变(用新字母代替)replaces
  • word中在某位置插入新字母inserts
'''
* @breif: 对单词进行异化操作,产生与原词有微小差异的新词
* @param[in]: word -> (str)原词汇
* @retval: 与原词有微小差异的新词
'''defeditsOnce(self, word):# 字母表
    letters    ='abcdefghijklmnopqrstuvwxyz'# 将词汇分解为左右组合,例如tree分解为[(t,ree),(tr,ee),(tre,e),(tree, )]
    splits     =[(word[:i], word[i:])for i inrange(len(word)+1)]
    deletes    =[L + R[1:]for L, R in splits if R]
    transposes =[L + R[1]+ R[0]+ R[2:]for L, R in splits iflen(R)>1]
    replaces   =[L + c + R[1:]for L, R in splits if R for c in letters]
    inserts    =[L + c + R               for L, R in splits for c in letters]returnset(deletes + transposes + replaces + inserts)

2.2 语言模型建模

搜集一大段文本作为数据集

在这里插入图片描述
接着直接计算词频作为语言模型

    P
   
   
    (
   
   
    c
   
   
    )
   
  
  
   P(c)
  
 
P(c)
'''
* @breif: 查询词汇word的频率
* @param[in]: word -> (str)待查词文本
* @retval: 词汇word的频率p(word)
'''defp(self, word):
    self.wordsCnt = Counter(re.findall(r'\w+', text.lower()))
    self.wordsNum =sum(self.wordsCnt.values())return self.wordsCnt[word]/ self.wordsNum

2.3 误差模型建模

采用短路表达式划分优先级,即优先级为

该词汇(在词典中)
经过一次编辑
经过二次编辑
该词汇(不在词典中)

,若高优先级词汇存在会直接返回,相当于

argmaxP(w|c)

的操作。

defcandidates(self, word):return(self.known([word])or self.known(self.editsOnce(word))or self.known(self.editsTwice(word))or[word])

3 单词修正测试

在这里插入图片描述
首先做一个简单的测试:

defcorrection(self, word):returnmax(self.candidates(word), key=self.p)

随便挑几个单词

print(c.correction('worl'))>>> work

print(c.correction('traon'))>>> train

print(c.correction('inteligent'))>>> intelligent

效果还不错,接着拿个大的测试集来测试一下

trainPath = os.path.abspath(os.path.join(__file__,"../../data/big.txt"))
testPath = os.path.abspath(os.path.join(__file__,"../../data/spell_test.txt"))
c = WordsCorrector(trainPath)
c.predict(testPath)>>>75% of 270 correct (6% unknown) at 56 words per second

完整代码与数据集联系下方博主名片获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《机器人原理与技术》
  • 《机器学习强基计划》
  • 《计算机视觉教程》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇


本文转载自: https://blog.csdn.net/FRIGIDWINTER/article/details/127177936
版权归原作者 Mr.Winter` 所有, 如有侵权,请联系我们删除。

“机器学习:基于朴素贝叶斯实现单词拼写修正器(附Python代码)”的评论:

还没有评论