为 spacy pipeline 创建组件
Create components for spacy pipeline
我目前正在使用 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
看起来您正在用 spaCy 编写一个简单的无状态组件。无状态组件可以定义为接受 Doc 和 returns 相同 Doc 的函数。您的代码有几个问题。
首先,关于管道的工作原理。您可以将 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])
但这也行不通 - 您正在 return 字符串,但您需要 return 文档。
您似乎正在尝试将 Doc 中的每个标记更改为其词元。但是您不能更改 Doc 的文本,这是 spaCy 中的设计决定,因此不会起作用。
你应该看看 docs on custom components。
如果我对您尝试做的事情的理解是正确的,那么这作为管道组件似乎没有意义,可以只是 post-processing。
我目前正在使用 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
看起来您正在用 spaCy 编写一个简单的无状态组件。无状态组件可以定义为接受 Doc 和 returns 相同 Doc 的函数。您的代码有几个问题。
首先,关于管道的工作原理。您可以将 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])
但这也行不通 - 您正在 return 字符串,但您需要 return 文档。
您似乎正在尝试将 Doc 中的每个标记更改为其词元。但是您不能更改 Doc 的文本,这是 spaCy 中的设计决定,因此不会起作用。
你应该看看 docs on custom components。
如果我对您尝试做的事情的理解是正确的,那么这作为管道组件似乎没有意义,可以只是 post-processing。