spaCy + Stanza(前身为StanfordNLP)
该包封装了Stanza(前身为StanfordNLP)库,因此你可以在spaCy管道中使用Stanford的模型。Stanford模型在CoNLL 2017和2018共享任务中取得了顶级精度,该任务涉及68种语言的分词、词性标注、形态分析、词形还原和标注依存分析。从v1.0开始,Stanza还支持选定语言的命名实体识别。
⚠️ 以前版本的此包名为
spacy-stanfordnlp
。
使用这个封装,你将能使用由预训练的stanza
模型计算的以下注释:
- 统计分词(反映在
Doc
及其tokens中) - 词形还原(
token.lemma
和token.lemma_
) - 词性标注(
token.tag
,token.tag_
,token.pos
,token.pos_
) - 形态分析(
token.morph
) - 依存分析(
token.dep
,token.dep_
,token.head
) - 命名实体识别(
doc.ents
,token.ent_type
,token.ent_type_
,token.ent_iob
,token.ent_iob_
) - 句子分段(
doc.sents
)
️️️⌛️ 安装
从v1.0.0开始,spacy-stanza
仅与spaCy v3.x兼容。安装最新版本:
pip install spacy-stanza
对于spaCy v2,安装v0.2.x并参考 v0.2.x使用文档:
pip install "spacy-stanza<0.3.0"
请确保还 下载其中一个 预训练的Stanza模型。
📖 使用及示例
⚠️ 重要提示: 该包已重构以利用 spaCy v3.0。以前为 spaCy v2.x构建的版本工作方式有很大不同。请参阅以前版本的README以了解文档。
使用spacy_stanza.load_pipeline()
创建一个nlp
对象,你可以用它处理含Stanza管道的文本并创建spaCy
Doc
对象。默认情况下,spaCy管道和Stanza管道将使用相同的lang
初始化,例如“en”:
import stanza
import spacy_stanza
# 如有必要,下载stanza模型
stanza.download("en")
# 初始化管道
nlp = spacy_stanza.load_pipeline("en")
doc = nlp("Barack Obama was born in Hawaii. He was elected president in 2008.")
for token in doc:
print(token.text, token.lemma_, token.pos_, token.dep_, token.ent_type_)
print(doc.ents)
如果spaCy中提供了给定语言的数据,相关语言类可以用作nlp
对象的基础,比如English()
。这样你就可以使用spaCy的词汇属性,比如is_stop
或like_num
。该nlp
对象遵循与其他spaCyLanguage
类相同的API,因此你可以使用displaCy可视化Doc
对象,向管道添加自定义组件,使用基于规则的匹配器,并执行通常在spaCy中执行的所有操作。
# 访问spaCy的词汇属性
print([token.is_stop for token in doc])
print([token.like_num for token in doc])
# 可视化依存关系
from spacy import displacy
displacy.serve(doc) # 如果在Jupyter notebook中使用displacy.render
# 用nlp.pipe处理文本
for doc in nlp.pipe(["大量文本", "更多文本", "..."]):
print(doc.text)
# 结合你自己的自定义管道组件
from spacy import Language
@Language.component("custom_component")
def custom_component(doc):
# 在此对doc做点什么
print(f"调用了自定义组件: {doc.text}")
return doc
nlp.add_pipe("custom_component")
doc = nlp("一些文本")
# 将属性序列化为numpy数组
np_array = doc.to_array(['ORTH', 'LEMMA', 'POS'])
Stanza管道选项
可以按照Pipeline
API提供的参数以关键字形式提供Stanza
Pipeline
的其他选项:
-
提供Stanza语言作为
lang
。对于不支持spaCy的Stanza语言,请使用“xx”作为spaCy语言设置:# 为科普特语初始化一个管道 nlp = spacy_stanza.load_pipeline("xx", lang="cop")
-
遵循
Pipeline
API提供Stanza管道设置:# 使用`hdt`包初始化德语管道 nlp = spacy_stanza.load_pipeline("de", package="hdt")
-
使用spaCy进行分词而非统计分词(仅限英语):
nlp = spacy_stanza.load_pipeline("en", processors= {"tokenize": "spacy"})
-
按照其他关键字参数提供的额外处理器设置:
# 提供预先分词文本(空格分词) nlp = spacy_stanza.load_pipeline("de", tokenize_pretokenized=True)
spaCy配置在[nlp.tokenizer]
块中指定所有Pipeline
选项。例如,以上例子中预分词文本的德语管道配置:
[nlp.tokenizer]
@tokenizers = "spacy_stanza.PipelineAsTokenizer.v1"
lang = "de"
dir = null
package = "default"
logging_level = null
verbose = null
use_gpu = true
[nlp.tokenizer.kwargs]
tokenize_pretokenized = true
[nlp.tokenizer.processors]
序列化
完整的Stanza管道配置保存在spaCy管道
config
中,因此你可以像其他nlp
管道一样保存和加载该管道:
# 保存到本地目录
nlp.to_disk("./stanza-spacy-model")
# 重新加载该管道
nlp = spacy.load("./stanza-spacy-model")
注意,这默认不保存任何Stanza模型数据。Stanza模型非常大,因此目前的包期望你通过stanza.download()
单独下载这些模型,并使它们在默认模型目录中或配置中的[nlp.tokenizer.dir]
路径下可用。
添加额外的spaCy管道组件
默认情况下,由spacy_stanza.load_pipeline()
返回的nlp
对象中的spaCy管道将为空,因为所有stanza
属性都在自定义分词器StanzaTokenizer
中计算并设置。但是由于它是一个常规的nlp
对象,你可以向管道中添加自己的组件。例如,你可以添加
你自己的自定义文本分类组件
通过nlp.add_pipe("textcat", source=source_nlp)
,或使用EntityRuler
组件
通过自己的基于规则的模式增强命名实体。