使用HMM實現簡單拼音輸入法

發表於2016-04-08

之前寫過一篇使用語言模型進行中文分詞的部落格,本篇在之前寫的語言模型的基礎上,通過隱馬爾科夫模型實現簡單的拼音輸入法,即輸入一組拼音,我們把它轉換成中文。

一、隱馬爾科夫模型

首先我們來說一下什麼是馬爾科夫鏈,簡單的說,任何一組我們可以觀察到的連續序列,比如連續一個星期的天氣狀況,都可以稱為馬爾科夫鏈。

馬爾科夫鏈的最主要特性是,假設當前節點的狀態(比如今天的天氣),只與之前N個連續狀態相關(比如之前一個星期的天氣狀況),通過這個性質和大量的統計,我們就可以根據最近幾天的天氣預測未來一天的天氣了。

那麼什麼是隱馬爾科夫模型呢?

比如你有一個朋友在美國,他會每天告訴你他今天做了什麼(打球、跑步或呆在家裡),你要通過他的這些活動推測過去一週內他們那邊的天氣。這裡你朋友的活動對你來說是可以觀察到的,即觀察序列,而過去一週的天氣是隱藏序列,那麼這個通過觀察序列推測隱藏序列的模型,就是隱馬爾科夫模型。

隱馬爾科夫模型的“隱”就體現在“隱藏序列”這個概念裡。

二、通過拼音推測漢字

很明顯,我們的拼音輸入法的觀察序列就是使用者的輸入拼音,比如”wo shi zhong guo ren”,我們要推測出使用者想要輸入的是“我 是 中 國 人”,這是個很典型的隱馬爾科夫模型:

hmm1

如上圖所示,我們根據給定的觀察物件O,獲得一個概率最大的序列S*。我們所知道的資料有:

1, 所有觀察物件的值

2, 隱藏序列的馬爾科夫模型概率,這是通過統計獲得的

3, 隱藏狀態到觀察狀態的概率,比如 “晴天”(隱藏狀態) 到 “出去玩”(觀察狀態)的概率

我們要求的是S*各個狀態的連續概率最大的那個序列。

三、前向概率Viterbi演算法

我們把隱藏序列中的一個節點的每一種可能取值都畫出來的話,我們會發現這其實是一個有向圖尋找最優路徑的問題:

viterbi

H、O、S都是當前節點可能的取值(比如hao拼音可能有好、號、耗等漢字)。而對於這種尋找最優路徑的問題,我們可以通過動態規劃的思想去考慮,假設σt(k)表示第t個位置對應的漢字是k,s表示隱藏序列,o表示觀察序列,M表示當前隱藏節點的可能取值,那麼:

viterbi2

上式中的表示從隱藏節點k到觀察序列t+1的發射概率,α_{l,k}表示l到k的馬爾科夫狀態轉移概率。

寫出了遞迴式,這個動態規劃程式就容易寫了。

四、實現

既然我們是一個有向圖,那麼閒來構造圖中的所有節點:


核心的viterbi演算法為:


由於完整程式碼牽扯的東西太多,包括語言模型、漢字拼音對映表,這裡就不在全部貼出來了,不過有了上面兩部分程式碼,其實其他的也很容易謝了,就是載入進去而已。如有興趣可以聯絡我索取相關完整程式碼。

輸出效果:


第一組輸入的有一個錯字,主要是因為語料庫不夠完善,可能“入法”兩個字的概率小於“入發”兩個字了,不是大問題。

由於找我發郵件要程式碼的人太多…我覺得還是直接放在 這裡 讓大家下載吧,不過程式碼都是demo性質的,只為實現效果,切勿放到真實環境執行。

相關文章