spaCy,准备训练数据:doc.char_span 返回 'None'

spaCy, preparing training data: doc.char_span returning 'None'

我正在按照 spaCy 文档中的说明准备我自己的训练数据 (here)。

我的问题从这一行开始:

span = doc.char_span(start, end, label=label)

对于我标记为组织的实体 ('ORG'),它似乎工作正常,即它 returns 一个跨度对象。但是,对于我标记为金钱的实体 ('MONEY'),它 returns 是一个 None 对象。

这是我训练集中的两个例子:

('Payments from the Guardian, Kings Place, 90 York Way, London N1 9GU, for articles:', [(18, 26, 'ORG')]) // Returns a span object for 'Guardian'

('24 July 2020, received £100. Hours: 1 hr. (Registered 02 February 2021)', [(24, 28, 'MONEY')]) // Returns None for '£100'

注意:Â出现在控制台中,但它不在原始 json 文本文件中。留下它以防万一它是问题的一部分

有人对我哪里出错有什么建议吗?

[我对spacy很陌生(上周开始学习),所以请ELI5!]

更新:看来 Â 可能是问题所在,以下是我加载数据的方式。我如何摆脱 Â's? (在原始文件中不可见)

with open('training_data.json') as train_data:
    train_data_json = json.load(train_data)

导致问题的是 Â 符号。当它存在时 span returns None 正如您正确指出的那样。

用于测试的训练数据(注意 'MONEY' 注释的更新索引):

train = [("Tokyo Tower is 333m tall.", [(0, 11, "BUILDING")]),
        ('Payments from the Guardian, Kings Place, 90 York Way, London N1 9GU, for articles:', [(18, 26, 'ORG')]),
        ('24 July 2020, received £100. Hours: 1 hr. (Registered 02 February 2021)', [(23, 27, 'MONEY')])]

您共享的 spacy 文档中的代码:

db = DocBin()
for text, annotations in train:
    doc = nlp(text)
    for start, end, label in annotations:
        span = doc.char_span(start, end, label=label)
        print(span)

输出:

Tokyo Tower
Guardian
£100

打开文件时出现编码问题。 MONEY 类型的 tags 上的信息提取上下文无法解决此问题,因为令牌的开头不是 £

不清楚文件使用的是什么编码,所以首先尝试一些最常见的编码,它们是 utf-8iso-8859-1latin1

with open('training_data.json', encoding='utf-8')
    # your logic here

用其他潜在候选人替换encoding

正如其他答案所指出的,您有一个编码问题需要解决。我们不能在没有看到文件的情况下说出您的文件是什么编码。通常在 Linux 上你可以使用 file 命令来检查编码(不完美,但相当不错),但是 JSON 应该总是 UTF8,所以这对这里没有帮助。如果您可以访问 JSON 之前的数据源,您可能需要检查一下。

但是除此之外,问题是 char_span returns None 如果您的跨度无效,也就是说,如果您的字符索引与标记边界不对齐。例如,如果您想在“Tokyo Tower is...”示例中标记“Tokyo”,但给出字符索引 0 和 4(“Toky”),您将得到 None.

在这种情况下,听起来你有一个需要修复的系统错误,但如果有少量注释是错误的,你可以将一些选项传递给函数,告诉它在对齐时扩展或收缩而是关闭。查看 the docs 了解更多详情。