使用UER进行开庭公告命名实体识别-续2

使用UER进行开庭公告命名实体识别-续2

再接着上篇博客,本次依然采用自己生成训练数据的方式来训练,经过上一次的实验和优化,本次生成的训练数据标注错误的问题将会大大减少,因为很多实体是根据已有数据进行收集的,没有耗费大量的人力去逐条核验,难免会存在噪音,这一次修复了上篇中存在的各种噪音问题,并且还做了较多优化,具体效果如何,继续来看看吧。

优化方案

这一次在上一次的训练结果上做了以下优化点:

  1. 修复了目前见过的在数据集生成方面的噪音;
  2. 生成的数据种类大幅增加,增加了6种模板;
  3. 大幅度减少每种模板生成的数量,防止过拟合;
  4. 通过在生成的文本中增加一定的冗余数据,来让模型学会识别哪些信息并不是我们需要的实体;
  5. 生成了一定比例当事人之间没有任何分隔符号的数据,以此来进一步提升训练模型的抽取能力;
  6. 修复了一个“意料之外,又在情理之中”的问题,这个问题下面会说明;
  7. 修复了有空白字符开头的句子预测实体的位置索引不准确的问题。

意料之外,又在情理之中”的问题

在做以上优化时,发现模型存在一个奇怪的问题,当被告放在前面,原告放在后面时,模型无法正确识别

案例

1
2
3
4
5
6
7
8
{'label': {'defendant': [{'春和集团有限公司': [55, 62]},
{'江苏太平洋造船集团股份有限公司': [64, 78]},
{'梁光夫': [80, 82]}],
'plaintiff': [{'国家开发银行股份有限公司': [40, 51]}],
'reason': [{'合同纠纷': [83, 86]}],
'time': [{'二〇一七年四月二十七日上午九时三十分': [4, 21]}],
'tribunal': [{'12法庭': [26, 29]}]},
'text': '我院定于二〇一七年四月二十七日上午九时三十分,在本院12法庭依法公开开庭审理被告国家开发银行股份有限公司与原告春和集团有限公司、江苏太平洋造船集团股份有限公司、梁光夫合同纠纷一案。'}

这里的抽取结果,原告与被告身份搞反了,推测是生成的训练数据,原告总是在前面,被告总是在后面,所以模型记住了位置信息,所以在这一版本中优化了这一点,随机改变原告、被告等的生成顺序。

有空白字符开头的句子,预测的实体位置索引不准确

1
2
3
4
5
6
7
8
{'label': {'defendant': [{'告春和集团有限公': [55, 62]},
{'、江苏太平洋造船集团股份有限公': [64, 78]},
{'、梁光': [80, 82]}],
'plaintiff': [{'告国家开发银行股份有限公': [40, 51]}],
'reason': [{'夫合同纠': [83, 86]}],
'time': [{'于二〇一七年四月二十七日上午九时三十': [4, 21]}],
'tribunal': [{'院12法': [26, 29]}]},
'text': ' 我院定于二〇一七年四月二十七日上午九时三十分,在本院12法庭依法公开开庭审理被告国家开发银行股份有限公司与原告春和集团有限公司、江苏太平洋造船集团股份有限公司、梁光夫合同纠纷一案。'}

这里在开头加了一个空格,导致输出的实体边界全部错误,实际上模型预测的并没有错,只是因为模型在分词时就把句子首尾的空白字符去掉了,而我输出时依然把开头的空白字符算了进去,所以导致实体边界错乱,只要控制输出时也先把句子首尾的空白字符去掉即可。
注意:句子内部出现空白字符不会有任何影响

另外也要注意,训练数据(tsv文件中的text)也不要让首尾出现空白字符,否则的话,在模型读入数据时,会因为文本长度和标签长度对应不上而出错。所以在从我们利用模板生成的数据转换到tsv文件时,要注意这一点。

