Spacy doc.char_span вызывает ошибку всякий раз, когда в строке есть какое-либо число

Я пытался обучить модель из космоса. У меня есть строки и смещения их токенов, сохраненные в файле 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,, программа успешно запустилась.

Я также упомянул об этой Выпуске, но этот выпуск имеет особый характер. Но в этой строке нет специального символа.

Кто-нибудь может знать, почему это происходит со всеми строками, содержащими число?

Какую версию Spacy вы используете? Вы пробовали с последней?

J. Ferrarons 18.11.2022 21:02

@ J.Ferrarons Я использую в своей системе spacy версии 3.4.3, и это последняя версия.

SHIVAM SINGH 19.11.2022 08:02
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
Python PyPDF2 - запись метаданных PDF
Python PyPDF2 - запись метаданных PDF
Python скрипт, который будет записывать метаданные в PDF файл, для этого мы будем использовать PDF ридер из библиотеки PyPDF2 . PyPDF2 - это...
Переменные, типы данных и операторы в Python
Переменные, типы данных и операторы в Python
В Python переменные используются как место для хранения значений. Пример переменной формы:
Почему Python - идеальный выбор для проекта AI и ML
Почему Python - идеальный выбор для проекта AI и ML
Блог, которым поделился Harikrishna Kundariya в нашем сообществе Developer Nation Community.
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Как автоматически добавлять котировки в заголовки запросов с помощью PyCharm
Анализ продукта магазина на Tokopedia
Анализ продукта магазина на Tokopedia
Tokopedia - это место, где продавцы могут продавать свои товары. Товар должен быть размещен на витрине, чтобы покупателям было легче найти товар...
0
2
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ошибка 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: https://spacy.io/usage/linguistic-features#native-tokenizers

Спасибо большое за твою помощь. Не думал об этом. Это решило мою проблему.

SHIVAM SINGH 20.11.2022 08:37

Другие вопросы по теме