如何将spaCy自定义跨度扩展序列化为JSON?

时间:2019-07-15 17:56:43

标签: json serialization spacy

我正在使用spaCy 2.1.6在跨度上定义custom extension

>>> from spacy import load
>>> nlp = load("en_core_web_lg")                   
>>> from spacy.tokens import Span
>>> Span.set_extension('my_label', default=None)
>>> d = nlp("The fox jumped.")
>>> d[0:2]._.my_label = "ANIMAL"
>>> d[0:2]._.my_label                   
'ANIMAL'

当我将文档序列化为JSON时,自定义范围扩展名不会出现。

>>> d.to_json()
{'text': 'The fox jumped.',
 'ents': [],
 'sents': [{'start': 0, 'end': 15}],
 'tokens': [{'id': 0,
   'start': 0,
   'end': 3,
   'pos': 'DET',
   'tag': 'DT',
   'dep': 'det',
   'head': 1},
  {'id': 1,
   'start': 4,
   'end': 7,
   'pos': 'NOUN',
   'tag': 'NN',
   'dep': 'nsubj',
   'head': 2},
  {'id': 2,
   'start': 8,
   'end': 14,
   'pos': 'VERB',
   'tag': 'VBD',
   'dep': 'ROOT',
   'head': 2},
  {'id': 3,
   'start': 14,
   'end': 15,
   'pos': 'PUNCT',
   'tag': '.',
   'dep': 'punct',
   'head': 2}]}

(我对Spans的自定义注释特别感兴趣,但Doc对象的JSON序列化似乎也是如此。)

对文档进行剔除和剔除会保留自定义扩展名。

如何将自定义范围扩展名添加到JSON序列化中,还是不支持?

3 个答案:

答案 0 :(得分:0)

使用此功能,并以任何需要的方式添加自定义扩展:


def doc2json(doc: spacy.tokens.Doc, model: str):
    json_doc = {
        "text": doc.text,
        "text_with_ws": doc.text_with_ws,
        "cats": doc.cats,
        "is_tagged": doc.is_tagged,
        "is_parsed": doc.is_parsed,
        "is_nered": doc.is_nered,
        "is_sentenced": doc.is_sentenced,
    }
    ents = [
        {"start": ent.start, "end": ent.end, "label": ent.label_} for ent in doc.ents
    ]
    if doc.is_sentenced:
        sents = [{"start": sent.start, "end": sent.end} for sent in doc.sents]
    else:
        sents = []
    if doc.is_tagged and doc.is_parsed:
        noun_chunks = [
            {"start": chunk.start, "end": chunk.end} for chunk in doc.noun_chunks
        ]
    else:
        noun_chunks = []
    tokens = [
        {
            "text": token.text,
            "text_with_ws": token.text_with_ws,
            "whitespace": token.whitespace_,
            "orth": token.orth,
            "i": token.i,
            "ent_type": token.ent_type_,
            "ent_iob": token.ent_iob_,
            "lemma": token.lemma_,
            "norm": token.norm_,
            "lower": token.lower_,
            "shape": token.shape_,
            "prefix": token.prefix_,
            "suffix": token.suffix_,
            "pos": token.pos_,
            "tag": token.tag_,
            "dep": token.dep_,
            "is_alpha": token.is_alpha,
            "is_ascii": token.is_ascii,
            "is_digit": token.is_digit,
            "is_lower": token.is_lower,
            "is_upper": token.is_upper,
            "is_title": token.is_title,
            "is_punct": token.is_punct,
            "is_left_punct": token.is_left_punct,
            "is_right_punct": token.is_right_punct,
            "is_space": token.is_space,
            "is_bracket": token.is_bracket,
            "is_currency": token.is_currency,
            "like_url": token.like_url,
            "like_num": token.like_num,
            "like_email": token.like_email,
            "is_oov": token.is_oov,
            "is_stop": token.is_stop,
            "is_sent_start": token.is_sent_start,
            "head": token.head.i,
        }
        for token in doc
    ]
    return {
        "model": model,
        "doc": json_doc,
        "ents": ents,
        "sents": sents,
        "noun_chunks": noun_chunks,
        "tokens": tokens,
    }

答案 1 :(得分:0)

因为我遇到了同样的问题,而唯一的其他答案并没有真正帮助我,我认为我也给其他人提供了一些提示。

自从 Spacy 2.1 Spacy 删除了 print_tree 并添加了 to_json。 to_json 不会返回自定义扩展,因为“此方法将输出与 spacy train 预期的 JSON 训练数据相同的格式” (https://spacy.io/usage/v2-1)。

如果要输出自定义扩展,则需要编写自己的 to_json 函数。

为此,我建议扩展 spacy 给出的 to_json()。

答案 2 :(得分:0)

不是很喜欢这里的其他两个答案,因为它们似乎有点矫枉过正(扩展了@Chooklii 的 Doc 对象或@Laksh 的自定义但不稳定的 doc2json 方法解决方案)所以我'我只是把我为我的一个项目所做的事情放在这里,也许这对某人有用。

doc = <YOUR_DOC_OBJECT>
extra_fields = [field for field in dir(doc._) if field not in ('get', 'set', 'has')]
doc_json = doc.to_json()
doc_json.update({field: doc._.get(field) for field in extra_fields})

doc_json 现在应该包含您通过 spaCy 提供的扩展接口设置的所有字段以及其他 spaCy 管道设置的字段。