#python #spacy
#python #spacy
Вопрос:
Моя цель — распределить документы, которые уже были помечены и сопоставлены с аннотациями gold.
У меня есть набор данных аннотированных документов в классическом формате spacy
{
"text": "This is a sentence, this is another sentence...",
"entities": [(100, 112, "PERSON"), (150, 154, "LOCATION"),...]
}
и я преобразовал его в набор данных с тегами BILUO, где приведенный выше образец будет выглядеть следующим образом
{
"text": "This is a sentence, this is another sentence...",
"spacy_tokens": ["This", "is", "a", "sentence", ",", "this",...],
"ner_tags": ["O", "O", ..., "B-PERSON", "I-PERSON", "L-PERSON",...]
}
используя следующий код
nlp = spacy.load('de_core_news_sm')
for i, (doc, gold) in enumerate(zip(docs, golds)):
doc = nlp.make_doc(doc)
gold = GoldParse(doc, **gold)
sample = {
"text": str(doc),
"tokens": [w for w in doc],
"ner_tags": [tag for tag in gold.ner]
}
Вопрос
Мой вопрос в том, как я могу теперь (ретроспективно) разделить образцы дальше по предложениям. Т.е. Когда я добавляю a sentencizer
в конвейер spacy, я могу разделить doc
, но как мне синхронизировать gold.sent_starts
с разделением предложений?
Ответ №1:
Предполагая, что вы spacy_tokens
синхронизированы с вашим ner_tags
*, тогда вам нужно создать документ с точно такой токенизацией и запустить его через sentencizer, чтобы получить token.is_sent_start
значения:
import spacy
from spacy.tokens import Doc
nlp = spacy.blank("en")
nlp.add_pipe(nlp.create_pipe("sentencizer"))
text = "He doesn't like London and Berlin. I do."
words = ["He", "doesn't", "like", "London", "and", "Berlin", ".", "I", "do", "."]
ner = ["O", "O", "O", "U-LOC", "O", "U-LOC", "O", "O", "O", "O"]
words, spaces = spacy.util.get_words_and_spaces(words, text)
doc = Doc(nlp.vocab, words=words, spaces=spaces)
doc = nlp.get_pipe("sentencizer")(doc)
sent_starts = [t.is_sent_start for t in doc]
Если вы не создадите документ, предоставив токенизацию gold с Doc(words=)
помощью, English
токенизация по умолчанию для nlp(text)
будет ['He', 'does', "n't", 'like', 'London', 'and', 'Berlin', '.', 'I', 'do', '.']
, и все sent_start
(или другие) теги будут не синхронизированы.
* Приведенный выше код подходит только text
для смещения символов entities
, но если ваш gold
включает words
, то gold.ner
выравнивается с gold.words
, но не обязательно с [t.text for t in doc]
.