ITPub博客

首页 > 人工智能 > 自然语言 > 开源自然语言处理工具包hanlp中CRF分词实现详解

开源自然语言处理工具包hanlp中CRF分词实现详解

自然语言 作者:adnb34g 时间:2019-02-27 09:55:04 1 删除 编辑

 

CRF 简介

CRF 是序列标注场景中常用的模型,比 HMM 能利用更多的特征,比 MEMM 更能抵抗标记偏置的问题。

[gerative-discriminative.png] 

CRF 训练

这类耗时的任务,还是交给了用 C++ 实现的 CRF++ 。关于 CRF++ 输出的 CRF 模型,请参考《 CRF++ 模型格式说明》。  

CRF 解码

解码采用维特比算法实现。并且稍有改进,用中文伪码与白话描述如下:

首先任何字的标签不仅取决于它自己的参数,还取决于前一个字的标签。但是第一个字前面并没有字,何来标签?所以第一个字的处理稍有不同,假设第 个字的标签为 X ,遍历 X 计算第一个字的标签,取分数最大的那一个。

如何计算一个字的某个标签的分数呢?某个字根据 CRF 模型提供的模板生成了一系列特征函数,这些函数的输出值乘以该函数的权值最后求和得出了一个分数。该分数只是“点函数”的得分,还需加上“边函数”的得分。边函数在本分词模型中简化为 f(s ’ ,s) ,其中 s ’为前一个字的标签, s 为当前字的标签。于是该边函数就可以用一个 4*4 的矩阵描述,相当于 HMM 中的转移概率。

实现了评分函数后,从第二字开始即可运用维特比后向解码,为所有字打上 BEMS 标签。  

实例

还是取经典的 “商品和服务”为例,首先 HanLP 的 CRFSegment 分词器将其拆分为一张表:

 

null 表示分词器还没有对该字标注。

代码

上面说了这么多,其实我的实现非常简练:


 

 

 


标注结果

标注后将 table打印出来:

 

最终处理

 

将 BEMS 该合并的合并,得到:

[ 商品 /null, 和 /null, 服务 /null]

然后将词语送到词典中查询一下,没查到的暂时当作 nx ,并记下位置(因为这是个新词,为了表示它的特殊性,最后词性设为 null ),再次使用维特比标注词性:

[ 商品 /n, 和 /cc, 服务 /vn]

新词识别

 

CRF 对新词有很好的识别能力,比如:

CRFSegment segment = new CRFSegment();

segment.enablePartOfSpeechTagging(true);

System.out.println(segment.seg(" 你看过穆赫兰道吗 "));

输出 :

 

CRF 标注结果

你   S   

看   S   

过   S   

穆   B   

赫   M   

兰   M   

道   E   

吗   S   

[ 你 /rr, 看 /v, 过 /uguo, 穆赫兰道 /null, 吗 /y]

 

null 表示新词。




来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31524777/viewspace-2637046/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
八年IT互联从业经历,专注网络营销、大数据、人工智能等领域的知识分享

注册时间:2018-03-09

  • 博文量
    184
  • 访问量
    165399