日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

python基于隱馬爾可夫模型實(shí)現(xiàn)中文拼音輸入

系統(tǒng) 1878 0

在網(wǎng)上看到一篇關(guān)于隱馬爾科夫模型的介紹,覺(jué)得簡(jiǎn)直不能再神奇,又在網(wǎng)上找到大神的一篇關(guān)于如何用隱馬爾可夫模型實(shí)現(xiàn)中文拼音輸入的博客,無(wú)奈大神沒(méi)給可以運(yùn)行的代碼,只能純手動(dòng)網(wǎng)上找到了結(jié)巴分詞的詞庫(kù),根據(jù)此訓(xùn)練得出隱馬爾科夫模型,用維特比算法實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的拼音輸入法。githuh地址:https://github.com/LiuRoy/Pinyin_Demo

原理簡(jiǎn)介隱馬爾科夫模型

抄一段網(wǎng)上的定義:

隱馬爾可夫模型 (Hidden Markov Model) 是一種統(tǒng)計(jì)模型,用來(lái)描述一個(gè)含有隱含未知參數(shù)的馬爾可夫過(guò)程。其難點(diǎn)是從可觀察的參數(shù)中確定該過(guò)程的隱含參數(shù),然后利用這些參數(shù)來(lái)作進(jìn)一步的分析。

拼音輸入法中可觀察的參數(shù)就是拼音,隱含的參數(shù)就是對(duì)應(yīng)的漢字。

viterbi算法

參考https://zh.wikipedia.org/wiki/維特比算法,思想是動(dòng)態(tài)規(guī)劃,代碼比較簡(jiǎn)單就不贅述。

代碼解釋

model定義

代碼見(jiàn)model/table.py文件,針對(duì)隱馬爾科夫的三個(gè)概率矩陣,分別設(shè)計(jì)了三個(gè)數(shù)據(jù)表存儲(chǔ)。這樣的好處很明顯,漢字的轉(zhuǎn)移概率矩陣是一個(gè)非常大的稀疏矩陣,直接文件存儲(chǔ)占用空間很大,并且加載的時(shí)候也只能一次性讀入內(nèi)存,不僅內(nèi)存占用高而且加載速度慢。此外數(shù)據(jù)庫(kù)的join操作非常方便viterbi算法中的概率計(jì)算。

數(shù)據(jù)表定義如下:

            
class Transition(BaseModel):

  __tablename__ = 'transition'

  id = Column(Integer, primary_key=True)
  previous = Column(String(1), nullable=False)
  behind = Column(String(1), nullable=False)
  probability = Column(Float, nullable=False)


class Emission(BaseModel):

  __tablename__ = 'emission'

  id = Column(Integer, primary_key=True)
  character = Column(String(1), nullable=False)
  pinyin = Column(String(7), nullable=False)
  probability = Column(Float, nullable=False)


class Starting(BaseModel):

  __tablename__ = 'starting'

  id = Column(Integer, primary_key=True)
  character = Column(String(1), nullable=False)
  probability = Column(Float, nullable=False)
          

模型生成

代碼見(jiàn)train/main.py文件,里面的init starting,init emission,init_transition分別對(duì)應(yīng)于生成隱馬爾科夫模型中的初始概率矩陣,發(fā)射概率矩陣,轉(zhuǎn)移概率矩陣,并把生成的結(jié)果寫(xiě)入sqlite文件中。訓(xùn)練用到的數(shù)據(jù)集是結(jié)巴分詞里的詞庫(kù),因?yàn)闆](méi)有訓(xùn)練長(zhǎng)句子,最后運(yùn)行的結(jié)果也證明只能適用于短句輸入。

初始概率矩陣

統(tǒng)計(jì)初始化概率矩陣,就是找出所有出現(xiàn)在詞首的漢字,并統(tǒng)計(jì)它們出現(xiàn)在詞首的次數(shù),最后根據(jù)上述數(shù)據(jù)算出這些漢字出現(xiàn)在詞首的概率,沒(méi)統(tǒng)計(jì)的漢字就認(rèn)為出現(xiàn)在詞首的概率是0,不寫(xiě)入數(shù)據(jù)庫(kù)。有一點(diǎn)注意的是為了防止概率計(jì)算的時(shí)候因?yàn)樵剿阍叫?dǎo)致計(jì)算機(jī)無(wú)法比較,所有的概率都進(jìn)行了自然對(duì)數(shù)運(yùn)算。統(tǒng)計(jì)的結(jié)果如下:

