A Pure-HMM 分词器
先介绍一下使用的资源,分词使用的语料来自于SIGHAN Bakeoff 2005的 icwb2-data.rar,《中文分词入门之资源》里有很详细的介绍:
/icwb2-data.rar/training/msr_training.utf8? 用以训练HMM,其中包含已分词汇约2000000个
/icwb2-data.rar/testing/pku_test.utf8?????????? 测试集
/icwb2-data.rar/scripts/score?????????????????????????? 一个perl脚本,测试分词效果
???????? 我们使用经典的字符标注模型,首先需要确定标注集,在前面的介绍中,我们使用的是{B,E}的二元集合,研究表明基于四类标签的字符标注模型明显优于两类标签,原因是两类标签过于简单而损失了部分信息。四类标签的集合是 {B,E,M,S},其含义如下:
B:一个词的开始
E:一个词的结束
M:一个词的中间
S:单字成词
举例:你S现B在E应B该E去S幼B儿M园E了S
用四类标签为msr_training.utf8做好标记后,就可以开始用统计的方法构建一个HMM。我们打算构建一个2-gram(bigram)语言模型,也即一个1阶HMM,每个字符的标签分类只受前一个字符分类的影响。现在,我们需要求得HMM的状态转移矩阵 A 以及混合矩阵 B。其中:
???????????????????????????????????? Aij = P(Cj|Ci) ?= ?P(Ci,Cj) / P(Ci) = Count(Ci,Cj) / Count(Ci)
???????????????????????????????????? Bij = P(Oj|Ci)? =? P(Oj,Ci) / P(Ci) = Count(Oj,Ci) / Count(Ci)
公式中C = {B,E,M,S},O = {字符集合},Count代表频率。在计算Bij时,由于数据的稀疏性,很多字符未出现在训练集中,这导致概率为0的结果出现在B中,为了修补这个问题,我们采用加1的数据平滑技术,即:
???????????????????????????????????? Bij = P(Oj|Ci)? =? (Count(Oj,Ci) + 1)/ Count(Ci)
???????? 这并不是一种最好的处理技术,因为这有可能低估或高估真实概率,更加科学的方法是使用复杂一点的Good—Turing技术,这项技术的的原始版本是图灵当年和他的助手Good在破解德国密码机时发明的。求得的矩阵A如下:
??????? B?????? M??????????????????? E????????????? S
B? 0.0 | 0.19922840916814916 | 0.8007715908318509 | 0.0
M? 0.0 | 0.47583202978061256 | 0.5241679702193874 | 0.0
E? 0.6309567616935934 | 0.0 | 0.0 | 0.36904323830640656
S? 0.6343402140354506 | 0.0 | 0.0 | 0.36565844303914763
矩阵中出现的概率为0的元素表明B-B, B-S, M-B, M-S, E-M, E-E, S-M, S-E这8种组合是不可能出现的。这是合乎逻辑的。求得的矩阵B,部分如下:
?? o1?????????????? o2??????????? o3??????????????? o4
B 7.8127868094E-7 1.460991186336E-4 0.007293548529516 6.047041844505E-4……
M ……
E …….
S ……
我们设定初始向量Pi = {0.5, 0.0, 0.0, 0.5}(M和E不可能出现在句子的首位)。至此,HMM模型构建完毕。其实用统计方法构建HMM并不复杂,麻烦的是写程序,特别是需要将分类标签和字符集合进行编码,这是个极其繁琐的过程。
我用的JAVA写程序,因此使用的Jahmm这个开源项目来进行相关的计算,对于一个HMM模型,现在我们可以写入一个观察序列,用Viterbi算法获得一个隐藏序列(分词结果)。具体做法是(举例为虚构):
1 . 对测试集按标点符号,空格,换行符拆分为一条一条的只包含字符的单句:
……
中共中央***
国家主席
……
2. 将句子转化为对应的编码,也即观察序列:
……
101 121 101 47 1010 32 1992
332 3241 893 2111
……
3. 输入观察序列,使用Viterbi算法输出隐藏序列(0:B,1:M,2:E,3:S)
……
0112333
0202
……
4. 输出最终分词结果:
……
中共中央/总/书/记
国家/主席
……
现在我们在对测试集pku_test.utf8分词,并用perl脚本进行评测,结果如下=== SUMMARY:
=== TOTAL INSERTIONS:?? ?5627
=== TOTAL DELETIONS:?? ?10639
=== TOTAL SUBSTITUTIONS:?? ?18194
=== TOTAL NCHANGE:?? ?34460
=== TOTAL TRUE WORD COUNT:?? ?104372
=== TOTAL TEST WORD COUNT:?? ?99360:
=== TOTAL TRUE WORDS RECALL:? 0.724 ? 正确切分出的词的数目/应切分出的词的总数
=== TOTAL TEST WORDS PRECISION: 0.760? 正确切分出的词的数目/切分出的词的总数
=== F MEASURE:????? 0.742 ? F1 = 2 * Precision*Recall / (Precision + Recall)
=== OOV Recall Rate:?? ?0.250????? 未登录词召回率
精度为:76%,召回为:72.4%。一个不太让人满意的结果,我们来看看他都干了些什么:
??????????????????????????????????????????????????????? 改判/被/告人/死/刑立/即/执行
这是一个较典型的例子,可见分词结果中出现了“告人”,“刑立”等字典中不存在的词,这些是由于HMM分词的“自由度”太大造成的,当然这种较大的“自由度”也有好处,比如:
??????????????????????????????????????????????????????? 检察院/鲍绍坤/检察/长
???????? 看!HMM成功的识别出一个人名,这是基于词典的分词方法做不到的。实际上,在ICTCLAS系统中(2004)就是用的HMM来识别人名。下一节将会介绍一个基于词典的混合HMM分词器。