格式化 SpaCy NER 的训练数据集

Dio*_*sos 6 format json named-entity-recognition training-data spacy

我想用我自己的实体为 NER 训练一个空白模型。为此,我需要使用一个数据集,该数据集当前为 .csv 格式并具有以下格式的实体标签(我将为每个相关列提供一个示例行):


栏目:句子

价值:我想要苹果


列:数据

值:['want;@command;2;6','apples';@fruit;7;13']


列:实体

值:我@command @fruit


列:entity_types

值:@bot/@command;@bot/@food/@fruit


为了训练 SpaCy 的 NER,我需要以下格式的 json 形式的训练数据:

    TRAIN_DATA = [
    ('Who is Shaka Khan?', {
        'entities': [(7, 17, 'PERSON')]
    }),
    ('I like London and Berlin.', {
        'entities': [(7, 13, 'LOC'), (18, 24, 'LOC')]
    })
]
Run Code Online (Sandbox Code Playgroud)

链接到 SpaCy 文档中的相关部分

我试图找到一种解决方案,以解决如何将数据从 csv 重新格式化为 SpaCy 所需的格式,但到目前为止我还没有成功。数据集确实包含所有必要的信息——文本字符串、实体名称、实体类型、实体偏移——但我根本不知道如何以正确的形式获取它们。

我将不胜感激关于我将如何实现这一目标的任何和所有帮助!

Ine*_*ani 6

从您的问题中并没有 100% 清楚您是否也在询问 CSV 提取 - 所以我只是假设这不是问题。(如果是这样,使用该csv模块应该很容易实现。如果 CSV 数据很混乱并且包含一堆组合在一个字符串中的东西,您可能必须调用split它并以hacky 的方式进行。)

如果您能够以这样的格式提取“句子”和“数据”列,那么您实际上已经非常接近 spaCy 的训练格式了:

[{ 
    'sentence': 'I want apples'
    'data': [('want', '@command', 2, 6) ('apples', '@fruit', 7, 13)]
}]
Run Code Online (Sandbox Code Playgroud)

+1与 spaCy 相比,您的数据似乎以不同的方式计算结束字符,并且偏移量为。所以你必须通过减去来调整它1。我可能把它写得比它应该的要冗长得多,但我希望这能让它更容易理解:

TRAIN_DATA = []

for example in your_extracted_data:  # see example above
    entities = []
    for entity in example['data']:  # iterate over the entities
        text, label, start, end = entity  # ('want', '@command', 2, 6)
        label = label.split('@')[1].upper()  # not necessary, but nicer
        end = end - 1  # correct the end character index
        entities.append((start, end, label))
    # add training example of (text, annotations) tuple
    TRAIN_DATA.append((example['sentence'], {'entities': entities}))
Run Code Online (Sandbox Code Playgroud)

这应该为您提供如下所示的训练数据:

[
    ('I want apples', {'entities': [(2, 5, 'COMMAND'), (7, 12, 'FRUIT')]})
]
Run Code Online (Sandbox Code Playgroud)