Преобразование областей на уровне символов в области на уровне токенов

#python #huggingface-transformers

Вопрос:

В настоящее время я пытаюсь преобразовать промежутки уровня символов в промежутки уровня токенов и задаюсь вопросом, есть ли в библиотеке функциональность, которой я, возможно, не воспользуюсь.

Данные, которые я в настоящее время использую, состоят из «правильного» текста (я говорю «правильного», поскольку он написан так, как будто это обычный документ, а не с такими вещами, как дополнительные пробелы для более простых операций разделения) и аннотированных объектов. Сущности аннотированы на уровне символов, но я хотел бы получить маркированный диапазон на уровне подслова.

Мой план состоял в том, чтобы сначала преобразовать области на уровне символов в области на уровне слов, а затем преобразовать их в области на уровне подсловов. Фрагмент кода, который я написал, выглядит так:

 new_text = []
for word in original_text.split():
    if (len(word) > 1) and (word[-1] in ['.', ',', ';', ':']):
        new_text.append(word[:-1]   ' '   word[-1])
    else:
        new_text.append(word)

new_text = ' '.join(new_text).split()

word2char_span = {}
start_idx = 0
for idx, word in enumerate(new_text):
    char_start = start_idx
    char_end = char_start   len(word)
    word2char_span[idx] = (char_start, char_end)
    start_idx  = len(word)   1
 

Это, кажется, работает хорошо, но один крайний случай, о котором я не подумал, — это скобки. Чтобы привести более конкретный пример, пара абзац-сущность выглядит следующим образом:

 >>> original_text = "RDH12, a retinol dehydrogenase causing Leber's congenital amaurosis, is also involved in 
steroid metabolism. Three retinol dehydrogenases (RDHs) were tested for steroid converting abilities: human and 
murine RDH 12 and human RDH13. RDH12 is involved in retinal degeneration in Leber's congenital amaurosis (LCA). 
We show that murine Rdh12 and human RDH13 do not reveal activity towards the checked steroids, but that human type 
12 RDH reduces dihydrotestosterone to androstanediol, and is thus also involved in steroid metabolism. Furthermore, 
we analyzed both expression and subcellular localization of these enzymes."
>>> entity_span = [139, 143]
>>> print(original_text[139:143])
'RDHs'
 

Этот пример фактически возвращает a KeyError , когда я пытаюсь ссылаться (139, 143) , потому что код настройки, который я написал, принимает (RDHs) в качестве сущности, а не RDHs . Я также не хочу жестко кодировать обработку скобок, потому что есть некоторые объекты, в которые включены скобки.

Я чувствую, что должен быть более простой подход к этому вопросу, и я немного переосмысливаю ситуацию. Любая обратная связь о том, как я мог бы достичь того, чего хочу, будет оценена по достоинству.

Комментарии:

1. Я не понимаю: вы хотите разделить его на список слов, а затем использовать индексирование

Ответ №1:

Токенизация — сложная штука. Я бы предложил использовать SpaCy для обработки ваших данных, поскольку вы можете получить доступ к смещению каждого маркера в исходном тексте на уровне символов, что должно упростить сопоставление ваших символов с маркерами:

 import spacy

nlp = spacy.load("en_core_web_sm")
original_text = "Three retinol dehydrogenases (RDHs) were tested for steroid converting abilities:"

# Process data
doc = nlp(original_text)

for token in doc:
    print(token.idx, token, sep="t")

 

Выход:

 0   Three
6   retinol
14  dehydrogenases
29  (
30  RDHs
34  )
36  were
41  tested
48  for
52  steroid
60  converting
71  abilities
80  :