HMM 拼音輸入法


拼音輸入法案例

https://zhuanlan.zhihu.com/p/25132270

https://github.com/LiuRoy/Pinyin_Demo

在網上看到一篇關於隱馬爾科夫模型的介紹,覺得簡直不能再神奇,又在網上找到大神的一篇關於如何用隱馬爾可夫模型實現中文拼音輸入的博客,無奈大神沒給可以運行的代碼,只能純手動網上找到了結巴分詞的詞庫,根據此訓練得出隱馬爾科夫模型,用維特比算法實現了一個簡單的拼音輸入法。githuh地址:LiuRoy/Pinyin_Demo

 

原理簡介

隱馬爾科夫模型

抄一段網上的定義:

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

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

viterbi算法

參考https://zh.wikipedia.org/wiki/維特比算法,思想是動態規划,代碼比較簡單就不贅述。

 

優化版

https://github.com/fanqingsong/pinyin_input_method

模型訓練

在 corpus 目錄中, 保存了一份 dict.txt, 為刪減版本的jieba詞庫。

此詞庫為默認訓練詞庫。

另外一個為 dict.backup.txt為原來repo的詞庫, 太大,訓練時間太長。 所以調試階段不適用。

模型所在數據庫有也對應兩個 hmm.sqlite hmm.backup.sqlite

運行命令

./bin/run.sh hmm/train.py

 

viterbi實現

代碼建hmm/viterbi.py文件,此處會找到最多十個局部最優解,注意是十個局部最優解而不是十個全局最優解,但是這十個解中最優的那個是全局最優解,代碼如下:

def viterbi(pinyin_list): """  viterbi算法實現輸入法   Args:  pinyin_list (list): 拼音列表  """ # query the char-prob pair # char must in starting table, named as start_char # prob = start_char prob * emit_prob # emit_prob is the probability that start_char emit to the start_pinyin start_pinyin = pinyin_list[0] start_char = Emission.join_starting(start_pinyin) print("------ start_char -------") print(start_char) V = {char: prob for char, prob in start_char} print("------ V -------") print(V) print("\r\n") # let's count from the second pinyin to calc viterbi matrix for i in range(1, len(pinyin_list)): pinyin = pinyin_list[i] print("------ i -------") print(i) print("------ pinyin -------") print(pinyin) prob_map = {} for phrase, prob in V.iteritems(): print("------ phrase -------") print(phrase) print("------ prob -------") print(prob) prev_char = phrase[-1] # only get the most possible next_char, with highest probability result = Transition.join_emission(pinyin, prev_char) print("------ result -------") print(result) if not result: continue # next_prob = transfer probability(pre_char -> next_char) * emission probability(next_char -> pinyin) next_char, next_prob = result print("-------- next_char --------") print(next_char) # make new V of new char path, ie phrase. prob_map[phrase + next_char] = next_prob + prob if prob_map: # update V, in order to do further research V = prob_map else: return V print("\r\n") return V

 

結果展示

運行文件,簡單的展示一下運行結果:

./bin/run.sh hmm/viterbi.py

輸出

root@xxx:~/win10/mine/pinyin_input_method# ./bin/run.sh hmm/viterbi.py
PYTHONPATH=/usr/local/spark/python:/usr/local/spark/python/lib/py4j-0.10.4-src.zip::/root/win10/mine/pinyin_input_method
input:duan yu
------ start_char -------
[(u'\u77ed', -8.848355540206123), (u'\u6bb5', -8.848355540206123)]
------ V -------
{u'\u6bb5': -8.848355540206123, u'\u77ed': -8.848355540206123}


------ i -------
1
------ pinyin -------
yu
------ phrase -------
段
------ prob -------
-8.84835554021
------ result -------
(u'\u8a89', -0.1840036429769394)
-------- next_char --------
譽
------ phrase -------
短
------ prob -------
-8.84835554021
------ result -------
(u'\u8bed', 0.0)
-------- next_char --------
語


短語 -8.84835554021
段譽 -9.03235918318
input:
bye bye

 

 

漢字轉拼音(pypinyin)

https://github.com/mozillazg/python-pinyin

>>> from pypinyin import pinyin, lazy_pinyin, Style
>>> pinyin('中心')
[['zhōng'], ['xīn']]
>>> pinyin('中心', heteronym=True)  # 啟用多音字模式
[['zhōng', 'zhòng'], ['xīn']]
>>> pinyin('中心', style=Style.FIRST_LETTER)  # 設置拼音風格
[['z'], ['x']]
>>> pinyin('中心', style=Style.TONE2, heteronym=True)
[['zho1ng', 'zho4ng'], ['xi1n']]
>>> pinyin('中心', style=Style.TONE3, heteronym=True)
[['zhong1', 'zhong4'], ['xin1']]
>>> pinyin('中心', style=Style.BOPOMOFO)  # 注音風格
[['ㄓㄨㄥ'], ['ㄒㄧㄣ']]
>>> lazy_pinyin('中心')  # 不考慮多音字的情況
['zhong', 'xin']
>>> lazy_pinyin('戰略', v_to_u=True)  # 不使用 v 表示 ü
['zhan', 'lüe']
# 使用 5 標識輕聲
>>> lazy_pinyin('衣裳', style=Style.TONE3, neutral_tone_with_five=True)
['yi1', 'shang5']

 

jieba詞庫

https://github.com/fxsjy/jieba/tree/master/jieba

算法

  • 基於前綴詞典實現高效的詞圖掃描,生成句子中漢字所有可能成詞情況所構成的有向無環圖 (DAG)
  • 采用了動態規划查找最大概率路徑, 找出基於詞頻的最大切分組合
  • 對於未登錄詞,采用了基於漢字成詞能力的 HMM 模型,使用了 Viterbi 算法

https://raw.githubusercontent.com/fxsjy/jieba/master/jieba/dict.txt

AT&T 3 nz
B超 3 n
c# 3 nz
C# 3 nz
c++ 3 nz
C++ 3 nz
T恤 4 n
A座 3 n
A股 3 n
A型 3 n
A輪 3 n
AA制 3 n
AB型 3 n
B座 3 n
B股 3 n
B型 3 n
B超 3 n
B輪 3 n
BB機 3 n
BP機 3 n
C盤 3 n
C座 3 n
C語言 3 n
CD盒 3 n
CD機 3 n
CALL機 3 n
D盤 3 n
D座 3 n
D版 3 n
E盤 3 n
E座 3 n
E化 3 n
E通 3 n
F盤 3 n
F座 3 n
G盤 3 n
H盤 3 n
H股 3 n
I盤 3 n
IC卡 3 n
IP卡 3 n
IP電話 3 n
IP地址 3 n
K黨 3 n
K歌之王 3 n
N年 3 n
O型 3 n
PC機 3 n
PH值 3 n
SIM卡 3 n
U盤 3 n
VISA卡 3 n
Z盤 3 n
Q版 3 n
QQ號 3 n
RSS訂閱 3 n
T盤 3 n

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM