Создание компонентов для пространственного конвейера

В настоящее время я работаю со Spacy и изучаю, как я могу использовать конвейеры для более эффективной работы. Я пытаюсь создать свои собственные компоненты для добавления в конвейер, но каждый раз сталкиваюсь с некоторыми проблемами. Пример :

import spacy
nlp = spacy.blank("fr")

def lemmatizer(doc) :
    return " ".join([elt.lemma_ for elt in nlp(doc.text)])

nlp.add_pipe(lemmatizer) # add the lemmatizer to the pipeline

nlp("Hi, I'm new here.")

Я получаю следующую ошибку:

    ---------------------------------------------------------------------------
RecursionError                            Traceback (most recent call last)
 in 
----> 1 nlp("Hi, I'm new here.")

/var/opt/data/dataiku/datadir/code-envs/python/recla_text_sci/lib64/python3.6/site-packages/spacy/language.py in __call__(self, text, disable, component_cfg)
    443             if not hasattr(proc, "__call__"):
    444                 raise ValueError(Errors.E003.format(component=type(proc), name=name))
--> 445             doc = proc(doc, **component_cfg.get(name, {}))
    446             if doc is None:
    447                 raise ValueError(Errors.E005.format(name=name))

 in lemmatizer(doc)
      1 def lemmatizer(doc) :
----> 2     return " ".join([elt.lemma_ for elt in nlp(doc.text)])

... last 2 frames repeated, from the frame below ...

/var/opt/data/dataiku/datadir/code-envs/python/recla_text_sci/lib64/python3.6/site-packages/spacy/language.py in __call__(self, text, disable, component_cfg)
    443             if not hasattr(proc, "__call__"):
    444                 raise ValueError(Errors.E003.format(component=type(proc), name=name))
--> 445             doc = proc(doc, **component_cfg.get(name, {}))
    446             if doc is None:
    447                 raise ValueError(Errors.E005.format(name=name))

RecursionError: maximum recursion depth exceeded
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
22
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

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

Во-первых, о том, как работают пайплайны. Вы можете представить конвейер spaCy (вызов nlp()) следующим образом:

def do_nlp(text):
    doc = tokenizer(text) # the tokenizer is special and comes before the pipeline
    for pipe in pipes:
        doc = pipe(doc)

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

Итак, с вашим кодом причина ошибки, которую вы получаете, заключается в том, что внутри цикла выше вы снова вызываете nlp(). Который снова вызывает nlp(). И так далее. Вы не можете вызывать nlp() внутри компонента, да и не нужно.

Если бы это была единственная проблема, вы могли бы сделать это:

return " ".join([elt.lemma_ for elt in doc])

Но это тоже не сработает — вы возвращаете строку, а вам нужно вернуть Doc.

Похоже, вы пытаетесь изменить каждый токен в документе на его лемму. Но вы не можете изменить текст документа, это дизайнерское решение в spaCy, так что это не сработает.

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

Если мое понимание того, что вы пытаетесь сделать, верно, это не имеет смысла как компонент конвейера и может быть просто постобработкой.

Прочитав ссылку, которую вы предоставили, я понял, что шел по этому пути неправильно. Спасибо за помощь

Saad Cherkaoui Ikbal 10.05.2022 10:17

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