开始训练

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[2022-09-28 07:34:33,854 INFO] Epoch id: 5, Training steps: 100, Avg loss: 0.003
[2022-09-28 07:34:51,574 INFO] Epoch id: 5, Training steps: 200, Avg loss: 0.002
[2022-09-28 07:35:09,429 INFO] Epoch id: 5, Training steps: 300, Avg loss: 0.003
[2022-09-28 07:35:27,318 INFO] Epoch id: 5, Training steps: 400, Avg loss: 0.002
[2022-09-28 07:35:45,185 INFO] Epoch id: 5, Training steps: 500, Avg loss: 0.002
[2022-09-28 07:36:03,039 INFO] Epoch id: 5, Training steps: 600, Avg loss: 0.002
[2022-09-28 07:36:20,893 INFO] Epoch id: 5, Training steps: 700, Avg loss: 0.002
[2022-09-28 07:36:38,803 INFO] Epoch id: 5, Training steps: 800, Avg loss: 0.003
[2022-09-28 07:36:56,640 INFO] Epoch id: 5, Training steps: 900, Avg loss: 0.003
[2022-09-28 07:37:14,524 INFO] Epoch id: 5, Training steps: 1000, Avg loss: 0.002
[2022-09-28 07:37:32,418 INFO] Epoch id: 5, Training steps: 1100, Avg loss: 0.002
[2022-09-28 07:37:50,308 INFO] Epoch id: 5, Training steps: 1200, Avg loss: 0.002
[2022-09-28 07:38:08,172 INFO] Epoch id: 5, Training steps: 1300, Avg loss: 0.003
[2022-09-28 07:38:26,029 INFO] Epoch id: 5, Training steps: 1400, Avg loss: 0.003
[2022-09-28 07:38:43,904 INFO] Epoch id: 5, Training steps: 1500, Avg loss: 0.003
[2022-09-28 07:39:01,814 INFO] Epoch id: 5, Training steps: 1600, Avg loss: 0.002
[2022-09-28 07:39:19,693 INFO] Epoch id: 5, Training steps: 1700, Avg loss: 0.002
[2022-09-28 07:40:22,461 INFO] Report precision, recall, and f1:
[2022-09-28 07:40:22,461 INFO] 0.991, 0.991, 0.991

本次因为只是优化了数据集,关于一些常规性的预处理工作和前面都是一样的,训练了5轮,最终准确率也达到了99%(感觉验证集不应该有这么高,毕竟数据量大幅度减少,并且增加了难度)。

模型评估

测试集评估

在测试集上的评测指标如下:

1
2
3
4
5
6
correct/total: 1649/1700
accuracy: 0.97
correct/total: 1655/1700
precision: 0.9735294117647059
correct/total: 1651/1700
precision: 0.9711764705882353

经过对测试数据预测错误的原因分析,分为以下几种:

  1. 公司实体预测不准确:1
  2. 英文企业、人名提取不准确:1
  3. 人名实体预测不准确:1
  4. 角色预测不准确:23(因为数据集的生成存在问题,确实无法判断角色)
  5. 名字之间无分隔,导致识别出错:2
  6. 生成的训练数据有噪音:6
  7. 开庭地点中含有案由:1
  8. 法院名称有重合:1
  9. 法庭地点不准确:3
  10. 案由提取不准确:7
  11. 预测标签存在明显错误:3

针对问题1、2、4、5、7、9只能适当增加一些数据集,问题4已解决,问题6发现的噪音问题已经解决,问题8和10可能需要增加一些特定法院名称和案由的训练数据。

利用CRF层学习句子的约束条件

我这里以一条预测数据的标签的一部分来解释问题11的含义

1
B-reason I-reason I-origin_appellee I-origin_appellee I-origin_appellee I-origin_appellee

我们都知道BIO标注规则的含义,这里”origin_appellee”直接跟在”I-reason”后面明显是不合理的,经过资料查询发现CRF可以解决这一问题,CRF层可以加入一些约束来保证最终预测结果是有效的。这些约束可以在训练数据时被CRF层自动学习得到。

可能的约束条件有:

  1. 句子的开头应该是“B-”或“O”,而不是“I-”。
  2. “B-label1 I-label2 I-label3…”,在该模式中,类别1,2,3应该是同一种实体类别。比如,“B-Person I-Person” 是正确的,而“B-Person I-Organization”则是错误的。
  3. “O I-label”是错误的,命名实体的开头应该是“B-”而不是“I-”。

