用HMM模型进行中文分词
问题情况 中文分词任务,采用的是Sighan2004(backoff2005微软数据)数据。给出训练集和测试集,对测试集进行中文分词,要求给出的分词结果F-score尽量大。
常见解法介绍 首先是两个naive版本,但是对于这个特定的任务,虽然naive版本原理实现简单,但是效果却很好。
1.正向(逆向)最大匹配
以选出匹配的单词尽可能长为目标分词,具体操作是从一个方向不断尝试匹配出最长单词,再进行下一次匹配,直到匹配完成为止。
2.双向最大匹配
同样以选出匹配的单词尽可能长为目标分词,具体操作可以给分词结果打分,找一个合适的打分函数下,匹配单词较长且单词出现次数较多则比较合算,同时希望求解打分函数最大值的复杂度比较低。
在上一篇report中详细介绍过我的双向最大匹配实现方法,原理简单但是效果很好,是我目前能实现效果最好的一个版本。
下面有四个基于概率的版本,算法相对高级一点。
*这四个版本都把分词结果看作汉字的4-tag序列(‘S’单字,’B’词首,’E’词尾,’M’词中),那么分词转化为找到一个最合适的序列。
3.最大熵模型
最大熵模型基于4-tag,并且使得分词留下信息量最大的信念来做,用到了信息论里的一些理论基础。
4.CRF模型
CRF模型基于4-tag的随机向量场方法,用到了一些概率方法。
5.HMM模型
与CRF相似的,HMM也是基于4-tag的概率模型,HMM模型找出概率最大的一个4-tag序列作为分词结果,其中的转移概率由训练获得。
6.结构化感知器
读到有人写的源代码,但是具体还没有仔细学习过。等学习了自己实现一个专门写一篇report来阐述原理。
HMM模型原理 设 l 为序列长度, tag[0:l] 为tag序列, char[0:l] 为character序列,其中 [:] 切片用法和python一样为左闭右开区间。
P(tag[0:l]|char[0:l])=P(tag[0]|char[0] as start)?Πl?1k=1P(tag[k]|tag[k?1]char[k?1]char[k])?P(tag[l?1]|char[l?1] as end)
如果画出状态转移图像,发现状态只能在层间点转移,转移路径上的分数为概率,求一条概率最大的路径。这可以用维特比算法计算,本质上就是一个动态规划,属于很简单的算法问题。以下为我的实现。
文章图片
def mostPossibleTag(char):
char = numberFormatter(char)
l = len(char)
if l == 0:
return []
p0 = {t: getStartPro(char[0], t) for t in TAG}
tag0 = {t: [t] for t in TAG}
for i in range(1, l):
p = {t: 0 for t in TAG}
tag = {t: [] for t in TAG}
for t in TAG:
for prevT in TAG:
tranP = p0[prevT] * getTranPro(char[i-1], prevT, char[i], t)
if tranP > p[t]:
p[t] = tranP
tag[t] = tag0[prevT] + [t]
p0 = p
tag0 = tag
maxP = -1
maxT = ''
for t in TAG:
tranP = p0[t] * getEndPro(char[l-1], t)
if tranP > maxP:
maxP = tranP
maxT = t
return tag0[maxT]
具体实现 1.对于未登录词或未登录用法的处理
可以给一些字典外的字一个平均水平的估计值。例如吃馕,馕是一个生字,那么馕就作为吃后面接的字的平均水平。那么通过吃饭,吃醋等高概率出现词汇大致可以学习出吃馕是’B‘->’E‘。
但是对一些非法转移序列必须给出0分的概率(例如’S’->’M’之类的)。
还有一种情况,对于字典里常见字但是从没见过用法的组合,应该给一个很低的惩罚估计概率,例如吃饭,这个搭配很常见,但是‘E’->’B’这个组合可能从来没见过,所以再计算这个组合的时候应该给一个惩罚低概率,但是不能为0。
我的实现不是特别仔细,只大致实现了惩罚情况,仔细的实现边界条件不好处理,一直出现错误,我后来索性try except,一出现错误(汉字,用法没见过,用法次数为0之类的未登录问题)就开启惩罚估计。
2.数字和百分号小数点特殊处理
3.标点
因为标点符号必然独立成词,所以可以切开标点符号再对于每一小句切词,可以降低句子长度。
4.运算精度
如果句子比较长,概率会很小,应该取对数来计算,但是我的代码没有,因为经过了3.的切分,句子不是很长了。
测试结果
模型 | F-score |
---|---|
HMM模型 | 0.915 |
双向最大匹配 | 0.951 |
最大熵模型 | 0.839 |
CRF模型 | 0.964 |
推荐阅读
- Machine|scikit-learn-分类模型评价标准
- machine|LightGBM参数介绍
- machine|【机器学习-西瓜书】二、性能度量(召回率;P-R曲线;F1值;ROC;AUC)
- Machine|基于HMM的中文分词
- Machine|机器学习分类结果混淆矩阵 TP、TN、FP、FN 防混淆基于方法
- java|fasttext 加载模型 内存分配失败
- Virtual|安装 VMware Tools 时报 客户机操作系统已将 CD-ROM 门锁定,并且可能正在使用CD-ROM--解决方案(简单粗暴)
- GC|深入理解JVM底层实现_2 对象结构、指针引用和垃圾回收机制
- Machine|OpenCV中Canny边缘检测
- Machine|Gabor滤波器与特征提取