使用bert进行关系三元组抽取。
模型和数据下载地址:https://cowtransfer.com/s/c5e2422d2e0b40 点击链接查看 [ BERT-Relation-Extraction ] ,或访问奶牛快传 cowtransfer.com 输入传输口令 vvf067 查看;
scikit-learn==1.1.3
scipy==1.10.1
seqeval==1.2.2
transformers==4.27.4
pytorch-crf==0.7.2
--checkpoint:模型和配置保存位置
--model_hub:预训练模型
----chinese-bert-wwm-ext:
--------vocab.txt
--------pytorch_model.bin
--------config.json
--data:存放数据
----dgre
--------ori_data:原始的数据
--------ner_data:处理之后的数据
------------labels.txt:标签
------------train.txt:训练数据
------------dev.txt:测试数据
--------re_data:
------------labels.txt:关系标签
------------train.txt:训练数据
------------dev.txt:测试数据
------------rels.txt:该数据集没有,因为实体只有两类,有的话则是哪些实体之间具有关系
--config.py:配置
--model.py:模型
--process.py:处理ori数据得到ner数据和re数据
--predict.py:加载训练好的模型进行预测
--ner_main.py:实体识别训练和测试
--re_main.py:关系识别训练和测试
使用的方法:
- 1、利用BERT-BILSTM-CRF识别出文本里面的实体。
- 2、根据rels之间实体对之间的关系,将可能有关系的两类实体和文本拼接后输入到模型里面进行分类。
这里以dgre数据为例。
1、去https://huggingface.co/hfl/chinese-bert-wwm-ext/tree/main下载相关文件到chinese-bert-wwm-ext下。
2、在process.py里面定义将ori_data里面的数据处理得到ner_data下的数据和re_data下的数据。
ner_data下数据样本是这样的:
--labels.txt
故障设备
故障原因
--train.txt/dev.txt
{"id": "AT0001", "text": ["6", "2", "号", "汽", "车", "故", "障", "报", "告", "综", "合", "情", "况", ":", "故", "障", "现", "象", ":", "加", "速", "后", ",", "丢", "开", "油", "门", ",", "发", "动", "机", "熄", "火", "。"], "labels": ["O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "B-故障设备", "I-故障设备", "I-故障设备", "B-故障原因", "I-故障原因", "O"]}
一行一条样本,格式为BIO。
re_data下的数据样本是这样的:
--labels.txt
性能故障
部件故障
检测工具
组成
没关系
--train.txt/dev.txt
{"text": "故障原因:车轮悬架臂支座表面与车架接触面两者之间的表面接触不平整,在车辆低速急加速时,车轮悬架臂支座瞬间的推力,刚好车轮悬架臂支座表面与车架接触面接触不平整,车轮悬架臂支座表面与车架表面产生相对位移,使两者表面之间有摩擦,产生金属异响声解决方法:根据车轮悬架臂支座表面与车架接触面两者之间的表面接触不平整现象,对车轮悬架臂支座表面与车架表面进行平整化处理", "labels": ["车架接触面", "表面接触不平整", "部件故障"], "id": "1380_2"}
如果还有rels.txt,则是这样的
{
"故障设备_故障原因": ["性能故障", "部件故障", "检测工具", "组成"]
}
可参考duie/re_data下的rels.txt
也就是不同类型的实体对之间存在的关系。
3、在config.py里面定义一些参数,比如:
--max_seq_len:句子最大长度,GPU显存不够则调小。
--epochs:训练的epoch数
--train_batch_size:训练的batchsize大小,GPU显存不够则调小。
--dev_batch_size:验证的batchsize大小,GPU显存不够则调小。
--save_step:多少step保存模型
其余的可保持不变。注意:实体识别最大长度和关系抽取最大长度要保持一致。
4、在ner_main.py里面修改data_name为数据集名称。需要注意的是名称和data下的数据集名称保持一致。最后运行:python ner_main.py
5、在re_main.py里面修改data_name为数据集名称。需要注意的是名称和data下的数据集名称保持一致。最后运行:python re_main.py
5、在predict.py修改data_name并加入预测数据,最后运行:python predict.py
max_seq_len=512
epochs=3
train_batch_size=12
dev_batch_size=12
实体识别:
precision recall f1-score support
故障原因 0.70 0.74 0.72 490
故障设备 0.75 0.79 0.77 484
micro avg 0.72 0.76 0.74 974
macro avg 0.72 0.76 0.74 974
weighted avg 0.72 0.76 0.74 974
关系识别:
precision recall f1-score support
性能故障 0.96 0.87 0.91 30
部件故障 0.89 0.99 0.94 464
检测工具 1.00 0.67 0.80 3
组成 0.60 0.95 0.73 19
没关系 0.96 0.62 0.75 176
accuracy 0.89 692
macro avg 0.88 0.82 0.83 692
weighted avg 0.90 0.89 0.88 692
联合预测:
文本>>>>>: 492号汽车故障报告故障现象一辆车用户用水清洗发动机后,在正常行驶时突然产生铛铛异响,自行熄火
实体>>>>>: {'故障原因': [('异响', 40, 41), ('熄火', 45, 46)]}
关系>>>>>: []
====================================================================================================
文本>>>>>: 故障现象:空调制冷效果差。
实体>>>>>: {'故障设备': [('空调', 5, 6)], '故障原因': [('制冷效果差', 7, 11)]}
关系>>>>>: [('空调', '制冷效果差', '部件故障')]
====================================================================================================
文本>>>>>: 原因分析:1、遥控器失效或数据丢失;2、ISU模块功能失效或工作不良;3、系统信号有干扰导致。处理方法、体会:1、检查该车发现,两把遥控器都不能工作,两把遥控器同时出现故障的可能几乎是不存在的,由此可以排除遥控器本身的故障。2、检查ISU的功能,受其控制的部分全部工作正常,排除了ISU系统出现故障的可能。3、怀疑是遥控器数据丢失,用诊断仪对系统进行重新匹配,发现遥控器匹配不能正常进行。此时拔掉ISU模块上的电源插头,使系统强制恢复出厂设置,再插上插头,发现系统恢复,可以进行遥控操作。但当车辆发动在熄火后,遥控又再次失效。4、查看线路图发现,在点火开关处安装有一钥匙行程开关,当钥匙插入在点火开关内,处于ON位时,该开关接通,向ISU发送一个信号,此时遥控器不能进行控制工作。当钥匙处于OFF位时,开关断开,遥控器恢复工作,可以对门锁进行控制。如果此开关出现故障,也会导致遥控器不能正常工作。同时该行程开关也控制天窗的自动回位功能。测试天窗发现不能自动回位。确认该开关出现故障
实体>>>>>: {'故障设备': [('遥控器', 7, 9), ('ISU模块', 20, 24), ('系统信号', 37, 40), ('遥控器', 66, 68), ('遥控器', 158, 160), ('遥控器', 182, 184), ('开关', 434, 435)], '故障原因': [('失效', 10, 11), ('数据', 13, 14), ('丢失', 15, 16), ('功能失效', 25, 28), ('工作不良', 30, 33), ('干扰', 42, 43), ('不能工作', 70, 73), ('数据丢失', 161, 164), ('失效', 260, 261), ('不能自动回位', 424, 429), ('故障', 438, 439)]}
关系>>>>>: [('遥控器', '失效', '部件故障'), ('遥控器', '丢失', '部件故障'), ('ISU模块', '功能失效', '部件故障'), ('ISU模块', '工作不良', '部件故障'), ('系统信号', '干扰', '部件故障'), ('遥控器', '不能工作', '部件故障'), ('遥控器', '数据丢失', '部件故障'), ('遥控器', '不能自动回位', '部件故障'), ('开关', '故障', '部件故障')]
====================================================================================================
文本>>>>>: 原因分析:1、发动机点火系统不良;2、发动机系统油压不足;3、喷嘴故障;4、发动机缸压不足;5、水温传感器故障。
实体>>>>>: {'故障设备': [('发动机点火系统', 7, 13), ('发动机系统', 19, 23), ('喷嘴', 31, 32), ('发动机', 38, 40), ('水温传感器', 48, 52)], '故障原因': [('不良', 14, 15), ('油压不足', 24, 27), ('故障', 33, 34), ('缸压不足', 41, 44), ('故障', 53, 54)]}
关系>>>>>: [('发动机点火系统', '不良', '部件故障'), ('发动机系统', '油压不足', '部件故障'), ('喷嘴', '故障', '部件故障'), ('发动机', '缸压不足', '部件故障'), ('水温传感器', '故障', '部件故障')]
====================================================================================================
max_seq_len:256
epochs:1
train_batch_size:12
dev_batch_size:12
实体在第1000step手动停止,关系在1500step手动停止。具体可自己调节。
实体识别:
precision recall f1-score support
Date 0.87 0.79 0.83 3130
Number 0.77 0.72 0.75 877
Text 0.70 0.63 0.66 2045
人物 0.80 0.90 0.85 44595
企业 0.47 0.67 0.55 3148
企业/品牌 0.53 0.69 0.60 160
作品 0.00 0.00 0.00 90
国家 0.71 0.74 0.73 2241
图书作品 0.86 0.72 0.78 4535
地点 0.40 0.50 0.44 958
城市 0.45 0.61 0.52 220
奖项 0.00 0.00 0.00 529
学校 0.64 0.86 0.74 1879
学科专业 0.00 0.00 0.00 8
影视作品 0.86 0.63 0.72 7900
文学作品 0.57 0.21 0.30 188
景点 0.44 0.36 0.40 118
机构 0.81 0.37 0.51 2977
歌曲 0.80 0.76 0.78 4976
气候 0.80 0.80 0.80 132
电视综艺 0.76 0.65 0.70 1010
行政区 0.73 0.70 0.71 305
语言 0.00 0.00 0.00 20
音乐专辑 0.70 0.70 0.70 1035
micro avg 0.77 0.79 0.78 83076
macro avg 0.57 0.54 0.55 83076
weighted avg 0.78 0.79 0.77 83076
关系识别:
precision recall f1-score support
没关系 0.73 0.71 0.72 4887
毕业院校 0.99 1.00 0.99 1372
主角 0.80 0.21 0.33 188
占地面积 0.95 0.95 0.95 165
成立日期 0.99 1.00 0.99 2101
主题曲 0.84 0.93 0.88 404
歌手 0.86 0.85 0.85 3319
创始人 0.90 0.91 0.91 301
简称 0.94 0.99 0.97 651
母亲 0.91 0.53 0.67 1145
人口数量 0.96 1.00 0.98 85
嘉宾 0.69 0.90 0.78 761
代言人 0.95 0.97 0.96 129
校长 0.98 0.96 0.97 419
官方语言 1.00 0.72 0.84 18
邮政编码 0.00 0.00 0.00 7
父亲 0.78 0.86 0.82 2240
所属专辑 0.96 0.95 0.96 1203
主持人 0.90 0.78 0.84 619
祖籍 0.96 0.95 0.96 256
面积 0.91 0.91 0.91 95
票房 0.95 0.84 0.89 289
国籍 0.99 0.97 0.98 1925
作者 0.92 0.96 0.94 4488
首都 0.94 0.85 0.89 73
所在城市 0.95 0.91 0.93 106
作曲 0.61 0.82 0.70 1252
导演 0.90 0.90 0.90 2736
饰演 1.00 0.79 0.88 1185
注册资本 0.99 1.00 1.00 280
朝代 0.85 1.00 0.92 924
专业代码 0.00 0.00 0.00 3
海拔 1.00 1.00 1.00 58
制片人 0.75 0.76 0.76 289
气候 1.00 1.00 1.00 137
编剧 0.80 0.64 0.71 846
修业年限 0.00 0.00 0.00 5
作词 0.88 0.54 0.67 1279
董事长 0.96 0.95 0.95 966
妻子 0.64 0.91 0.75 2473
丈夫 1.00 0.01 0.01 759
获奖 0.99 0.98 0.99 550
主演 0.91 0.96 0.93 5937
号 1.00 0.98 0.99 262
总部地点 0.96 0.99 0.98 533
改编自 0.96 1.00 0.98 275
上映时间 0.96 0.97 0.96 1302
出品公司 0.95 0.98 0.97 949
配音 0.94 0.87 0.90 490
accuracy 0.87 50736
macro avg 0.85 0.81 0.81 50736
weighted avg 0.88 0.87 0.86 50736
联合预测:
文本>>>>>: 歌曲《墨写你的美》是由歌手冷漠演唱的一首歌曲
实体>>>>>: {'歌曲': [('墨写你的美', 3, 7)], '人物': [('冷漠', 13, 14)]}
关系>>>>>: [('墨写你的美', '冷漠', '歌手')]
====================================================================================================
文本>>>>>: 982年,阎维文回到山西,隆重地迎娶了刘卫星
实体>>>>>: {'人物': [('阎维文', 5, 7), ('刘卫星', 19, 21)]}
关系>>>>>: [('阎维文', '刘卫星', '妻子'), ('刘卫星', '阎维文', '妻子')]
====================================================================================================
文本>>>>>: 王皃姁为还是太子的刘启生了二个儿子,刘越(汉景帝第11子)、刘寄(汉景帝第12子)
实体>>>>>: {'人物': [('王皃姁', 0, 2), ('刘启', 9, 10), ('刘越', 18, 19), ('刘寄', 30, 31)]}
关系>>>>>: [('王皃姁', '刘启', '父亲'), ('王皃姁', '刘越', '父亲'), ('王皃姁', '刘寄', '父亲'), ('刘启', '王皃姁', '父亲'), ('刘启', '刘越', '父亲'), ('刘启', '刘寄', '父亲'), ('刘越', '王皃姁', '父亲'), ('刘越', '刘启', '父亲'), ('刘越', '刘寄', '父亲'), ('刘寄', '王皃姁', '父亲'), ('刘寄', '刘启', '父亲'), ('刘寄', '刘越', '父亲')]
====================================================================================================
文本>>>>>: 数据分析方法五种》是2011年格致出版社出版的图书,作者是尤恩·苏尔李
实体>>>>>: {'图书作品': [('数据分析方法五种', 0, 7)], '人物': [('尤恩·苏尔李', 29, 34)]}
关系>>>>>: [('数据分析方法五种', '尤恩·苏尔李', '作者')]
====================================================================================================
文本>>>>>: 视剧《不可磨灭》是导演潘培成执导,刘蓓、丁志诚、李洪涛、丁海峰、雷娟、刘赫男等联袂主演
实体>>>>>: {'影视作品': [('不可磨灭', 3, 6)], '人物': [('潘培成', 11, 13), ('刘蓓', 17, 18), ('丁志诚', 20, 22), ('李洪涛', 24, 26), ('丁海峰', 28, 30), ('雷娟', 32, 33), ('刘赫男', 35, 37)]}
关系>>>>>: [('不可磨灭', '潘培成', '导演'), ('不可磨灭', '刘蓓', '主演'), ('不可磨灭', '丁志诚', '主演'), ('不可磨灭', '李洪涛', '主演'), ('不可磨灭', '丁海峰', '主演'), ('不可磨灭', '雷娟', '主演'), ('不可磨灭', '刘赫男', '主演')]
====================================================================================================
可以看到,对于人物之间关系的识别会存在问题,这也正是补充里面所提到的。可能需要对人物之间的关系进行特别的优化。
后处理很重要。在DGRE数据集中,限制了:
- 原因必须在设备的后面。
- 如果出现:设备1-原因1-设备2-原因2,则设备1不会考虑设备2后的所有原因了。
构建负样本很重要。虽然我们限制了哪两类实体之间有关系,但是在其内部还是有没有关系的存在,因此要构建负样本让模型知道这些实体之间没有关系。具体不同数据集可能构建的方式不大一样。
该方法还是存在一些问题:
- 不能区分两个实体之间存在多个关系。
- 对于同类实体之间存在的关系不能有效的识别,而且不能区分主体和客体。
为了解决第二个问题,会发现关系是成对出现的,比如A是B的妻子,那么B是A的丈夫。duie数据中有四类:["丈夫","妻子","父亲","母亲"]。针对于父亲、母亲需要补充关系"儿子/女儿"。对于这种数据,需要交换sbj和obj,然后构建新的关系。在process.py中:
if spo["predicate"] in ["丈夫", "妻子", "父亲", "母亲"]:
# 这里针对人物之间的关系转换一下
tmp_reverse = {}
tmp_reverse["id"] = i
tmp_reverse["text"] = text
if spo["predicate"] == "妻子":
tmp_labels = [obj, sbj, "丈夫"]
elif spo["predicate"] == "丈夫":
tmp_labels = [obj, sbj, "妻子"]
elif spo["predicate"] == "父亲":
tmp_labels = [obj, sbj, "儿子/女儿"]
elif spo["predicate"] == "母亲":
tmp_labels = [obj, sbj, "儿子/女儿"]
tmp_reverse["labels"] = tmp_labels
max_seq_len=256
epochs=5
train_batch_size=24
dev_batch_size=12
运行1820步后手动停止。
precision recall f1-score support
没关系 0.92 0.92 0.92 18867
歌手 0.86 0.88 0.87 3315
制片人 0.94 0.67 0.78 284
校长 0.99 0.97 0.98 419
面积 0.90 0.93 0.91 95
占地面积 0.96 0.94 0.95 165
总部地点 0.97 1.00 0.98 533
朝代 0.86 0.95 0.90 728
作曲 0.70 0.69 0.69 1253
邮政编码 0.00 0.00 0.00 7
成立日期 0.98 1.00 0.99 2094
祖籍 0.98 0.99 0.99 234
妻子 0.81 0.78 0.79 2046
饰演 0.98 0.86 0.92 1161
注册资本 1.00 1.00 1.00 280
简称 0.97 0.98 0.97 651
创始人 0.91 0.92 0.91 281
配音 0.92 0.95 0.94 496
所在城市 0.98 0.86 0.91 106
号 0.96 0.99 0.97 255
国籍 0.98 0.99 0.98 1733
修业年限 0.00 0.00 0.00 5
作词 0.77 0.69 0.73 1273
嘉宾 0.78 0.83 0.81 747
主题曲 0.86 0.91 0.89 406
专业代码 0.00 0.00 0.00 3
董事长 0.96 0.94 0.95 951
编剧 0.64 0.75 0.69 855
代言人 0.93 0.97 0.95 129
所属专辑 0.96 0.96 0.96 1209
海拔 1.00 1.00 1.00 58
母亲 0.00 0.00 0.00 159
官方语言 0.00 0.00 0.00 18
父亲 1.00 0.01 0.01 302
人口数量 0.92 1.00 0.96 85
改编自 0.99 1.00 0.99 288
丈夫 0.79 0.77 0.78 1971
出品公司 0.97 0.97 0.97 950
导演 0.91 0.89 0.90 2735
票房 0.87 0.94 0.90 279
首都 0.76 0.94 0.84 68
上映时间 0.97 0.99 0.98 1286
主角 0.75 0.62 0.68 188
作者 0.94 0.91 0.93 4463
气候 1.00 1.00 1.00 137
主演 0.94 0.95 0.95 5898
主持人 0.87 0.76 0.81 623
获奖 0.97 0.99 0.98 532
毕业院校 0.99 1.00 0.99 1331
儿子/女儿 0.73 0.88 0.79 3824
accuracy 0.90 65776
macro avg 0.82 0.80 0.80 65776
weighted avg 0.90 0.90 0.89 65776
文本>>>>>: 歌曲《墨写你的美》是由歌手冷漠演唱的一首歌曲
实体>>>>>: {'歌曲': [('墨写你的美', 3, 7)], '人物': [('冷漠', 13, 14)]}
关系>>>>>: [('墨写你的美', '冷漠', '歌手')]
====================================================================================================
文本>>>>>: 982年,阎维文回到山西,隆重地迎娶了刘卫星
实体>>>>>: {'人物': [('阎维文', 5, 7), ('刘卫星', 19, 21)]}
关系>>>>>: [('阎维文', '刘卫星', '妻子'), ('刘卫星', '阎维文', '丈夫')]
====================================================================================================
文本>>>>>: 王皃姁为还是太子的刘启生了二个儿子,刘越(汉景帝第11子)、刘寄(汉景帝第12子)
实体>>>>>: {'人物': [('王皃姁', 0, 2), ('刘启', 9, 10), ('刘越', 18, 19), ('刘寄', 30, 31)]}
关系>>>>>: [('王皃姁', '刘启', '儿子/女儿'), ('刘启', '王皃姁', '儿子/女儿'), ('刘启', '刘越', '儿子/女儿'), ('刘启', '刘寄', '儿子/女儿'), ('刘越', '王皃姁', '儿子/女儿'), ('刘越', '刘启', '儿子/女儿'), ('刘寄', '王皃姁', '儿子/女儿')]
====================================================================================================
文本>>>>>: 数据分析方法五种》是2011年格致出版社出版的图书,作者是尤恩·苏尔李
实体>>>>>: {'图书作品': [('数据分析方法五种', 0, 7)], '人物': [('尤恩·苏尔李', 29, 34)]}
关系>>>>>: [('数据分析方法五种', '尤恩·苏尔李', '作者')]
====================================================================================================
文本>>>>>: 视剧《不可磨灭》是导演潘培成执导,刘蓓、丁志诚、李洪涛、丁海峰、雷娟、刘赫男等联袂主演
实体>>>>>: {'影视作品': [('不可磨灭', 3, 6)], '人物': [('潘培成', 11, 13), ('刘蓓', 17, 18), ('丁志诚', 20, 22), ('李洪涛', 24, 26), ('丁海峰', 28, 30), ('雷娟', 32, 33), ('刘赫男', 35, 37)]}
关系>>>>>: [('不可磨灭', '潘培成', '导演'), ('不可磨灭', '刘蓓', '主演'), ('不可磨灭', '丁志诚', '主演'), ('不可磨灭', '李洪涛', '主演'), ('不可磨灭', '丁海峰', '主演'), ('不可磨灭', '雷娟', '主演'), ('不可磨灭', '刘赫男', '主演')]
====================================================================================================
有一定的效果,可能训练更长时间效果更好。
由于这几个项目的代码结构都差不多,而且都和信息抽取相关,就一起放在这。
- BERT-BILSTM-CRF:中文实体识别
- BERT-Relation-Extraction:中文关系抽取
- BERT-ABSA:中文方面级情感分析
- BERT-Event-Extraction 中文事件抽取