另外还需要说明的是,一开始我自己也没想过会出现这种不合理的标签预测结果,我在将预测标签转为格式化数据时,是默认新的实体都是以B开头的。

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
def pretty_print2(text, labels):
data = {"text": text}
label_dict = {}
text = text.strip()
current_label = ''
start = -1
for i, j in enumerate(labels):
if j == 'O':
if start != -1:
end = i
entity = text[start:end]
temp = {entity: [start, end-1]}
if current_label in label_dict:
label_dict[current_label].append(temp)
else:
label_dict.update({current_label: [temp]})
start = -1
elif "B-" in j:
if start != -1:
end = i
entity = text[start:end]
temp = {entity: [start, end-1]}
if current_label in label_dict:
label_dict[current_label].append(temp)
else:
label_dict.update({current_label: [temp]})
start = i
current_label = j.strip('B-')
# 最末尾如果不是'O',提取最后的实体
if start != -1:
entity = text[start:len(text)]
temp = {entity: [start, len(text)-1]}
if current_label in label_dict:
label_dict[current_label].append(temp)
else:
label_dict.update({current_label: [temp]})
data["label"] = label_dict
pprint(data)

这样处理带来的问题就是,有的数据虽然预测标签有错误,但是转换为格式化数据时却难以发现错误。例如在测试数据就有这样的案例,其中一条数据的案由为:“其他(城建)”,但是预测的标签为:“B-reason I-reason I-origin_appellee I-origin_appellee I-origin_appellee I-origin_appellee”,由于”I-origin_appellee”没有以B开头,所以转换程序认为后续依然为reason实体,所以转换结果看起来完全正确。

真实数据及评估

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# 正确预测
{'label': {'appellant': [{'徐兴华': [60, 62]}, {'杨锦春': [64, 66]}],
'case_no': [{'(2022)云刑终440号': [24, 36]}],
'reason': [{'走私、贩卖、运输、制造毒品': [41, 53]}],
'time': [{'2022年08月29日 09:00': [3, 19]}],
'tribunal': [{'第二法庭': [95, 98]}]},
'text': '时间:2022年08月29日 09:00 案号:(2022)云刑终440号 案由:走私、贩卖、运输、制造毒品案 上诉人:徐兴华,杨锦春 '
'合议庭成员:庆文、李江鹏、余姗珊书记员:马毅嵩 地点:第二法庭 '}

# 正确预测
{'label': {'appellant': [{'蔡立君': [55, 57]}],
'appellee': [{'洱源县云洱果脯有限责任公司': [63, 75]}],
'case_no': [{'(2022)云民终1440号': [23, 36]}],
'origin_plaintiff': [{'丽江摩梭印象水业有限公司': [81, 92]}],
'reason': [{'著作权权属、侵权纠纷': [40, 49]}],
'time': [{'2022年08月30日 09:30': [3, 19]}],
'tribunal': [{'第五法庭': [121, 124]}]},
'text': '时间:2022年08月30日 09:30案号:(2022)云民终1440号案由:著作权权属、侵权纠纷 '
'上诉人:蔡立君被上诉人:洱源县云洱果脯有限责任公司原审原告:丽江摩梭印象水业有限公司 合议庭成员:杨凌萍、刘小华、陈姣 书记员:张晶 '
'地点:第五法庭'}

# 正确预测
{'label': {'litigant': [{'耿志慧': [40, 42]},
{'解彬': [44, 45]},
{'王文娟': [58, 60]},
{'张吴西西': [62, 65]}],
'reason': [{'非法吸收公众存款罪': [46, 54]}, {'非法吸收公众存款罪': [66, 74]}],
'time': [{'二〇二〇年二月二十七日上午九时整': [4, 19]}],
'tribunal': [{'温榆河第十二法庭': [24, 31]}]},
'text': '我院定于二〇二〇年二月二十七日上午九时整,在本院温榆河第十二法庭依法公开开庭审理耿志慧、解彬非法吸收公众存款罪一案同王文娟、张吴西西非法吸收公众存款罪一案合并审理。'}

# 正确预测
{'label': {'case_no': [{'(2016)渝0116民初7329号': [0, 17]},
{'(2016)渝0116民初7329号': [56, 73]}],
'court': [{'江津区人民法院': [100, 106]}],
'defendant': [{'王洪春': [82, 84]}, {'何向东': [86, 88]}],
'plaintiff': [{'陈华辉': [76, 78]}],
'reason': [{'企业出售合同纠纷': [89, 96]}],
'time': [{'二〇一六年八月二十九日14:00到17:30': [22, 43]}],
'tribunal': [{'第十五审判法庭': [45, 51]}]},
'text': '(2016)渝0116民初7329号本院定于二〇一六年八月二十九日14:00到17:30在第十五审判法庭开庭审理(2016)渝0116民初7329号原告陈华辉诉被告王洪春,何向东企业出售合同纠纷一案。江津区人民法院承办人:文学清'}

