简介
Doccano 标注导出格式如下所示:
{
'id': 6400, 'text': '扎实推进垃圾分类示范区创建,实现覆盖率100%,开展垃圾分类示范片区创建的街道占比达到100%', 'Comments': [], 'entities': [{
'id': 1662, 'label': '关键数据', 'start_offset': 26, 'end_offset': 39}, {
'id': 1663, 'label': '数值', 'start_offset': 43, 'end_offset': 47}], 'relations': [{
'id': 273, 'from_id': 1662, 'to_id': 1663, 'type': '达到'}]}
Doccano 标注导出格式的数据,不方便使用,无论是做信息抽取训练还是导入到图数据库中等,均无法直接使用;
故本文将其转为 DeepKE 大模型训练数据格式,从而实现方便用户使用的目的。
虽然读者不一定使用DeepKE 训练大模型做信息抽取,但是转换后的数据格式,也能简化读者的数据转换工作。
本文将Doccano标注导出的格式,转化为下述格式
- 如下是命名实体识别的数据格式:
{ "text": "相比之下,青岛海牛队和广州松日队的雨中之战虽然也是0∶0,但乏善可陈。", "entity": [{ "entity": "广州松日队", "entity_type": "组织机构"}, { "entity": "青岛海牛队", "entity_type": "组织机构"}]}
- 如下是SPO的数据格式:
{ "text": "(电影里让我直接想起来的还有——吴宇森导演的《辣手神探》的殓房的秘门啊", "relation": [{ "head": "辣手神探", "head_type": "影视作品", "relation": "导演", "tail": "吴宇森", "tail_type": "人物"}]}
代码实现
核心转换代码
utils.py
,点击查看代码文件
import json
from dataclasses import dataclass
from typing import List
@dataclass
class Ent:
entity: str
entity_type: str
@dataclass
class Rel:
head: str
head_type: str
relation: str
tail: str
tail_type: str
@classmethod
def from_defaults(cls, head_ent: Ent, rel: str, tail_ent: Ent):
return cls(
head_ent.entity,
head_ent.entity_type,
rel,
tail_ent.entity,
tail_ent.entity_type
)
@dataclass
class DataFormat:
text: str
entity: List[Ent]
relation: List[Rel]
def to_string(self):
return json.dumps(
{
'text': self.text,
'entity': str([ent.__dict__ for ent in self.entity]),
'relation': str([rel.__dict__ for rel in self.relation])
},
ensure_ascii=False
)
def doccano_trans(item):
text = item['text']
ents = item['entities']
rels = item['relations']
ent_d = {
}
for ent in ents:
start_offset, end_offset = ent['start_offset'], ent['end_offset']
name = text[start_offset:end_offset]
label = ent['label']
ent_d[ent['id']] = Ent(name, label)
res_rel = []
for rel in rels:
from_id, to_id, rel_name = rel['from_id'], rel['to_id'], rel['type']
head_ent, tail_ent = ent_d[from_id], ent_d[to_id]
res_rel.append(
Rel.from_defaults(head_ent, rel_name, tail_ent)
)
data_format = DataFormat(text, list(ent_d.values()), res_rel)
return data_format.to_string()
if __name__ == '__main__':
data = {
'id': 6400, 'text': '扎实推进垃圾分类示范区创建,实现覆盖率100%,开展垃圾分类示范片区创建的街道占比达到100%',
'Comments': [], 'entities': [{
'id': 1662, 'label': '关键数据', 'start_offset': 26, 'end_offset': 39},
{
'id': 1663, 'label': '数值', 'start_offset': 43, 'end_offset': 47}],
'relations': [{
'id': 273, 'from_id': 1662, 'to_id': 1663, 'type': '达到'}]}
print(doccano_trans(data))
上述代码中的data 来自 Doccano标注的数据,使用doccano_trans
函数,将其转换为如下格式:
{
"text": "扎实推进垃圾分类示范区创建,实现覆盖率100%,开展垃圾分类示范片区创建的街道占比达到100%", "entity": "[{'entity': '垃圾分类示范片区创建的街道', 'entity_type': '关键数据'}, {'entity': '100%', 'entity_type': '数值'}]", "relation": "[{'head': '垃圾分类示范片区创建的街道', 'head_type': '关键数据', 'relation': '达到', 'tail': '100%', 'tail_type': '数值'}]"}
文件转换
在核心转换代码部分实现了将某一个 Doccano标注的数据进行转换;
下述代码实现,直接转换整个导出的jsonl文件:
core.py
, 点击查看代码文件
import json
from utils import doccano_trans
file = 'data/test.jsonl'
data = []
with open(file, 'r', encoding='utf-8') as f:
for line in f:
data.append(
doccano_trans(json.loads(line))
)
with open('out.jsonl', 'w', encoding='utf-8') as f:
f.write('\n'.join(data))
上述代码执行后,会在当前文件夹创建out.jsonl
文件,保存转换完成的结果;
文章评论