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

2021-08-13 08:51:13 字數 3125 閱讀 7656

抄一段網上的定義:

隱馬爾可夫模型 (hidden markov 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分別對應於生成隱馬爾科夫模型中的初始概率矩陣,發射概率矩陣,轉移概率矩陣,並把生成的結果寫入sqlite檔案中。訓練用到的資料集是結巴分詞裡的詞庫,因為沒有訓練長句子,最後執行的結果也證明只能適用於短句輸入。

初始概率矩陣

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

轉移概率矩陣

此處用到的是最簡單的一階隱馬爾科夫模型,即認為在乙個句子裡,每個漢字的出現只和它前面的的乙個漢字有關,雖然簡單粗暴,但已經可以滿足大部分情況。統計的過程就是找出字典中每個漢字後面出現的漢字集合,並統計概率。因為這個概率矩陣非常的大,逐條資料寫入資料庫過慢,後續可以優化為批量寫入,提高訓練效率。結果如下:

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

發射概率矩陣

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

**建input_method/viterbi.py檔案,此處會找到最多十個區域性最優解,注意是十個區域性最優解而不是十個全域性最優解,但是這十個解中最優的那個是全域性最優解,**如下:

def

viterbi(pinyin_list):

"""viterbi演算法實現輸入法

aargs:

pinyin_list (list): 拼音列表

"""start_char =emission.join_starting(pinyin_list[0])

v =

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)

ifnot

result:

continue

state, new_prob =result

prob_map[phrase + state] = new_prob +prob

ifprob_map:

v =prob_map

else

:

return

v

return v

執行input_method/viterbi.py檔案,簡單的展示一下執行結果:

問題統計:

統計字典生成轉移矩陣寫入資料庫的速度太慢,執行一次要將近十分鐘。

發射概率矩陣資料不準確,總有一些漢字的拼音不匹配。

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

馬爾科夫模型與隱馬爾科夫模型

隨機過程 是隨時間而隨機變化的過程。又稱為隨機函式。馬爾科夫模型 vmm 它描述了一類重要的隨機過程。乙個系統有有限個狀態集s 隨時間推移,該系統將同某一狀態轉移到另一狀態。q s1,s2,sn 為一隨機變數序列,隨機變數取值為狀態集s中的乙個狀態,設時間t時狀態為qt。對系統的描述通常是給出當前時...

隱馬爾科夫模型

隱馬爾科夫 hiddenmarkov model 簡稱為hmm,hmm資料相當豐富,推薦參見 hmm學習最佳範例與崔曉源的部落格 一文,本文只對hmm進行簡要介紹,然後說明開源ghmm實現在linux環境的搭建,hmm的開源實現有眾多不同語言的實現。馬爾科夫模型 一階馬爾科夫模型假設為 1 t l時...

隱馬爾科夫模型

一 介紹 introduction 我們通常都習慣尋找乙個事物在一段時間裡的變化模式 規律 這些模式發生在很多領域,比如計算機中的指令序列,句子中的詞語順序和口語單詞的因素修咧等等,事實上任何領域中的一系列事件都有可能產生有用的模式。考慮乙個簡單的例子,有人試圖通過一片海藻推斷天氣 民間傳說告訴我們...