#spacy
#spacy
Вопрос:
Есть ли способ преобразовать файл CONLL в список Doc
объектов без необходимости разбора предложения с использованием nlp
объекта. У меня есть список аннотаций, которые я должен передать автоматическому компоненту, использующему Doc
объекты в качестве входных данных. Я нашел способ создать документ:
doc = Doc(nlp.vocab, words=[...])
И что я могу использовать from_array
функцию для воссоздания других лингвистических функций. Этот массив можно воссоздать, используя значение индекса из StringStore
object , я успешно создал объект Doc с информацией о ЛЕММЕ и ТЕГЕ, но не могу воссоздать данные HEAD. Мой вопрос заключается в том, как передать данные заголовка в объект Doc, используя метод from_array.
Запутанная вещь в заголовке заключается в том, что для предложения с такой структурой:
Ona 2
je 2
otišla 2
u 4
školu 2
. 2
Вывод этого фрагмента кода:
from spacy.attrs import TAG, HEAD, DEP
doc.to_array([TAG, HEAD, DEP])
является:
array([[10468770234730083819, 2, 429],
[ 5333907774816518795, 1, 405],
[11670076340363994323, 0, 8206900633647566924],
[ 6471273018469892813, 1, 8110129090154140942],
[ 7055653905424136462, 18446744073709551614, 435],
[ 7173976090571422945, 18446744073709551613, 445]],
dtype=uint64)
Я не могу сопоставить центральный столбец вывода from_array с приведенной выше структурой дерева зависимостей.
Заранее спасибо за помощь,
Даниэль
Ответ №1:
Хорошо, итак, я, наконец, взломал его, кажется, что head — index, если индекс меньше head и 18446744073709551616 — index в противном случае. Это функция, которую я использовал, если кому-то еще это было нужно:
import numpy as np
from spacy.tokens import Doc
docs = []
for sent in sents:
generated_doc = Doc(doc.vocab, words=[word["word"] for word in sent])
heads = []
for idx, word in enumerate(sent):
if word["pos"] not in doc.vocab.strings:
doc.vocab.strings.add(word["pos"])
if word["dep"] not in doc.vocab.strings:
doc.vocab.strings.add(word["dep"])
if word["head"] >= idx:
heads.append(word["head"] - idx)
else:
heads.append(18446744073709551616-idx)
np_array = np.array([np.array([doc.vocab.strings[word["pos"]], heads[idx], doc.vocab.strings[word["dep"]]], dtype=np.uint64) for idx, word in enumerate(sent)], dtype=np.uint64)
generated_doc.from_array([TAG, HEAD, DEP], np_array)
docs.append(generated_doc)
Комментарии:
1. Заголовки в
doc.to_array()
являются относительными, а не абсолютными заголовками, а затем они преобразуются вuint64
, поэтому отрицательные заголовки (голова влево, а не вправо) в конечном итоге выглядят вот так.2. @aab спасибо за ответ, да, именно так 🙂 , хотя я не нашел никакой документации по этому вопросу.
3. Нет, это скорее внутренний метод. Типичный способ — создать
Doc
файл сwords
помощью andspaces
(вы можете использоватьget_words_and_spaces
fromspacy.util
, если у вас естьwords
andtext
), а затем задать свойстваDoc
непосредственно как вdoc[3].head = doc[2]
ordoc[10].tag_ = "ABC"
.4. В предстоящей версии spacy v3 будет больше методов преобразования, которые преобразуют в
Doc
. Здесь представлен предварительный просмотр полноценного конвертера CoNLL-U с некоторой дополнительной обработкой NER в столбце MISC и объединением многословных токенов: github.com/explosion/spaCy/blob /…5. Уважаемый @aab, не знал, что я могу добавлять свойства напрямую, у меня было некоторое представление о том, что документы несколько неизменяемы. Большое спасибо за советы 🙂