基于HMM的分词算法


实现代码传送门

HMM的相关原理参考我的上一篇笔记:标注算法-HMM

下面以中文分词demo作为例子,介绍HMM在分词我任务中的应用。

1. 预处理

1.1. 训练集选择

推荐采用人民日报的词性标注语料集。

目前有2014版和1998版,前者语料库规模比后者的大,后者为人工标注版本,前者精度上相比要差一些,但前者的语料较为鲜活,与当前主流的中文书写习惯更为接近。

这里采用2014版语料集,该语料的其中一行如下:

人民网/nz 1月1日/t 讯/ng 据/p 《/w [纽约/nsf 时报/n]/nz 》/w 报道/v ,/w 美国/nsf 华尔街/nsf 股市/n 在/p 2013年/t 的/ude1 最后/f 一天/mq 继续/v 上涨/vn ,/w 和/cc [全球/n 股市/n]/nz 一样/uyy ,/w 都/d 以/p [最高/a 纪录/n]/nz 或/c 接近/v [最高/a 纪录/n]/nz 结束/v 本/rz 年/qt 的/ude1 交易/vn 。/w 

原始语料包含了词性标注,由于这里只用于分词任务,故需要先将其词性标签去除。

在处理的时候,有一个点需要特别注意,该语料集有两种细粒度可供选择,如 [纽约/nsf 时报/n]/nz,这表示既可以切分为 纽约时报 一个单词,也可以切分为 纽约时报 两个单词。

本文采用了细粒度更小的后者。

1.2. 标注方式

中文分词字标注通常有2-tag、4-tag和6-tag这几种方法,其中,又以4-tag标注最为常用

  • 2-tag

    标注集合为{B,I},其将词首标记设计为B,而将词的其他位置标记设计为I。

    中/B 华/I 人/B 民/I 共/B 和/I 国/I

    即标记“切分/不切分”就够了,优点是模型简单,训练速度较快;缺点是对语义规律的总结是片面的,导致模型的准确率较低

  • 4-tag

    标注集合为{S,B,M,E},S表示单字为词,B表示词的首字,M表示词的中间字,E表示词的结尾字。

    中/B 华/M 人/B 民/M 共/B 和/M 国/E

    优点是一定程度上总结语义规律,兼顾了2-tag和6-tag的特点,即使是使用分词效果一般的HMM模型,也可以得到不错的效果。

  • 6-tag

    标注集合为{S,B,M1,M2,M,E},S表示单字为词,B表示词的首字,M1/M2/M表示词的中间字,E表示词的结尾字。

    中/B 华/M1 人/M2 民/M 共/M 和/M 国/E

    优点是进一步总结了语义规律,更加易于发现长词;缺点是其对更多的字的位置进行了固定,需要大量的训练集支撑训练结果。

本文采用4-tag标注方式

1.3. 文本存储格式

常用的存储格式为

char1<break1>tag1<break2>char2<break1>tag2<break2>...

其中,break<n> 为第n级分割符,特别地,break1 是1级分割符,表示单词和标记符号间的分割;break2 是2级分割符,表示单词间的分割;break3 是3级分割符,表示段落间的分割,以此列推。

常用如下两套分割方案

  • break1='/', break2=' ', break3='\n', break4='\n\n', ...(每增加一个大纲级别,增加一个回车符,以此列推),例如

    祝/S 伟/B 大/E 祖/B 国/E 繁/B 荣/M 昌/M 盛/E !/S 
    祝/S 全/B 区/E 各/B 族/E 人/B 民/E 在/S 新/B 的/E 一/B 年/E 里/S 幸/B 福/E 安/B 康/E 、/S 扎/B 西/E 德/B 勒/E !/S
  • break1='\t', break2='\n', break3='\n\n', break4='\n\n\n', ...(每增加一个大纲级别,增加一个回车符,以此列推),例如

    祝	S
    伟	B
    大	E
    祖	B
    国	E
    繁	B
    荣	M
    昌	M
    盛	E
    !	S

本文采用第二种存储格式

2. 模型设计

一些参数的具体取值如下:

  • Q={'B', 'M', 'E', 'S'}, V={所有字符的集合}
  • OI 表示每次输入的序列,例如,O='祝伟大祖国繁荣昌盛!', I='SBEBEBMMES'
  • N=len(Q), M=len(V), S=len(seq)