python基于隱馬爾可夫模型實(shí)現(xiàn)中文拼音輸入_第1張圖片

轉(zhuǎn)移概率矩陣

此處用到的是最簡(jiǎn)單的一階隱馬爾科夫模型,即認(rèn)為在一個(gè)句子里,每個(gè)漢字的出現(xiàn)只和它前面的的一個(gè)漢字有關(guān),雖然簡(jiǎn)單粗暴,但已經(jīng)可以滿足大部分情況。統(tǒng)計(jì)的過(guò)程就是找出字典中每個(gè)漢字后面出現(xiàn)的漢字集合,并統(tǒng)計(jì)概率。因?yàn)檫@個(gè)概率矩陣非常的大,逐條數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)過(guò)慢,后續(xù)可以優(yōu)化為批量寫(xiě)入,提高訓(xùn)練效率。結(jié)果如下:

python基于隱馬爾可夫模型實(shí)現(xiàn)中文拼音輸入_第2張圖片

上圖展示的一后面出現(xiàn)概率最高的十個(gè)字,也挺符合日常習(xí)慣。

發(fā)射概率矩陣

通俗點(diǎn)就是統(tǒng)計(jì)每個(gè)漢字對(duì)應(yīng)的拼音以及在日常情況下的使用概率,已暴舉例,它有兩個(gè)讀音:bao和pu,難點(diǎn)就是找bao和pu出現(xiàn)的概率。此處統(tǒng)計(jì)用到了pypinyin模塊,把字典中的短語(yǔ)轉(zhuǎn)換為拼音后進(jìn)行概率統(tǒng)計(jì),但是某些地方讀音也不完全正確,最后運(yùn)行的輸入法會(huì)出現(xiàn)和拼音不匹配的結(jié)果。統(tǒng)計(jì)結(jié)果如下:

python基于隱馬爾可夫模型實(shí)現(xiàn)中文拼音輸入_第3張圖片

viterbi實(shí)現(xiàn)

代碼建input_method/viterbi.py文件,此處會(huì)找到最多十個(gè)局部最優(yōu)解,注意是十個(gè)局部最優(yōu)解而不是十個(gè)全局最優(yōu)解,但是這十個(gè)解中最優(yōu)的那個(gè)是全局最優(yōu)解,代碼如下:

            
def viterbi(pinyin_list):
  """
  viterbi算法實(shí)現(xiàn)輸入法

  Aargs:
    pinyin_list (list): 拼音列表
  """
  start_char = Emission.join_starting(pinyin_list[0])
  V = {char: prob for char, prob in start_char}

  for i in range(1, len(pinyin_list)):
    pinyin = pinyin_list[i]

    prob_map = {}
    for phrase, prob in V.iteritems():
      character = phrase[-1]
      result = Transition.join_emission(pinyin, character)
      if not result:
        continue

      state, new_prob = result
      prob_map[phrase + state] = new_prob + prob

    if prob_map:
      V = prob_map
    else:
      return V
  return V
          

結(jié)果展示

運(yùn)行input_method/viterbi.py文件,簡(jiǎn)單的展示一下運(yùn)行結(jié)果:

python基于隱馬爾可夫模型實(shí)現(xiàn)中文拼音輸入_第4張圖片

問(wèn)題統(tǒng)計(jì):

統(tǒng)計(jì)字典生成轉(zhuǎn)移矩陣寫(xiě)入數(shù)據(jù)庫(kù)的速度太慢,運(yùn)行一次要將近十分鐘。發(fā)射概率矩陣數(shù)據(jù)不準(zhǔn)確,總有一些漢字的拼音不匹配。訓(xùn)練集太小,實(shí)現(xiàn)的輸入法不適用于長(zhǎng)句子。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 黄山市| 牡丹江市| 高清| 徐闻县| 广州市| 延长县| 唐河县| 镇坪县| 惠州市| 来凤县| 抚顺市| 定州市| 桃源县| 武义县| 岚皋县| 汾西县| 平阴县| 高雄市| 诸暨市| 曲水县| 承德市| 桦甸市| 蓬莱市| 晴隆县| 普安县| 麻江县| 衡阳市| 古丈县| 连平县| 东安县| 嘉祥县| 广水市| 永顺县| 武宁县| 竹山县| 黎城县| 沁源县| 通渭县| 望城县| 长武县| 郧西县|