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
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‘]
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
原文:https://www.cnblogs.com/lightsong/p/14690240.html