Я пытался обучить модель из космоса. У меня есть строки и смещения их токенов, сохраненные в файле JSON.
Я прочитал этот файл, используя кодировку utf-8
, и в нем нет специального символа. Но поднимает TypeError: object of type 'NoneType' has no len()
# code for reading file
with open("data/results.json", "r", encoding="utf-8") as file:
training_data = json.loads(file.read())
Я также пытался изменить alignment_type
с strict
на contract
и expand
. expand
работает, но показывает неправильные интервалы.
span = doc.char_span(start, end, label, alignment_mode="contract")
Код, который я использую
import spacy
from spacy.tokens import DocBin
nlp = spacy.blank("en")
db = DocBin()
training_dataset = [[
"Department of Chemistry,Central University of Las Villas,Santa Clara,Villa Clara,54830,Cuba.",
[
[
57,
68,
"city_name"
],
[
87,
91,
"country_name"
]
]
]]
for text, annotations in training_dataset:
doc = nlp(text)
ents = []
for start, end, label in annotations:
span = doc.char_span(start, end, label)
ents.append(span)
doc.ents = ents
db.add(doc)
Я вставил объект JSON, считанный из файла, непосредственно в программу для целей отладки.
Когда я попытался после удаления части 54830,
, программа успешно запустилась.
Я также упомянул об этой Выпуске, но этот выпуск имеет особый характер. Но в этой строке нет специального символа.
Кто-нибудь может знать, почему это происходит со всеми строками, содержащими число?
@ J.Ferrarons Я использую в своей системе spacy версии 3.4.3, и это последняя версия.
Ошибка TypeError: object of type 'NoneType' has no len()
возникает в строке doc.ents = ents
, когда одной из записей в ents
является None
.
Причина наличия None
в списке заключается в том, что doc.char_span(start, end, label)
возвращает None
, когда предоставленные start
и end
не совпадают с границами токенов.
Токенизатор модели (spacy.blank("en")
) ведет себя не так, как необходимо для этого варианта использования. Кажется, что он не производит конец токена после запятой, которая следует за числом без пробела после запятой.
Примеры:
Токенизация числа десятичными знаками:
>>> import spacy
>>> nlp = spacy.blank("en")
>>> nlp.tokenizer.explain("5,1")
[('TOKEN', '5,1')]
Один единственный токен.
Токенизация числа + запятая + буква:
>>> nlp.tokenizer.explain("5,a")
[('TOKEN', '5,a')]
Один единственный токен.
Токенизация буква + запятая + буква:
>>> nlp.tokenizer.explain("a,a")
[('TOKEN', 'a'), ('INFIX', ','), ('TOKEN', 'a')]
Три жетона.
Токенизация числа + запятая + пробел + буква:
>>> nlp.tokenizer.explain("5, a")
[('TOKEN', '5'), ('SUFFIX', ','), ('TOKEN', 'a')]
Три жетона.
Токенизация числа + запятая + пробел + число:
>>> nlp.tokenizer.explain("5, 1")
[('TOKEN', '5'), ('SUFFIX', ','), ('TOKEN', '1')]
Три жетона.
Поэтому при использовании токенизатора по умолчанию после запятой после числа требуется пробел, поэтому запятая используется для создания границ токена.
Обходные пути:
start
и end
аннотаций.Спасибо большое за твою помощь. Не думал об этом. Это решило мою проблему.
Какую версию Spacy вы используете? Вы пробовали с последней?