spaCy 中文分词如何选择 char、jieba 与 pkuseg 分词器?
【免费下载链接】spaCy💫 Industrial-strength Natural Language Processing (NLP) in Python项目地址: https://gitcode.com/GitHub_Trending/sp/spaCy
在 spaCy 中处理中文文本时,Chinese语言类(或spacy.blank("zh"))的默认分词器是字符级切分,而不是按词切分。如果你的任务需要真正的“词”粒度分词,就需要在char、jieba、pkuseg三种segmenter选项中做出选择并正确配置。本文基于 spaCy 文档中的 Chinese language support 章节和 spacy/lang/zh/__init__.py 源码,给出每个分词器的适用条件、配置写法、依赖安装和验证方法,帮助你在中文 NLP 项目中确定并验证分词方案。
三种分词器各自的行为与默认值
spaCy 的中文语言类支持三种 word segmentation 选项(见 usage/models 文档):
| Segmenter | 说明 |
|---|---|
char | 字符切分:默认选项。新建Chinese语言类或调用spacy.blank("zh")时启用的就是它,把文本切成单个字符。 |
jieba | Jieba:将 tokenizer 选项segmenter设为"jieba",使用 Jieba 做词级分词,需要额外安装 jieba 包。 |
pkuseg | PKUSeg:自 spaCy v2.3.0 起支持,把segmenter设为"pkuseg"。文档说明它被引入是为了更好地支持 Chinese OntoNotes 以及 spaCy 提供的中文 pipeline。 |
一个重要的版本行为变化:自 v3.0 起,默认分词器从 Jieba 改成了字符切分。也就是说,v3 中新建的中文 pipeline 不再自动用 jieba 分词。
另外,由于pkuseg分词器依赖一个需要从文件加载的模型,文档要求模型在 initialization 阶段(通常是训练前)加载,这样打包后的中文模型在运行时不会依赖某个本地路径。
按依赖需求和使用目标选择
三种选项的选择依据都来自文档中说明的行为差异:
- 不想引入额外依赖、或只做字符级处理:用
char。它是默认值,创建Chinese()即可用,无需安装任何第三方分词库。 - 需要词级分词且希望零模型配置:用
jieba。只需pip install jieba,配置里把segmenter设为"jieba"即可,不需要再调用initialize加载模型。 - 需要与 spaCy 提供的中文 pipeline 对齐、或需要用户词典干预:用
pkuseg。spaCy 官方中文 pipeline 内置的是基于 Chinese OntoNotes 5.0 训练的自定义pkuseg模型;同时pkuseg提供运行期修改用户词典的 API(pkuseg_update_user_dict),这是char和jieba不具备的能力。注意pkuseg要求安装spacy-pkuseg包,并必须在initialize时指定模型。
配置与验证各分词器
以下示例均使用文档给出的写法。验证方式为对一段文本调用nlp(text)后检查[token.text for token in doc]的结果。
char:默认配置即可
from spacy.lang.zh import Chinese # 字符切分(默认) nlp = Chinese() doc = nlp("作为语言而言") print([token.text for token in doc])仓库测试文件 spacy/tests/lang/zh/test_tokenizer.py 对char的断言是tokens == list(text),即每个 token 恰好是原文的一个字符。你运行上面代码后应看到与逐字符一致的结果(文档示例外的输出取决于你输入的具体文本)。
对应的完整 tokenizer 配置(来自文档):
[nlp.tokenizer] @tokenizers = "spacy.zh.ChineseTokenizer" segmenter = "char"jieba:先安装 jieba,再配置 segmenter
jieba分词器在创建 tokenizer 时导入 jieba 包;未安装会抛出ImportError,提示信息为安装pip install jieba。
pip install jiebafrom spacy.lang.zh import Chinese cfg = {"segmenter": "jieba"} nlp = Chinese.from_config({"nlp": {"tokenizer": cfg}}) doc = nlp("作为语言而言") print([token.text for token in doc])仓库测试文件中记录了 jieba 分词器对示例句“作为语言而言,为世界使用人数最多的语言,目前世界有五分之一人口做为母语。”的期望分词结果(以下为其中的分词片段,来自 test_tokenizer.py,属于仓库测试的期望值,实际输出以你安装的 jieba 版本为准):['作为', '语言', '而言', ',', '为', '世界', '使用', '人', '数最多', ...]。
pkuseg:安装 spacy-pkuseg,配置后必须调用 initialize
pkuseg路径比前两者多两步:安装spacy-pkuseg包,并在创建 pipeline 后调用nlp.tokenizer.initialize(...)指定模型。源码中的安装提示为:
pip install "spacy-pkuseg>=0.0.27,<0.1.0" # 或 conda install -c conda-forge "spacy-pkuseg>=0.0.27,<0.1.0"基本用法(来自文档):
from spacy.lang.zh import Chinese # 使用 pkuseg 提供的 "mixed" 模型 cfg = {"segmenter": "pkuseg"} nlp = Chinese.from_config({"nlp": {"tokenizer": cfg}}) nlp.tokenizer.initialize(pkuseg_model="mixed") doc = nlp("作为语言而言") print([token.text for token in doc])pkuseg_model接受两类值(文档 API 表):spacy-pkuseg提供的模型名,或本地模型目录路径。文档示例列出的几种加载方式:
# 加载 spaCy 的 OntoNotes 模型 nlp.tokenizer.initialize(pkuseg_model="spacy_ontonotes") # 加载 pkuseg 的 "news" 模型 nlp.tokenizer.initialize(pkuseg_model="news") # 加载本地模型 nlp.tokenizer.initialize(pkuseg_model="/path/to/pkuseg_model") # 覆盖用户词典(pkuseg_user_dict 为“每行一个词”的文件路径) nlp.tokenizer.initialize(pkuseg_model="spacy_ontonotes", pkuseg_user_dict="/path/to/user_dict")其中/path/to/pkuseg_model与/path/to/user_dict需要你替换为自己的本地模型目录与用户词典文件路径;pkuseg_user_dict默认为"default"(spacy-pkuseg自带的默认词典)。
pkuseg支持的领域模型(文档说明,用于研究场景):"mixed"(等价于pkuseg包的"default")、"news"、"web"、"medicine"、"tourism"。如果你的语料属于其他领域,文档指出pkuseg提供了训练 API 来自训模型:
import spacy_pkuseg as pkuseg from spacy.lang.zh import Chinese # 训练 pkuseg 模型 pkuseg.train("train.utf8", "test.utf8", "/path/to/pkuseg_model") # 在 spaCy 中文 tokenizer 中加载 cfg = {"segmenter": "pkuseg"} nlp = Chinese.from_config({"nlp": {"tokenizer": cfg}}) nlp.tokenizer.initialize(pkuseg_model="/path/to/pkuseg_model")仓库测试文件中同样记录了pkuseg(基于"spacy_ontonotes"模型)对同一示例句的期望分词片段:['作为', '语言', '而言', ',', '为', '世界', '使用', '人数', '最多', ...]——与 jieba 的结果在“人数/最多”和“做为”等处不同,这也是对比两个分词器切分粒度时可以直接观察到的差异。
在训练配置中声明 pkuseg 初始化
如果你要训练 pipeline 而不是临时用 blank 模型,文档建议在训练配置的[initialize.tokenizer]段提供 pkuseg 设置,数据会在训练前加载并随模型序列化,运行时不再需要相同的本地路径:
[initialize] [initialize.tokenizer] pkuseg_model = "/path/to/model" pkuseg_user_dict = "default"/path/to/model替换为你训练机上可访问的模型目录。
修改 pkuseg 用户词典
只有pkuseg分词器支持运行期修改用户词典(文档 API):
# 追加词到用户词典 nlp.tokenizer.pkuseg_update_user_dict(["中国", "ABC"]) # 清空用户词典并替换为新词 nlp.tokenizer.pkuseg_update_user_dict(["中国"], reset=True) # 清空用户词典 nlp.tokenizer.pkuseg_update_user_dict([], reset=True)注意:在char或jieba分词器上调用该方法只会发出警告(源码 zh/__init__.py 中对应Warnings.W104),不会生效。
常见报错与边界
- pkuseg 未初始化就处理文本:直接把
segmenter设为"pkuseg"但未调用initialize,处理文本时会抛出ValueError(错误码 E1000)。仓库测试 test_zh_uninitialized_pkuseg 验证的正是这一行为。 - 配置了不支持的 segmenter 值:例如
{"segmenter": "unk"}会在from_config时抛出ConfigValidationError(见 test_zh_unsupported_segmenter)。 - 缺少依赖:未安装 jieba 时选择
jieba、未安装spacy-pkuseg时选择pkuseg,都会抛出ImportError并提示对应的pip install命令。 - 数据授权边界:文档说明
pkuseg官方提供的模型包含仅限研究用途的数据,因此 spaCy 官方中文 pipeline 改用仅基于 Chinese OntoNotes 5.0 训练的自定义pkuseg模型。如果你的用途超出研究范围,需要留意这一点。
小结:一条可核对的操作路径
- 明确是否需要词级分词:不需要则保持默认
char(零依赖); - 需要词级分词且不想管理模型:安装
jieba,segmenter = "jieba"; - 需要用户词典、对齐官方中文 pipeline 或领域模型:安装
spacy-pkuseg>=0.0.27,<0.1.0,segmenter = "pkuseg",并务必调用nlp.tokenizer.initialize(pkuseg_model=...); - 用
[token.text for token in nlp(text)]核对切分结果,对照上文仓库测试文件中的示例分词确认粒度是否符合预期。
更完整的中文支持说明见 usage/models 文档,实现细节见 spacy/lang/zh/__init__.py。
【免费下载链接】spaCy💫 Industrial-strength Natural Language Processing (NLP) in Python项目地址: https://gitcode.com/GitHub_Trending/sp/spaCy
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考