# 正确预测
{'label': {'litigant': [{'罗星梦': [35, 37]},
{'王扬': [39, 40]},
{'李淑云': [42, 44]},
{'缪晋荣': [46, 48]},
{'北京华雷联盟资本管理中心(有限合伙)': [50, 67]}],
'reason': [{'借款合同纠纷': [68, 73]}],
'time': [{'二〇一八年六月七日下午十五时整': [4, 18]}],
'tribunal': [{'(北区)第11法庭': [20, 28]}]},
'text': '本院定于二〇一八年六月七日下午十五时整在(北区)第11法庭公开开庭审理罗星梦、王扬、李淑云、缪晋荣、北京华雷联盟资本管理中心(有限合伙)借款合同纠纷一案'}

# 正确预测
{'label': {'case_no': [{'(2017)渝04民终177号': [0, 14]},
{'(2017)渝04民终177号': [51, 65]}],
'court': [{'重庆市第四中级人民法院': [115, 125]}],
'defendant': [{'陈佐刚': [91, 93]}, {'彭水县茂林矿业开发有限公司': [95, 107]}],
'plaintiff': [{'彭水县茂林矿业开发有限公司朱山洞三号煤矿': [68, 87]}],
'reason': [{'劳动争议': [108, 111]}],
'time': [{'二〇一七年二月二十二日14:30到18:00': [19, 40]}],
'tribunal': [{'第三审判庭': [42, 46]}]},
'text': '(2017)渝04民终177号本院定于二〇一七年二月二十二日14:30到18:00在第三审判庭开庭审理(2017)渝04民终177号原告彭水县茂林矿业开发有限公司朱山洞三号煤矿诉被告陈佐刚,彭水县茂林矿业开发有限公司劳动争议一案。重庆市第四中级人民法院'}

# 正确预测
{'label': {'defendant': [{'香港皇冠船舶有限公司(CROWNSHIPLIMITED)': [51, 78]},
{'春和集团有限公司': [80, 87]},
{'江苏太平洋造船集团股份有限公司': [89, 103]},
{'梁光夫': [105, 107]}],
'plaintiff': [{'国家开发银行股份有限公司': [38, 49]}],
'reason': [{'合同纠纷': [108, 111]}],
'time': [{'二〇一七年四月二十七日上午九时三十分': [4, 21]}],
'tribunal': [{'12法庭': [26, 29]}]},
'text': '我院定于二〇一七年四月二十七日上午九时三十分,在本院12法庭依法公开开庭审理国家开发银行股份有限公司诉香港皇冠船舶有限公司(CROWNSHIPLIMITED)、春和集团有限公司、江苏太平洋造船集团股份有限公司、梁光夫合同纠纷一案。'}

# 正确预测
{'label': {'court': [{'北京市高级人民法院': [21, 29]}],
'litigant': [{'王朝阳': [42, 44]},
{'中地不动产评估有限公司': [46, 56]},
{'尤孝明': [58, 60]},
{'钱海滨': [62, 64]},
{'王朝霞': [66, 68]}],
'reason': [{'损害公司利益责任纠纷': [69, 78]}],
'time': [{'二零一六年十月十三日上午九时整': [4, 18]}],
'tribunal': [{'12法庭': [30, 33]}]},
'text': '我院定于二零一六年十月十三日上午九时整,在北京市高级人民法院12法庭依法公开开庭审理王朝阳与中地不动产评估有限公司、尤孝明、钱海滨、王朝霞损害公司利益责任纠纷上诉一案。'}

