1

我想用 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 doc 导出该数据,以便我可以将其导入到 doccano。

提前致谢。

4

3 回答 3

3

我最近有一个类似的任务,我是这样做的:

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]))

/干杯

于 2019-10-23T13:50:17.103 回答
2

Spacy 不支持这种开箱即用的确切格式,但您应该能够相当轻松地编写自定义函数。查看spacy.gold.docs_to_json(),它显示了与 JSON 的类似转换。

于 2019-09-13T14:09:26.597 回答
1

Doccano 和/或 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

区别:

  1. labelslabel在 JSON 中变成单数(?!?)
  2. e.start_char并且e.end_char实际上是(现在?)文档中的开始和结束,而不是句子中的......所以你必须通过文档中句子的位置来抵消它们。
于 2021-08-02T01:46:44.943 回答