首页 > 解决方案 > spaCy:是否可以将 json 格式(使用 BILUO 方案)文件转换为用于 Python 训练的列表格式?

问题描述

我想使用 wikiner 数据集对 spaCy 的预训练模型进行一些评估。但是,这些数据集是 json 格式,使用 BILUO 注释方案。我知道我可以在命令行界面中进行评估,但我想在 Python 解释器中进行,这需要不同的数据格式,如下所示。

TRAIN_DATA = [("Dogs are loyal", {'entities': [(0, 4, 'ANIMAL)]})]

不知道有没有办法将BILUO方案json格式的数据转换成下面的格式。或者,是否可以直接评估 json 格式的数据(例如,我可以将 json 文件读入 Python 解释器。)

谢谢!

编辑:添加示例 json 数据集

[
  {
    "id":0,
    "paragraphs":[
      {
        "sentences":[
          {
            "tokens":[
              {
                "orth":"Zum",
                "tag":"-",
                "ner":"O"
              },
              {
                "orth":"1.",
                "tag":"-",
                "ner":"O"
              },
              {
                "orth":"Januar",
                "tag":"-",
                "ner":"O"
              },
              {
                "orth":"1994",
                "tag":"-",
                "ner":"O"
              },
              {
                "orth":"wird",
                "tag":"-",
                "ner":"O"
              },
              {
                "orth":"Ruppendorf",
                "tag":"-",
                "ner":"U-LOC"
              },
              {
                "orth":"nach",
                "tag":"-",
                "ner":"O"
              },
              {
                "orth":"H\u00f6ckendorf",
                "tag":"-",
                "ner":"U-LOC"
              },
              {
                "orth":"eingemeindet",
                "tag":"-",
                "ner":"O"
              },
              {
                "orth":".",
                "tag":"-",
                "ner":"O"
              }
            ]
          }
        ]
      }
    ]
  },

标签: pythonjsonnlpspacy

解决方案


最初的警告:您可能已经意识到这一点,但是 spacy 的许多非英语 NER 模型都是在 WikiNER 上训练的,所以请注意,您可能会不小心对训练数据进行评估,这显然不会让您对该模型的效果如何。

如果你有 spacy 的带有 BILUO NER 标签的内部 JSON 训练格式,并且你希望实体跨度由字符偏移量引用,你可以加载数据GoldCorpus并将其转换为偏移量spacy.gold.offsets_from_biluo_tags。请注意,在没有为每个段落提供raw文本的情况下,在计算字符偏移量时,每个标记之间将有一个空格。

import spacy
from spacy.gold import GoldCorpus, offsets_from_biluo_tags

nlp = spacy.load('de')
goldcorpus = GoldCorpus("/path/to/train.json", "/path/to/train.json")

train_docs = goldcorpus.train_docs(nlp)
for doc, gold in train_docs:
    print(doc.text)
    print(offsets_from_biluo_tags(doc, gold.ner))

输出:

Zum 1. Januar 1994 wird Ruppendorf nach Höckendorf eingemeindet .
[(24, 34, 'LOC'), (40, 50, 'LOC')]

笔记:

  • GoldCorpus.train_docs()需要该nlp模型来处理语料库中的标记化与 spacy 不同的情况。
  • GoldCorpus总是希望同时提供火车和开发数据GoldCorpus(train_path, dev_path),因此只要您不将开发数据用于任何事情,加载两者的火车数据就不会导致任何问题。

推荐阅读