# 正确预测
{'label': {'court': [{'北京市东城区人民法院': [20, 29]}],
'litigant': [{'满毅': [47, 48]},
{'北京首都开发股份有限公司': [50, 61]},
{'北京圣泽宏房地产经纪有限公司': [62, 75]},
{'杨佳茗': [77, 79]}],
'reason': [{'房屋买卖合同纠纷': [80, 87]}],
'time': [{'二零一六年八月九日上午九时整': [4, 17]}],
'tribunal': [{'(北区)第28法庭': [30, 38]}]},
'text': '我院定于二零一六年八月九日上午九时整,在北京市东城区人民法院(北区)第28法庭依法公开开庭审理满毅与北京首都开发股份有限公司北京圣泽宏房地产经纪有限公司、杨佳茗房屋买卖合同纠纷一案。'}

# 正确预测
{'label': {'accused': [{'周容川': [72, 74]}, {'谭昌健': [76, 78]}],
'case_no': [{'2016)渝0151刑初167号': [0, 15]},
{'(2016)渝0151刑初167号': [52, 68]}],
'court': [{'铜梁区人民法院': [92, 98]}],
'reason': [{'故意毁坏财物罪': [82, 88]}],
'time': [{'二〇一六年九月二十七日09:30到10:10': [20, 41]}],
'tribunal': [{'第二审判庭': [43, 47]}]},
'text': '2016)渝0151刑初167号本院定于二〇一六年九月二十七日09:30到10:10在第二审判庭开庭审理(2016)渝0151刑初167号被告人周容川,谭昌健涉嫌犯故意毁坏财物罪一案。铜梁区人民法院'}

# 吉林省劳动人事争议仲裁委员会】提取为开庭法庭,有问题,但是这是一种新格式的数据
# 这种为劳动仲裁相关的开庭公告,需要新增一个实体类别--仲裁机构(吉林省劳动人事争议仲裁委员会)
{'label': {'appellant_c': [{'吴艳华': [58, 60]}, {'王恒': [62, 63]}],
'appellee_c': [{'长春市富源晟和房地产开发有限公司': [69, 84]},
{'吉林省中政人力资源服务有限公司': [86, 100]}],
'reason': [{'劳动争议': [101, 104]}],
'time': [{'2022年9月13日上午9时': [4, 17]}],
'tribunal': [{'吉林省劳动人事争议仲裁委员会】': [20, 34]},
{'仲裁一庭(金业大厦A座二楼)': [35, 48]}]},
'text': '本委定于2022年9月13日上午9时在【吉林省劳动人事争议仲裁委员会】仲裁一庭(金业大厦A座二楼)公开开庭审理申请人吴艳华、王恒与被申请人长春市富源晟和房地产开发有限公司、吉林省中政人力资源服务有限公司劳动争议一案。'}

# 案号应为:云劳人仲案字[2022] 224 号,这也是劳动仲裁相关开庭公告的案号形式,需要补充该形式数据进行训练。这里提取了两个时间倒不影响,业务使用时可以自己选取。
{'label': {'case_no': [{'[2022] 224 号': [6, 17]}],
'defendant': [{'山东仁恒建筑工程有限公司': [72, 83]}],
'plaintiff': [{'梁海玉': [68, 70]}],
'reason': [{'云劳人仲': [0, 3]}, {'劳动争议': [84, 87]}],
'time': [{'二〇二二年九月二十九日上午9时00分': [22, 39]},
{'二〇二二年九月二十三日': [95, 105]}],
'tribunal': [{'昆明市国贸路309号政通大厦一楼二号仲裁庭': [41, 61]}]},
'text': '云劳人仲案字[2022] 224 '
'号本院定于二〇二二年九月二十九日上午9时00分在昆明市国贸路309号政通大厦一楼二号仲裁庭公开开庭审理梁海玉诉山东仁恒建筑工程有限公司劳动争议案。特此公告。二〇二二年九月二十三日'}

通过在真实数据集上的测试,其实可以发现模型的准确率极高,虽然在测试集上存在各种问题,但是这些问题在真实数据集上极少出现(例如角色无法判断的问题,是因为生成的测试数据相比真实数据有一定的特殊性)。现在只需要将新增的劳动仲裁的数据再融入到模型的训练中,基本就把整个项目完成了。

把仲裁机构划分一个独立的实体类别是一个非常不错的选择,但是这样又要针对生成数据的模板进行较大的更改,可以将仲裁机构与法院认为是同一实体种类,后续交给业务方自行判断是一个比较简洁的方式,只需要在原法院的实体位置,增加一些仲裁机构样本即可,仲裁案号也是同理。