2.1. 未知参数学习

因为是有监督学习,所以直接按照公式求解三元组 \((A,B,\pi)\) 即可

特别地,在后面结果预测的步骤中有乘法操作,为了防止向下溢出,下面展示的最终结果都经过了 \(\log\) 对数处理,其中 \(\log 0\)\(-1e^{-9}\) 代替无穷小。

2.1.1. 初始状态\(\pi\)

\[ \pi_k = \log \frac{\sum_S(i_1=q_k)}{S} \]

训练结果

B	-0.35712716996161437
M	-1000000000.0
E	-1000000000.0
S	-1.2029184049041823

2.1.2. 转移概率矩阵 \(A\)

\[ a_{i j}=\log \frac{A_{i j}}{\sum_{j=1}^{N} A_{i j}} \]

训练结果

	B	M	E	S
B	-1000000000.0	-1000000000.0	-0.684810767901495	-0.7551392365415603
M	-0.3996402748676947	-1.1103647401125116	-1000000000.0	-1000000000.0
E	-0.16180464296111247	-1.9011772741974273	-1000000000.0	-1000000000.0
S	-1000000000.0	-1000000000.0	-0.5258124050930225	-0.92759081040002

事实上,实际训练中可能只能提供只有词频的训练集,一部分转移概率会无法计算。这里提供一个大概的估计方案(具体出处忘了 -_-||) \[ a_{(s|s)}=a_{(s|e)} = \pi_s\\a_{(b|s)} = a_{(b|e)} = \pi_b \] 另外,苏神在 字标注法与HMM模型 一文中给出了一个经验取值,这里也可以参考一下 \[ a_{(s|s)}=a_{(s|e)} = 0.3 \\a_{(b|s)} = a_{(b|e)} = 0.7 \]

2.1.3. 观测概率矩阵 \(B\)

\[ b_{j}(k)=\log \frac{B_{j k}}{\sum_{k=1}^{M} B_{j k}} \]

训练结果

	B	M	E	S
1	-4.518497982335498	-3.0320559244452023	-6.657433764192848	-6.537725478359201
纽	-8.661834062535963	-10.266377393929087	-10.24185808976377	-11.342070025548505
时	-5.649817195217472	-5.929086653096597	-5.321189787834555	-5.718670228629817
报	-5.890738992552965	-6.927055415985019	-6.088823142305065	-8.059478386294197
...

2.2. 结果预测

采用维特比算法对结果进行预测

由于前面参数都已经取 \(\log\) 对数,所以下面相应的步骤也由乘法操作改为加法操作;原流程是递归的,下面改为循环,结果等价

流程伪代码如下:

  1. Input:

    单词序列 \(O = \{o_1,...,o_T\}\)

    所有的可能状态序列 \(Q=\{q_1,...,q_N\}\)

    三元组 \((A,B,\pi)\)

  2. Init:

    \(\text{for} \quad i \quad \text{in} \quad \{1,...,N\}\)

    • \(\delta_1 = \pi_i + b_i(o_1)\)

    • \(\Psi_1(i)= \{i\}\)

  3. Loop:

    \(\text{for} \quad t \quad \text{in} \quad \{2,...,T\}\)

    • \(\text{for} \quad i \quad \text{in} \quad \{1,...,N\}\)
      • \(\delta_t(i) = \max_{1\leq j \leq N} [\delta_{t-1}(j) + a_{ji}] + b_i(o_t)\)
      • \(\Psi_t(i) =\Psi_{t-1}(i)+ \{\arg \max_{1\leq j \leq N} [\delta_{t-1}(j) + a_{ji}] \}\)
  4. Output:

    预测状态序列 \(I=\Psi_T(\arg \max_{1 \leq i \leq N} \delta_T(i))\)

3. 分词效果展示

['结婚', '和', '尚未', '结婚', '的', '人']
['隐马尔', '可夫', '模型', '中有', '两个', '序列', ',', '一个', '是', '状态', '序列', ',', '另一个', '是', '观测', '序列', ',', '其中', '状态', '序列', '是', '隐藏', '的', '。']

可以看出,基于HMM的分词,基本满足简单的分词需求,但其分词效果并不是很完美,可以看出 隐马尔可夫 这个新词并未被分出来,中有 这个词明显分词错误。

4. references

《统计学习方法》第10章,李航

字标注法与HMM模型


评论
  目录