实体关系,实体属性抽取是信息抽取的关键任务;实体关系抽取是指从一段文本中抽取关系三元组,实体属性抽取是指从一段文本中抽取属性三元组;信息抽取一般分以下几种情况一对一,一对多,多对一,多对多的情况:
-
一对一:“张三男汉族硕士学历”含有一对一的属性三元组(张三,民族,汉族)。
-
一对多:“华扬联众数字技术股份有限公司于2017年8月2日在上海证券交易所上市”,含有一对多的属性三元组(华扬联众数字技术股份有限公司,上市时间,2017年8月2日)和(华扬联众数字技术股份有限公司,上市地点,上海证券交易所上市)
-
多对一:“上海森焱软件有限公司和上海欧提软件有限公司的注册资本均为100万人民币”,含有多对一的属性三元组(上海森焱软件有限公司,注册资本,100万人民币)和(上海欧提软件有限公司,注册资本,100万人民币)
-
多对多:“大华种业稻麦种子加工36.29万吨、销售37.5万吨;苏垦米业大米加工22.02万吨、销售24.86万吨”,含有多对多的属性三元组(大华种业,稻麦种子产量,36.29万吨)和(苏垦米业,大米加工产量,22.02万吨)
代码结构如下:
├── data
│ ├── entity_attribute_data
│ │ ├── dev_data
│ │ │ └── dev.json
│ │ ├── predict_data
│ │ │ └── predict.json
│ │ ├── test_data
│ │ │ └── test.json
│ │ └── train_data
│ │ └── train.json
│ └── entity_relation_data
│ ├── dev_data
│ │ └── dev.json
│ ├── predict_data
│ │ └── predict.json
│ ├── test_data
│ │ └── test.json
│ └── train_data
│ └── train.json
├── data_set_reader
│ └── ie_data_set_reader.py
├── dict
│ ├── entity_attribute_label_map.json
│ └── entity_relation_label_map.json
├── examples
│ ├── many_to_many_ie_attribute_ernie_fc_ch_infer.json
│ ├── many_to_many_ie_attribute_ernie_fc_ch.json
│ ├── many_to_many_ie_relation_ernie_fc_ch_infer.json
│ └── many_to_many_ie_relation_ernie_fc_ch.json
├── inference
│ ├── custom_inference.py
│ └── __init__.py
├── model
│ ├── ernie_fc_ie_many_to_many.py
│ └── __init__.py
├── run_infer.py
├── run_trainer.py
└── trainer
├── custom_dynamic_trainer.py
├── custom_trainer.py
└── __init__.py
1.数据集简介
这里提供三份已标注的数据集:属性抽取数据集(demo示例数据集)、关系抽取数据集(demo示例数据集)、DuIE2.0(全量数据集)。
-
属性抽取训练集、测试集、验证集和预测集分别存放在./data/entity_attribute_data目录下的train_data、test_data、dev_data和predict_data文件夹下,对应的示例标签词表存放在./dict目录下。
-
关系抽取训练集、测试集、验证集和预测集分别存放在./data/entity_relation_data目录下的train_data、test_data、dev_data和predict_data文件夹下,对应的示例标签词表存放在./dict目录下。
-
DuIE2.0数据集已经上传到“数据集中”也进行解压
注:数据集(包含词表)均为utf-8格式。
Demo示例数据集(属性抽取数据集、关系抽取数据集)
demo示例数据集中属性抽取数据集与关系抽取数据集的结构一样,他们都只包含少量数据集,可用于快速开始模型的训练与预测。
训练集/测试集/的数据格式相同,每个样例分为两个部分文本和对应标签
{"text": "倪金德,1916年生,奉天省营口(今辽宁省营口市)人", "spo_list": [{"predicate": "出生日期", "subject": [0, 3], "object": [4, 9]}, {"predicate": "出生地", "subject": [0, 3], "object": [11, 16]}]}
{"text": "基本介绍克里斯蒂娜·塞寇丽(Christina Sicoli)身高163cm,在加拿大安大略出生和长大,毕业于伦道夫学院", "spo_list": [{"predicate": "毕业院校", "subject": [4, 13], "object": [55, 60]}]}
预测集只有一个key("text"):
{"text": "倪金德,1916年生,奉天省营口(今辽宁省营口市)人"}
{"text": "基本介绍克里斯蒂娜·塞寇丽(Christina Sicoli)身高163cm,在加拿大安大略出生和长大,毕业于伦道夫学院"}
标签词表:标签列表是一个json字符串,key是标签值,value是标签对应id,示例词表采用BIO标注,B表示关系,分为主体(S)与客体(O),如下所示:
{
"O": 0,
"I": 1,
"B-毕业院校@S": 2,
"B-毕业院校@O": 3,
"B-出生地@S": 4,
"B-出生地@O": 5,
"B-祖籍@S": 6,
"B-祖籍@O": 7,
"B-国籍@S": 8,
"B-国籍@O": 9,
"B-出生日期@S": 10,
"B-出生日期@O": 11
}
注意:O, I对应的ID必须是0, 1,B-XXX@O对应的id需要必须为B-XXX@S对应的id+1(B-XXX@s须为偶数,B-XXX@O须为奇数)
DuIE2.0数据集
DuIE2.0是业界规模最大的中文关系抽取数据集,其schema在传统简单关系类型基础上添加了多元复杂关系类型,此外其构建语料来自百度百科、百度信息流及百度贴吧文本,全面覆盖书面化表达及口语化表达语料,能充分考察真实业务场景下的关系抽取能力。
DuIE2.0数据集的格式与本框架所需要的文本输入格式不一致,需要进行转化成demo示例数据集的格式才能使用,具体转化步骤如下:下载数据集到 ./data/DuIE2.0 文件夹中,并解压
-
进入./data/DuIE2.0目录
-
运行./data/DuIE2.0/convert_data.py 脚本
{'text': '《司马迁之人格与风格\u3000道教徒的诗人李白及其痛苦》是李长之代表作品,共收录了两本著作,《司马迁之人格与风格》,是中国第一部透过西方文学批评视角全面审视、评价司马迁及其《史记》的学术专著', 'spo_list': [{'predicate': '作者', 'object_type': {'@value': '人物'}, 'subject_type': '图书作品', 'object': {'@value': '李长之'}, 'subject': '司马迁之人格与风格\u3000道教徒的诗人李白及其痛苦'}, {'predicate': '作者', 'object_type': {'@value': '人物'}, 'subject_type': '图书作品', 'object': {'@value': '李长之'}, 'subject': '司马迁之人格与风格 道教徒的诗人李白及其痛苦'}]}
《司马迁之人格与风格 道教徒的诗人李白及其痛苦》是李长之代表作品,共收录了两本著作,《司马迁之人格与风格》,是中国第一部透过西方文学批评视角全面审视、评价司马迁及其《史记》的学术专著 * 司马迁之人格与风格 道教徒的诗人李白及其痛苦
2.网络模型选择(文心大模型)
文心预置的可用于生成任务的模型源文件在/home/aistudio/model/ernie_fc_ie_many_to_many.py
网络名称(py文件的类型) | 简介 | 支持类型 |
---|---|---|
ErnieFcIe(ernie_fc_ie_many_to_many.py) | ErnieFcIe多对多信息抽取任务模型源文件,可加载ERNIE2.0-Base、ERNIE2.0-large、ERNIE3.0-Base、ERNIE3.0-x-Base、ERNIE3.0-Medium | 通用信息抽取Finetune任务 |
ERNIE预训练模型下载:文心提供的ERNIE预训练模型的参数文件和配置文件在 /home/aistudio/models_hub目录下,使用对应的sh脚本,即可拉取对应的模型、字典、必要环境等文件。
简单罗列可能会用的模型:
模型名称 | 下载脚本 | 备注 |
---|---|---|
ERNIE1.0-m-Base | Text | ERNIE-M:通过将跨语言语义与单语语料库对齐来增强多语言表示 |
ERNIE1.0-gen-Base | Text | ERNIE-GEN:用于自然语言生成的增强型多流预训练和微调框架 |
ERNIE2.0-Base | Text | |
ERNIE2.0-large | Text | |
ERNIE3.0-Base | Text | |
ERNIE3.0-x-Base | Text | |
ERNIE3.0-Medium | Text | 下载并解压后得到对应模型的参数、字典和配置 |
简单介绍以下几个不常用模型:
ERNIE-GEN 是面向生成任务的预训练-微调框架,首次在预训练阶段加入span-by-span 生成任务,让模型每次能够生成一个语义完整的片段。在预训练和微调中通过填充式生成机制和噪声感知机制来缓解曝光偏差问题。此外, ERNIE-GEN 采样多片段-多粒度目标文本采样策略, 增强源文本和目标文本的关联性,加强了编码器和解码器的交互。
ERNIE-GEN base 模型和 ERNIE-GEN large 模型。 预训练数据使用英文*和 BookCorpus,总共16GB。此外,我们还发布了基于 430GB 语料(数据描述见ERNIE-GEN Appendix A.1)预训练的ERNIE-GEN large 模型。
- ERNIE-GEN base (lowercased | 12-layer, 768-hidden, 12-heads, 110M parameters)
- ERNIE-GEN large (lowercased | 24-layer, 1024-hidden, 16-heads, 340M parameters)
- ERNIE-GEN large with 430G (lowercased | 24-layer, 1024-hidden, 16-heads, 340M parameters)
微调任务:在五个典型生成任务上与当前效果最优的生成预训练模型(UniLM、MASS、PEGASUS、BART、T5等)进行对比, 包括生成式摘要 (Gigaword 和 CNN/DailyMail), 问题生成(SQuAD), 多轮对话(Persona-Chat) 和生成式多轮问答(CoQA)。
https://github.com/PaddlePaddle/ERNIE/blob/repro/ernie-gen/README.zh.md
ERNIE-M 是面向多语言建模的预训练-微调框架。为了突破双语语料规模对多语言模型的学习效果限制,提升跨语言理解的效果,我们提出基于回译机制,从单语语料中学习语言间的语义对齐关系的预训练模型 ERNIE-M,显著提升包括跨语言自然语言推断、语义检索、语义相似度、命名实体识别、阅读理解在内的 5 种典型跨语言理解任务效果。
飞桨发布了 ERNIE-M base 多语言模型和 ERNIE-M large 多语言模型。
- ERNIE-M base (12-layer, 768-hidden, 12-heads)
- ERNIE-M large (24-layer, 1024-hidden, 16-heads)
下游任务:在自然语言推断,命名实体识别,阅读理解,语义相似度以及跨语言检索等任务上选取了广泛使用的数据集进行模型效果验证,并且与当前效果最优的模型(XLM、Unicoder、XLM-R、INFOXLM、VECO、mBERT等)进行对比。
https://github.com/PaddlePaddle/ERNIE/blob/repro/ernie-m/README_zh.md
3.训练&预测
3.1 属性抽取模型训练&预测
以属性抽取数据集的训练为例:
训练的配置文件:
配置文件:./examples/many_to_many_ie_attribute_ernie_fc_ch.json
{
"dataset_reader": {
"train_reader": {
"name": "train_reader",
"type": "IEReader",
"fields": [],
"config": {
"data_path": "./data/entity_attribute_data/train_data/",
"shuffle": false,
"batch_size": 2,
"epoch": 5,
"sampling_rate": 1.0,
"need_data_distribute": true,
"need_generate_examples": false,
"extra_params": {
"vocab_path": "./models_hub/ernie_3.0_base_ch_dir/vocab.txt", #选择对应预训练模型的词典路径,在models_hub路径下
"label_map_config": "./dict/entity_attribute_label_map.json",
"num_labels": 12,
"max_seq_len": 512,
"do_lower_case":true,
"in_tokens":false,
"tokenizer": "FullTokenizer"
}
}
},
"test_reader": {
"name": "test_reader",
"type": "IEReader",
"fields": [],
"config": {
"data_path": "./data/entity_attribute_data/test_data/",
"shuffle": false,
"batch_size": 2,
"epoch": 1,
"sampling_rate": 1.0,
"need_data_distribute": false,
"need_generate_examples": false,
"extra_params": {
"vocab_path": "./models_hub/ernie_3.0_base_ch_dir/vocab.txt", #选择对应预训练模型的词典路径,在models_hub路径下
"label_map_config": "./dict/entity_attribute_label_map.json",
"num_labels": 12,
"max_seq_len": 512,
"do_lower_case":true,
"in_tokens":false,
"tokenizer": "FullTokenizer"
}
}
}
},
"model": {
"type": "ErnieFcIe",
"is_dygraph":1,
"num_labels":12,
"optimization": {
"learning_rate": 5e-05,
"use_lr_decay": true,
"warmup_steps": 0,
"warmup_proportion": 0.1,
"weight_decay": 0.01,
"use_dynamic_loss_scaling": false,
"init_loss_scaling": 128,
"incr_every_n_steps": 100,
"decr_every_n_nan_or_inf": 2,
"incr_ratio": 2.0,
"decr_ratio": 0.8
},
"embedding": {
"config_path": "./models_hub/ernie_3.0_base_ch_dir/ernie_config.json" #选择对应预训练模型的配置文件路径,在models_hub路径下
}
},
"trainer": {
"type": "CustomDynamicTrainer",
"PADDLE_PLACE_TYPE": "gpu",
"PADDLE_IS_FLEET": 0,
"train_log_step": 10,
"use_amp": true,
"is_eval_dev": 0,
"is_eval_test": 1,
"eval_step": 50,
"save_model_step": 100,
"load_parameters": "",
"load_checkpoint": "",
"pre_train_model": [
{
"name": "ernie_3.0_base_ch",
"params_path": "./models_hub/ernie_3.0_base_ch_dir/params" #选择对应预训练模型的参数路径,在models_hub路径下
}
],
"output_path": "./output/ie_attribute_ernie_3.0_base_fc_ch", #输出路径
"extra_param": {
"meta":{
"job_type": "entity_attribute_extraction"
}
}
}
}
# 基于示例的数据集,可以运行以下命令在训练集(train.txt)上进行模型训练,并在测试集(test.txt)上进行验证;
# 训练属性抽取
%cd /home/aistudio
!python run_trainer.py --param_path ./examples/many_to_many_ie_attribute_ernie_fc_ch.json
# 训练运行的日志会自动保存在./log/test.log文件中;
# 训练中以及结束后产生的模型文件会默认保存在./output/目录下,其中save_inference_model/文件夹会保存用于预测的模型文件,save_checkpoint/文件夹会保存用于热启动的模型文件
部分结果展示:
INFO: 11-30 15:19:47: custom_dynamic_trainer.py:85 * 139681516312320 current learning rate: 2e-07
DEBUG: 11-30 15:19:48: ernie_fc_ie_many_to_many.py:234 * 139681516312320 phase = training precision = 1.0 recall = 1.0 f1 = 1.0 step = 2500 time_cost = 0.5210211277008057 loss = [0.00099489]
INFO: 11-30 15:19:48: custom_dynamic_trainer.py:85 * 139681516312320 current learning rate: 0.0
DEBUG: 11-30 15:19:48: ernie_fc_ie_many_to_many.py:261 * 139681516312320 phase = test precision = 0.958 recall = 0.976 f1 = 0.967 time_cost = 0.4507319927215576
INFO: 11-30 15:19:48: custom_dynamic_trainer.py:138 * 139681516312320 eval step = 14
INFO: 11-30 15:19:48: custom_dynamic_trainer.py:103 * 139681516312320 Final test result:
DEBUG: 11-30 15:19:49: ernie_fc_ie_many_to_many.py:261 * 139681516312320 phase = test precision = 0.958 recall = 0.976 f1 = 0.967 time_cost = 0.44904589653015137
INFO: 11-30 15:19:49: custom_dynamic_trainer.py:138 * 139681516312320 eval step = 14
使用预置网络进行预测的方式为使用./run_infer.py入口脚本,通过--param_path参数来传入./examples/目录下的json配置文件。
预测分为以下几个步骤:
-
基于示例的数据集,可以运行以下命令在预测集(predict.txt)上进行预测:
-
预测运行的日志会自动保存在./output/predict_result.txt文件中。
以属性抽取数据集的预测为例:
预测的配置文件
-
配置文件:./examples/many_to_many_ie_attribute_ernie_fc_ch_infer.json
-
在配置文件./examples/many_to_many_ie_attribute_ernie_fc_ch_infer.json中需要更改 inference.inference_model_path 为上面训练过程中所保存的预测模型的路径
{
"dataset_reader": {
"predict_reader": {
"name": "predict_reader",
"type": "IEReader",
"fields": [],
"config": {
"data_path": "./data/entity_attribute_data/predict_data/",
"shuffle": false,
"batch_size": 2,
"epoch": 1,
"sampling_rate": 1.0,
"extra_params": {
"vocab_path": "../../models_hub/ernie_3.0_base_ch_dir/vocab.txt",
"label_map_config": "./dict/entity_attribute_label_map.json",
"num_labels": 12,
"max_seq_len": 512,
"do_lower_case":true,
"in_tokens":false,
"tokenizer": "FullTokenizer",
"need_data_distribute": false,
"need_generate_examples": true
}
}
}
},
"inference": {
"output_path": "./output/predict_result.txt", #输出文件路径
"label_map_config": "./dict/entity_attribute_label_map.json",
"PADDLE_PLACE_TYPE": "gpu",
"inference_model_path": "./output/ie_attribute_ernie_3.0_base_fc_ch/save_inference_model/inference_step_1000", #加载推理模型
"extra_param": {
"meta": {
"job_type": "information_extraction"
}
}
}
}
3.2 关系抽取模型训练&预测
# 训练关系抽取
!python run_trainer.py --param_path ./examples/many_to_many_ie_relation_ernie_fc_ch.json
# 训练运行的日志会自动保存在./log/test.log文件中;
# 训练中以及结束后产生的模型文件会默认保存在./output/目录下,其中save_inference_model/文件夹会保存用于预测的模型文件,save_checkpoint/文件夹会保存用于热启动的模型文件
部分结果展示:
DEBUG: 11-30 16:09:37: ernie_fc_ie_many_to_many.py:261 * 140264317826816 phase = test precision = 0.953 recall = 0.968 f1 = 0.96 time_cost = 0.7550814151763916
INFO: 11-30 16:09:37: custom_dynamic_trainer.py:138 * 140264317826816 eval step = 50
INFO: 11-30 16:09:41: dynamic_trainer.py:170 * 140264317826816 save path: ./output/ie_relation_ernie_3.0_medium/save_inference_model/inference_step_2500
INFO: 11-30 16:09:42: custom_dynamic_trainer.py:103 * 140264317826816 Final test result:
DEBUG: 11-30 16:09:43: ernie_fc_ie_many_to_many.py:261 * 140264317826816 phase = test precision = 0.953 recall = 0.968 f1 = 0.96 time_cost = 0.883291482925415
INFO: 11-30 16:09:43: custom_dynamic_trainer.py:138 * 140264317826816 eval step = 50
部分结果:
"text": "杨力革,男,汉族,1966年4月生,湖南益阳人,1987年7月参加工作,1992年10月入党,在职研究生学历(2004年7月*自治区党委党校领导*研究生班工商管理专业毕业)",
"spo_list": [
{
"predicate": "出生地",
"subject": [
0,
3
],
"object": [
18,
22
]
},
{
"predicate": "出生日期",
"subject": [
0,
3
],
"object": [
9,
16
]
}
]
4.总结
本项目讲解了基于ERNIE信息抽取技术,对属性和关系的抽取涉及多对多抽取,主要是使用可ERNIEKIT组件,整体效果非常不错,当然追求小样本学习的可以参考之前UIE项目或者去官网看看paddlenlp最新的更新,对训练和部署进行了提速。
模型 | 任务 | precision | recall | f1 |
---|---|---|---|---|
ernie_3.0_medium | 属性抽取 | 0.958 | 0.976 | 0.967 |
ernie_3.0_medium | 关系抽取 | 0.953 | 0.968 | 0.96 |