如何导出 "Document with entities from spaCy" 以在 doccano 中使用
How to export "Document with entities from spaCy" for use in doccano
我想用 doccano 或其他“开源文本注释工具”训练我的模型并不断改进我的模型。
我的理解是,我可以按照此处描述的格式将带注释的数据导入 doccano:
因此,第一步我加载了一个模型并创建了一个文档:
text = "Test text that should be annotated for Michael Schumacher"
nlp = spacy.load('en_core_news_sm')
doc = nlp(text)
我知道我可以从 doccano 导出 jsonl 格式(带有文本和带注释的标签)并用它训练模型,但我想知道如何从 python 中的 spaCy 文档导出该数据,以便我可以将它导入 doccano。
提前致谢。
Spacy 不支持这种开箱即用的确切格式,但您应该能够相当轻松地编写自定义函数。看看 spacy.gold.docs_to_json(),它显示了与 JSON.
类似的转换
我最近有一个类似的任务,这是我的做法:
import spacy
nlp = spacy.load('en_core_news_sm')
def text_to_doccano(text):
"""
:text (str): source text
Returns (list (dict)): deccano format json
"""
djson = list()
doc = nlp(text)
for sent in doc.sents:
labels = list()
for e in sent.ents:
labels.append([e.start_char, e.end_char, e.label_])
djson.append({'text': sent.text, "labels": labels})
return djson
基于你的例子...
text = "Test text that should be annotated for Michael Schumacher."
djson = text_to_doccano(text)
print(djson)
... 会打印出:
[{'text': 'Test text that should be annotated for Michael Schumacher.', 'labels': [[39, 57, 'PERSON']]}]
在相关说明中,当您将结果保存到文件时,标准 json.dump
保存 JSON 的方法将不起作用,因为它会将其写入以逗号分隔的条目列表。 AFAIK,doccano
期望每行一个条目并且没有尾随逗号。在解决这个问题时,以下代码片段很有魅力:
import json
open(filepath, 'w').write("\n".join([json.dumps(e) for e in djson]))
/干杯
Doccano and/or spaCy 似乎已经改变了一些东西,现在接受的答案中有一些缺陷。截至 2021 年 8 月 1 日,此修订版应该更适用于 spaCy 3.1 和 Doccano...
def text_to_doccano(text):
"""
:text (str): source text
Returns (list (dict)): deccano format json
"""
djson = list()
doc = nlp(text)
for sent in doc.sents:
labels = list()
for e in sent.ents:
labels.append([e.start_char - sent.start_char, e.end_char - sent.start_char, e.label_])
djson.append({'text': sent.text, "label": labels})
return djson
不同点:
labels
在 JSON 中变为单数 label
(?!?)
e.start_char
和 e.end_char
实际上(现在?)文档中的开始和结束,而不是句子中...所以你必须通过句子中的位置来抵消它们文档。
我用过Doccano标注工具,生成标注,
我已经从 Doccano 导出了 .jsonl 文件
使用以下自定义代码转换为 .spaCy 训练格式。
要遵循的步骤:
第一步:使用doccano工具标注数据。
第 2 步: 从 Doccano 导出注释文件,格式为 .jsonl。
第 3 步: 将该 .jsonl 文件传递给下面代码中的 fillterDoccanoData("./root.jsonl")
函数,在我的例子中,我有 root.jsonl 对我来说,你可以用你自己的。
第 4 步: 使用以下代码将您的 .jsonl 文件转换为 .spacy 训练文件。
第 5 步: 最后,您可以在工作目录中找到 train.spacy。
谢谢
import spacy
from spacy.tokens import DocBin
from tqdm import tqdm
import logging
import json
#filtter data to convert in spacy format
def fillterDoccanoData(doccano_JSONL_FilePath):
try:
training_data = []
lines=[]
with open(doccano_JSONL_FilePath, 'r') as f:
lines = f.readlines()
for line in lines:
data = json.loads(line)
text = data['data']
entities = data['label']
if len(entities)>0:
training_data.append((text, {"entities" : entities}))
return training_data
except Exception as e:
logging.exception("Unable to process " + doccano_JSONL_FilePath + "\n" + "error = " + str(e))
return None
#read Doccano Annotation file .jsonl
TRAIN_DATA=fillterDoccanoData("./root.jsonl") #root.jsonl is annotation file name file name
nlp = spacy.blank("en") # load a new spacy model
db = DocBin() # create a DocBin object
for text, annot in tqdm(TRAIN_DATA): # data in previous format
doc = nlp.make_doc(text) # create doc object from text
ents = []
for start, end, label in annot["entities"]: # add character indexes
span = doc.char_span(start, end, label=label, alignment_mode="contract")
if span is None:
print("Skipping entity")
else:
ents.append(span)
try:
doc.ents = ents # label the text with the ents
db.add(doc)
except:
print(text, annot)
db.to_disk("./train.spacy") # save the docbin object
我想用 doccano 或其他“开源文本注释工具”训练我的模型并不断改进我的模型。
我的理解是,我可以按照此处描述的格式将带注释的数据导入 doccano:
因此,第一步我加载了一个模型并创建了一个文档:
text = "Test text that should be annotated for Michael Schumacher"
nlp = spacy.load('en_core_news_sm')
doc = nlp(text)
我知道我可以从 doccano 导出 jsonl 格式(带有文本和带注释的标签)并用它训练模型,但我想知道如何从 python 中的 spaCy 文档导出该数据,以便我可以将它导入 doccano。
提前致谢。
Spacy 不支持这种开箱即用的确切格式,但您应该能够相当轻松地编写自定义函数。看看 spacy.gold.docs_to_json(),它显示了与 JSON.
类似的转换我最近有一个类似的任务,这是我的做法:
import spacy
nlp = spacy.load('en_core_news_sm')
def text_to_doccano(text):
"""
:text (str): source text
Returns (list (dict)): deccano format json
"""
djson = list()
doc = nlp(text)
for sent in doc.sents:
labels = list()
for e in sent.ents:
labels.append([e.start_char, e.end_char, e.label_])
djson.append({'text': sent.text, "labels": labels})
return djson
基于你的例子...
text = "Test text that should be annotated for Michael Schumacher."
djson = text_to_doccano(text)
print(djson)
... 会打印出:
[{'text': 'Test text that should be annotated for Michael Schumacher.', 'labels': [[39, 57, 'PERSON']]}]
在相关说明中,当您将结果保存到文件时,标准 json.dump
保存 JSON 的方法将不起作用,因为它会将其写入以逗号分隔的条目列表。 AFAIK,doccano
期望每行一个条目并且没有尾随逗号。在解决这个问题时,以下代码片段很有魅力:
import json
open(filepath, 'w').write("\n".join([json.dumps(e) for e in djson]))
/干杯
Doccano and/or spaCy 似乎已经改变了一些东西,现在接受的答案中有一些缺陷。截至 2021 年 8 月 1 日,此修订版应该更适用于 spaCy 3.1 和 Doccano...
def text_to_doccano(text):
"""
:text (str): source text
Returns (list (dict)): deccano format json
"""
djson = list()
doc = nlp(text)
for sent in doc.sents:
labels = list()
for e in sent.ents:
labels.append([e.start_char - sent.start_char, e.end_char - sent.start_char, e.label_])
djson.append({'text': sent.text, "label": labels})
return djson
不同点:
labels
在 JSON 中变为单数label
(?!?)e.start_char
和e.end_char
实际上(现在?)文档中的开始和结束,而不是句子中...所以你必须通过句子中的位置来抵消它们文档。
我用过Doccano标注工具,生成标注, 我已经从 Doccano 导出了 .jsonl 文件 使用以下自定义代码转换为 .spaCy 训练格式。
要遵循的步骤:
第一步:使用doccano工具标注数据。
第 2 步: 从 Doccano 导出注释文件,格式为 .jsonl。
第 3 步: 将该 .jsonl 文件传递给下面代码中的 fillterDoccanoData("./root.jsonl")
函数,在我的例子中,我有 root.jsonl 对我来说,你可以用你自己的。
第 4 步: 使用以下代码将您的 .jsonl 文件转换为 .spacy 训练文件。
第 5 步: 最后,您可以在工作目录中找到 train.spacy。
谢谢
import spacy
from spacy.tokens import DocBin
from tqdm import tqdm
import logging
import json
#filtter data to convert in spacy format
def fillterDoccanoData(doccano_JSONL_FilePath):
try:
training_data = []
lines=[]
with open(doccano_JSONL_FilePath, 'r') as f:
lines = f.readlines()
for line in lines:
data = json.loads(line)
text = data['data']
entities = data['label']
if len(entities)>0:
training_data.append((text, {"entities" : entities}))
return training_data
except Exception as e:
logging.exception("Unable to process " + doccano_JSONL_FilePath + "\n" + "error = " + str(e))
return None
#read Doccano Annotation file .jsonl
TRAIN_DATA=fillterDoccanoData("./root.jsonl") #root.jsonl is annotation file name file name
nlp = spacy.blank("en") # load a new spacy model
db = DocBin() # create a DocBin object
for text, annot in tqdm(TRAIN_DATA): # data in previous format
doc = nlp.make_doc(text) # create doc object from text
ents = []
for start, end, label in annot["entities"]: # add character indexes
span = doc.char_span(start, end, label=label, alignment_mode="contract")
if span is None:
print("Skipping entity")
else:
ents.append(span)
try:
doc.ents = ents # label the text with the ents
db.add(doc)
except:
print(text, annot)
db.to_disk("./train.spacy") # save the docbin object