如何将带有命名实体的CoNNL格式的文本导入spaCy,使用我的模型推断实体并将它们写入同一数据集(使用Python)?
我有一个CoNLL-NER格式的数据集,它基本上是一个带有两个字段的TSV文件。第一个字段包含一些文本中的标记-每行一个标记(每个标点符号也被视为标记),第二个字段包含BIO格式标记的命名实体标记 我想将这个数据集加载到spaCy中,用我的模型为文本推断新的命名实体标记,并将这些标记写入与新的第三列相同的TSV文件中。 我所知道的是,我可以通过以下方式推断命名实体:如何将带有命名实体的CoNNL格式的文本导入spaCy,使用我的模型推断实体并将它们写入同一数据集(使用Python)?,python,json,spacy,ner,conll,Python,Json,Spacy,Ner,Conll,我有一个CoNLL-NER格式的数据集,它基本上是一个带有两个字段的TSV文件。第一个字段包含一些文本中的标记-每行一个标记(每个标点符号也被视为标记),第二个字段包含BIO格式标记的命名实体标记 我想将这个数据集加载到spaCy中,用我的模型为文本推断新的命名实体标记,并将这些标记写入与新的第三列相同的TSV文件中。 我所知道的是,我可以通过以下方式推断命名实体: nlp=spacy.load(“一些空间模型”) text=“来自conll数据集的文本” doc=nlp(文本) 此外,我还使
nlp=spacy.load(“一些空间模型”)
text=“来自conll数据集的文本”
doc=nlp(文本)
此外,我还使用以下CLI命令将CoNLL数据集转换为spaCy的json格式:
python-mspacy conll_dataset.tsv/Users/user/docs-t json-c ner
但我不知道接下来该怎么办。找不到如何将此json
文件加载到spaCyDoc
格式。我尝试了这段代码(在spaCy的文档中找到):
来自spacy.tokens导入文档
从spacy.vocab导入vocab
doc=doc(Vocab())。来自磁盘(“sample.json”)
但是它抛出一个错误,说ExtraData:unpack(b)收到了额外的数据。
此外,我不知道如何将doc
对象中的NER写入同一TSV文件,将令牌和NER标记与TSV文件的现有行对齐
以下是TSV文件的摘录,作为我正在处理的数据示例:
The O
epidermal B-Protein
growth I-Protein
factor I-Protein
precursor O
. O
SpacyAPI在这里有一点差距,因为这种格式通常只用于训练模型。这是可能的,但并不明显。您必须加载语料库,因为它将作为培训加载为
GoldCorpus
,这将为您提供标记化但未标记的文档和原始格式注释的goldparse
然后,您可以将原始的GoldParse
注释转换为正确的格式,并手动将其添加到Doc
中。以下是实体的草图:
import spacy
from spacy.gold import GoldCorpus
nlp = spacy.load('en')
gc = GoldCorpus("file.json", "file.json")
for doc, gold in gc.dev_docs(nlp, gold_preproc=True):
doc.ents = spacy.gold.spans_from_biluo_tags(doc, gold.ner)
spacy.displacy.serve(doc, style='ent')
此处使用的是dev_docs()
,因为它加载文档时不会进行任何进一步的洗牌、扩充等操作,就像用于培训一样,并且它正在将第二个参数中的文件加载到GoldCorpus
GoldCorpus
需要一个培训文件和一个开发文件,因此第一个参数是必需的,但我们不会对从第一个参数加载的数据做任何进一步的处理
目前,请使用spacy 2.1.8进行此操作,因为2.2.1中的
gold\u preproc
选项存在缺陷gold\u preproc
保留您原来的标记化,而不是使用spacy重新标记。如果您不关心保留标记化,您可以设置gold\u preproc=False
,然后spacy提供的模型将工作得稍微好一点,因为标记化是相同的。spacy API中有一点空白,因为这种格式通常只用于训练模型。这是可能的,但并不明显。您必须加载语料库,因为它将作为培训加载为GoldCorpus
,这将为您提供标记化但未标记的文档和原始格式注释的goldparse
然后,您可以将原始的GoldParse
注释转换为正确的格式,并手动将其添加到Doc
中。以下是实体的草图:
import spacy
from spacy.gold import GoldCorpus
nlp = spacy.load('en')
gc = GoldCorpus("file.json", "file.json")
for doc, gold in gc.dev_docs(nlp, gold_preproc=True):
doc.ents = spacy.gold.spans_from_biluo_tags(doc, gold.ner)
spacy.displacy.serve(doc, style='ent')
此处使用的是dev_docs()
,因为它加载文档时不会进行任何进一步的洗牌、扩充等操作,就像用于培训一样,并且它正在将第二个参数中的文件加载到GoldCorpus
GoldCorpus
需要一个培训文件和一个开发文件,因此第一个参数是必需的,但我们不会对从第一个参数加载的数据做任何进一步的处理
目前,请使用spacy 2.1.8进行此操作,因为2.2.1中的
gold\u preproc
选项存在缺陷gold\u preproc
保留您原来的标记化,而不是使用spacy重新标记。如果您不关心保留标记化,您可以设置gold\u preproc=False
,然后spacy提供的模型将工作得更好,因为标记化是相同的。感谢您的回答,它似乎可以工作!我设法加载数据集,然后用另一个模型推断出新的NER标记。您能给我一个建议,告诉我如何使用IOB标签将结果保存回CoNLL格式(带有两个字段的tsv-令牌及其标签)?IOB标签可通过token.ent\u IOB\u
和token.ent\u type
获得。请参见此处的令牌属性:感谢您的回答,它似乎有效!我设法加载数据集,然后用另一个模型推断出新的NER标记。您能给我一个建议,告诉我如何使用IOB标签将结果保存回CoNLL格式(带有两个字段的tsv-令牌及其标签)?IOB标签可通过token.ent\u IOB\u
和token.ent\u type
获得。请参见此处的令牌属性:非常感谢您提出这个问题!非常感谢你提出这个问题!