隱馬爾科夫模型
隱馬爾可夫模型 (Hidden Markov Model) 是一種統計模型,用來描述一個含有隱含未知參數的馬爾可夫過程。其難點是從可觀察的參數中確定該過程的隱含參數,然后利用這些參數來作進一步的分析。
拼音輸入法中可觀察的參數就是拼音,隱含的參數就是對應的漢字。
那么我們要解決的就是隱馬爾可夫的第二個問題:由觀察序列求最優的隱藏序列
只需要HMM的三個要素(π,A,B)
參考別人github代碼:
https://github.com/LiuRoy/Pinyin_Demo
代碼解析如下:
1、模型生成
代碼見train/main.py文件,里面的initstarting,initemission,init_transition分別對應於生成隱馬爾科夫模型中的初始概率矩陣,發射概率矩陣,轉移概率矩陣,並把生成的結果寫入sqlite文件中。
訓練用到的數據集是結巴分詞里的詞庫,因為沒有訓練長句子,最后運行的結果也證明只能適用於短句輸入。
2、初始概率矩陣(π)
統計初始化概率矩陣,就是找出所有出現在詞首的漢字,並統計它們出現在詞首的次數,最后根據上述數據算出這些漢字出現在詞首的概率,沒統計的漢字就認為出現在詞首的概率是0,不寫入數據庫。有一點注意的是為了防止概率計算的時候因為越算越小導致計算機無法比較,所有的概率都進行了自然對數運算。統計的結果如下:
3、轉移概率矩陣(A)
此處用到的是最簡單的一階隱馬爾科夫模型,即認為在一個句子里,每個漢字的出現只和它前面的的一個漢字有關,雖然簡單粗暴,但已經可以滿足大部分情況。統計的過程就是找出字典中每個漢字后面出現的漢字集合,並統計概率。因為這個概率矩陣非常的大,逐條數據寫入數據庫過慢,后續可以優化為批量寫入,提高訓練效率。結果如下:
上圖展示的一后面出現概率最高的十個字,也挺符合日常習慣。
4、發射概率矩陣(B)
通俗點就是統計每個漢字對應的拼音以及在日常情況下的使用概率,已暴舉例,它有兩個讀音:bao和pu,難點就是找bao和pu出現的概率。此處統計用到了pypinyin模塊,把字典中的短語轉換為拼音后進行概率統計,但是某些地方讀音也不完全正確,最后運行的輸入法會出現和拼音不匹配的結果。統計結果如下:
5、viterbi算法實現:
代碼建input_method/viterbi.py文件,此處會找到最多十個局部最優解,注意是十個局部最優解而不是十個全局最優解,但是這十個解中最優的那個是全局最優解,代碼如下:
6、結果展示
運行input_method/viterbi.py文件,簡單的展示一下運行結果:
問題統計:
- 統計字典生成轉移矩陣寫入數據庫的速度太慢,運行一次要將近十分鍾。
- 發射概率矩陣數據不准確,總有一些漢字的拼音不匹配。
- 訓練集太小,實現的輸入法不適用於長句子。
別人訓練好的 hmm 拼音輸入法代碼:
本博客摘抄如下博客:
https://github.com/THUzhangga/HMM_shurufa
https://github.com/LiuRoy/Pinyin_Demo