用隱馬爾科夫模型 python 實現簡單拼音輸入法

姓名:唐來賓? 學號:17101223417

轉載

http://mp.weixin.qq.com/s/bATbcnF-SO-sYClgNLHngw

【嵌牛鼻子】拼音輸入,隱馬爾可夫模型

【嵌牛導讀】隱馬爾可夫模型 (Hidden Markov Model) 是一種統計模型,用來描述一個含有隱含未知參數的馬爾可夫過程焚刺。其難點是從可觀察的參數中確定該過程的隱含參數,然后利用這些參數來作進一步的分析稠歉。拼音輸入法中可觀察的參數就是拼音名惩,隱含的參數就是對應的漢字碟摆。

【嵌牛提問】如何學好算法述暂?

【嵌牛正文】在網上看到一篇關于隱馬爾科夫模型的介紹痹升,覺得簡直不能再神奇,又在網上找到大神的一篇關于如何用隱馬爾可夫模型實現中文拼音輸入的博客(http://sobuhu.com/ml/2013/03/07/hmm-pinyin-input-method.html)畦韭,無奈大神沒給可以運行的代碼视卢,只能純手動網上找到了結巴分詞的詞庫,根據此訓練得出隱馬爾科夫模型廊驼,用維特比算法實現了一個簡單的拼音輸入法据过。githuh地址:https://github.com/LiuRoy/Pinyin_Demo

原理簡介

隱馬爾科夫模型

抄一段網上的定義:

隱馬爾可夫模型 (Hidden Markov Model) 是一種統計模型,用來描述一個含有隱含未知參數的馬爾可夫過程妒挎。其難點是從可觀察的參數中確定該過程的隱含參數绳锅,然后利用這些參數來作進一步的分析。

拼音輸入法中可觀察的參數就是拼音酝掩,隱含的參數就是對應的漢字鳞芙。

viterbi算法

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

代碼解釋

model定義

代碼見model/table.py文件,針對隱馬爾科夫的三個概率矩陣镶苞,分別設計了三個數據表存儲喳坠。這樣的好處很明顯,漢字的轉移概率矩陣是一個非常大的稀疏矩陣茂蚓,直接文件存儲占用空間很大壕鹉,并且加載的時候也只能一次性讀入內存,不僅內存占用高而且加載速度慢聋涨。此外數據庫的join操作非常方便viterbi算法中的概率計算晾浴。

數據表定義如下:

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)

模型生成

代碼見train/main.py文件,里面的initstarting牍白,initemission脊凰,init_transition分別對應于生成隱馬爾科夫模型中的初始概率矩陣,發(fā)射概率矩陣茂腥,轉移概率矩陣狸涌,并把生成的結果寫入sqlite文件中。訓練用到的數據集是結巴分詞里的詞庫础芍,因為沒有訓練長句子杈抢,最后運行的結果也證明只能適用于短句輸入数尿。

初始概率矩陣

統計初始化概率矩陣仑性,就是找出所有出現在詞首的漢字,并統計它們出現在詞首的次數右蹦,最后根據上述數據算出這些漢字出現在詞首的概率诊杆,沒統計的漢字就認為出現在詞首的概率是0歼捐,不寫入數據庫。有一點注意的是為了防止概率計算的時候因為越算越小導致計算機無法比較晨汹,所有的概率都進行了自然對數運算豹储。統計的結果如下:

圖片發(fā)自簡書App

轉移概率矩陣

此處用到的是最簡單的一階隱馬爾科夫模型,即認為在一個句子里淘这,每個漢字的出現只和它前面的的一個漢字有關剥扣,雖然簡單粗暴,但已經可以滿足大部分情況铝穷。統計的過程就是找出字典中每個漢字后面出現的漢字集合钠怯,并統計概率。因為這個概率矩陣非常的大曙聂,逐條數據寫入數據庫過慢晦炊,后續(xù)可以優(yōu)化為批量寫入,提高訓練效率宁脊。結果如下:

上圖展示的一后面出現概率最高的十個字断国,也挺符合日常習慣。

發(fā)射概率矩陣

通俗點就是統計每個漢字對應的拼音以及在日常情況下的使用概率榆苞,已暴舉例稳衬,它有兩個讀音:bao和pu,難點就是找bao和pu出現的概率坐漏。此處統計用到了pypinyin模塊宋彼,把字典中的短語轉換為拼音后進行概率統計,但是某些地方讀音也不完全正確仙畦,最后運行的輸入法會出現和拼音不匹配的結果输涕。統計結果如下:

圖片發(fā)自簡書App

viterbi實現

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

def viterbi(pinyin_list):

? ? """

? ? viterbi算法實現輸入法

? ? 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

結果展示

運行input_method/viterbi.py文件寸士,簡單的展示一下運行結果:

圖片發(fā)自簡書App


問題統計:

統計字典生成轉移矩陣寫入數據庫的速度太慢檐什,運行一次要將近十分鐘。

發(fā)射概率矩陣數據不準確弱卡,總有一些漢字的拼音不匹配乃正。

訓練集太小,實現的輸入法不適用于長句子婶博。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末瓮具,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌名党,老刑警劉巖叹阔,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異传睹,居然都是意外死亡耳幢,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門欧啤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睛藻,“玉大人,你說我怎么就攤上這事邢隧⌒薜担” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵府框,是天一觀的道長吱窝。 經常有香客問我,道長迫靖,這世上最難降的妖魔是什么院峡? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮系宜,結果婚禮上照激,老公的妹妹穿的比我還像新娘。我一直安慰自己盹牧,他們只是感情好俩垃,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著汰寓,像睡著了一般口柳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上有滑,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天跃闹,我揣著相機與錄音,去河邊找鬼毛好。 笑死望艺,一個胖子當著我的面吹牛,可吹牛的內容都是我干的肌访。 我是一名探鬼主播找默,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吼驶!你這毒婦竟也來了惩激?” 一聲冷哼從身側響起店煞,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咧欣,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體轨帜,經...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡魄咕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了蚌父。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哮兰。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖苟弛,靈堂內的尸體忽然破棺而出喝滞,到底是詐尸還是另有隱情,我是刑警寧澤膏秫,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布右遭,位于F島的核電站,受9級特大地震影響缤削,放射性物質發(fā)生泄漏窘哈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一亭敢、第九天 我趴在偏房一處隱蔽的房頂上張望滚婉。 院中可真熱鬧,春花似錦帅刀、人聲如沸让腹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽骇窍。三九已至,卻和暖如春锥余,著一層夾襖步出監(jiān)牢的瞬間像鸡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工哈恰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留只估,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓着绷,卻偏偏與公主長得像蛔钙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子荠医,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內容