命名实体识别—NER——CRFPP

版权声明:我是南七小僧,微信: to_my_love ,欢迎交流思想碰撞。 https://blog.csdn.net/qq_25439417/article/details/83650966

在深度学习技术火起来之前,主流的、最有效的方法,就是CRF(条件随机场)模型。本文不对CRF模型进行展开讲解,而是结合我之前参加的瑞金医院NER赛题,直接用CRF++工具进行实战。下面直接进入正题。

1.赛题解读

赛题介绍:http://www.datafountain.cn/#/competitions/269/intro

任务描述

总结一下,这个题目要求我们对数据集中的每条记录,提取出正文中的主要机构实体,判断这些机构的风险等级(中性,正向或负向),并为每个实体生成相应的摘要和关键词。

我接下来主要讲提取实体这一部分,用的是CRF模型,训练直接使用CRF++工具(http://taku910.github.io/crfpp/)(似乎被墙了?)。

2.算法流程图

通过训练集【含NER与词性标注的文本】通过CRF++训练处一个特征模型

将测试文本的输入进CRF训练好的特征模型里

3.算法说明

3.1 定义实体标注集

为了确保最后的机构实体识别准确度,使用BMEWO标注集,各个标注的意义如下:

B:实体的开头

M:实体的中间部分

E:实体的结束

W:单独成实体

O:句子的其它成分

比如下面这个句子(已做分词处理):

山西      相立      山泉      饮品      开发      有限公司     生产      的桶装  饮用水  检出      铜绿      假   单胞菌

背后的标注为:

山西/B  相立/M 山泉/M 饮品/M 开发/M 有限公司/E  生产/O  的/O 桶装/O     饮用水/O     检出/O  铜绿/O   假/O 单胞菌/O

3.2训练文本、测试文本预处理

对训练文本进行中文分词、去除停用词的处理,并根据上述的标注集进行标注。同时,除了词本身,还引入了4个特征:

特征:【词性】,用jieba分词识别出来的词性

特征②:【是否是特征词】,该词是特征词,标记1;不是特征词,标记0。这里的特征词是指“实体通常的结尾词”,比如“有限公司”,“药监局”,“超市”等等,这些特征词来源于两个地方:

  1. 从训练集中分词得到。
  2. 从开源中文分词工具hanlp的机构名词典中整理得到。

特征③:【是否是地点】,该词是地点,标记为isloc;该词不是地点,标记为notloc。这里的地点信息我们是从jieba的分词词性标注功能中得到的,词性标注为ns的一般是地点。

特征④:【是否是句子结束】,该词是这个句子的结束词,标记为isend;否则标记为notend。

训练文本在经过预处理之后,格式如下:

宁夏      ns   0     isloc      notend B

物美      nz   0     notloc  notend M

超市      v     1     notloc  notend M

有限公司    n     1     notloc  notend M

森林公园    n     0     notloc  notend M

   n     1     notloc  isend    E

其中,第一列为词本身,第二列为特征①,第三列为特征②,第四列为特征③,第五列为特征④,第六列列为正确标注。

测试文本的预处理和上面的基本一样,区别在于,测试文本没有正确的实体标注,所以测试文本的预处理文件只有五列。最后我们要用CRF模型预测的是第六列标注。

3.3训练CRF模型

CRF模型的训练,需要一个特征模板,以便能够自动在训练文本中提取特征函数,特征模板的定义直接决定了最后的识别效果

针对此次的机构实体,我们定义了几种特征模板,最终选择了以下模板:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

# Unigram

U01:%x[-2,0]

U02:%x[-1,0]

U03:%x[0,0]

U04:%x[1,0]

U05:%x[2,0]

U06:%x[-2,0]/%x[-1,0]/%x[0,0]

U07:%x[-1,0]/%x[0,0]/%x[1,0]

U08:%x[0,0]/%x[1,0]/%x[2,0]

U09:%x[-1,0]/%x[0,0]

U10:%x[0,0]/%x[1,0]

U11:%x[-1,1]/%x[0,1]/%x[1,1]

U12:%x[-1,1]/%x[0,1]

U13:%x[0,1]/%x[1,1]

U14:%x[0,1]/%x[0,2]

U15:%x[-1,1]/%x[0,2]

U16:%x[-2,1]/%x[-1,1]/%x[0,2]

U17:%x[-1,1]/%x[0,2]/%x[1,1]

U18:%x[0,2]/%x[1,1]/%x[2,1]

U19:%x[0,0]/%x[0,2]

U20:%x[-1,0]/%x[0,2]

U21:%x[-2,0]/%x[-1,0]/%x[0,2]

U22:%x[-1,0]/%x[0,2]/%x[1,0]

U23:%x[0,2]/%x[1,0]/%x[2,0]

# Bigram

B

下面解释一下上述特征模板:

①Unigram类型

每一行%x[#,#]生成一个CRFs中的点(state)函数: f(s, o), 其中s为t时刻的标签(output),o为t时刻的上下文以及特征信息。

比如:U06:%x[-2,0]/%x[-1,0]/%x[0,0]

U06是指这个特征模板的编号,对于%x[-2,0]而言,%x是指找到的字符;[-2,0]是定位信息,其中中括号里面的-2是指当前词的前两个词,0是指第0列。后面用/连接的是多个特征的组合。

对于以下的训练文本:

宁夏     ns   0     isloc      notend B

物美     nz   0     notloc  notend M

超市     v     1     notloc  notend M

有限公司   n     1     notloc  notend M

森林公园   n     0     notloc  notend M

  n     1     notloc  isend    E

假如当前识别到第三行,则U06:%x[-2,0]/%x[-1,0]/%x[0,0]对应识别出来的文本为宁夏/物美/超市。

这就相当于我们在文本中找到的一条特征。

②Bigram类型

每一行%x[#,#]生成一个CRFs中的边(Edge)函数:f(s’, s, o), 其中s’为t – 1时刻的标签.也就是说,Bigram类型与Unigram大致机同,只是还要考虑到t – 1时刻的标签.这里只写一个B,默认生成f(s’, s).

有了特征模板以及训练文本文件,就可以进行CRF模型训练了,我们采用了CRF++这个开源工具包进行训练,使用默认参数,最终模型识别出来的特征有11616755条。

3.4预测、生成实体

有了上述预处理测试文本和训练生成的CRF模型,我们可以进行测试文本的标签预测,生成crf_test_output.txt

由于crf_test_output.txt里面预测的是每个词背后的标注,我们还要做一个后处理工作才能把真正的实体提取出来。

用正则表达式B+M*E+或者W匹配文本,然后将其背后的文字提取出来,就是识别出来的机构实体。

3.4效果和缺点

在使用CRF模型之后,我们得到了不错的效果。线下训练文本的实体召回率可以达到91.3%,另外,识别出来的无效实体也少了很多。

和基于规则的实体识别相比,它有着以下优点:

  • 通过特征模板,能够最大限度的挖掘文本的特征,而不需要人工提取。
  • 能够考虑大量的上下文信息、特征。
  • 考虑了相邻词的标注信息,这是传统的最大熵算法所不具备的。
  • 和神经网络模型相比,CRF模型的可解释性强,具体到每一个特征都有可以解释的意义。因此调整起来比较容易。

当然,这个模型也不是完美的,比如,我们训练的这个模型就比较“看重”机构特征词。举个例子,如果“下属公司”单独出现,则它也可能会被识别为机构名,需要我们人工定义一些规则将其去除。


CRF++工具的使用就没有介绍了,训练的过程只需要预处理语料以及模板文件,预处理语料格式和模板文件,在上文已经体现出来了,感兴趣的朋友,缺少语料或者工具,可以找我要。

猜你喜欢

转载自blog.csdn.net/qq_25439417/article/details/83650966