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分词器。

posted @ 2016-01-14 22:28  StevenLuke  阅读(113)  评论(0编辑  收藏  举报