如何向spaCy词汇表(vocab)添加词汇及属性?修改是否持久?
在spaCy中向Vocab添加词汇及语言特征的方法
一、添加词汇与语言特征的具体方法
spaCy的Vocab核心负责字符串与哈希值的映射,而词元(lemma)、词性标签(tag)这类语言特征,是通过词汇对应的Lexeme对象来管理的,以下是几种常用的设置方式:
1. 手动创建Lexeme并设置属性
直接创建目标词汇的Lexeme实例,然后为其指定各类语言特征:
import spacy nlp = spacy.load("zh_core_web_sm") # 替换为你使用的模型 # 向Vocab添加词汇并获取Lexeme对象 lex = nlp.vocab.add_word("apple") # 设置词元、词性、标签等属性 lex.set_attr("lemma_", "apple") lex.set_attr("pos_", "NOUN") lex.set_attr("tag_", "NN") lex.set_attr("is_stop", False) # 标记为非停用词
2. 批量更新已有词汇的属性
如果词汇已经存在于Vocab中,可以用set_lexeme_attrs批量设置特征:
# 定义要设置的属性字典 attrs = {"lemma_": "apple", "pos_": "NOUN", "tag_": "NN"} # 为指定词汇更新属性 nlp.vocab.set_lexeme_attrs("apple", attrs)
3. 通过自定义管道自动应用特征
如果需要在处理文本时自动为指定词汇补全特征,可以编写自定义管道组件:
from spacy.language import Language @Language.component("custom_lex_attrs") def custom_lex_attrs(doc): for token in doc: if token.text == "apple": token.lemma_ = "apple" token.pos_ = "NOUN" token.tag_ = "NN" return doc # 将管道添加到nlp流程中,放在分词器之后 nlp.add_pipe("custom_lex_attrs", after="tagger")
二、修改的生效范围
- 临时生效:直接通过
add_word或set_lexeme_attrs修改的Vocab,仅在当前Python进程的nlp实例中有效。重启进程、重新加载模型后,这些修改会全部丢失。 - 永久生效:如果需要让修改在每次调用spaCy时都生效,有两种可行方案:
- 保存自定义Vocab到磁盘,下次加载模型时导入:
# 保存Vocab nlp.vocab.to_disk("./custom_vocab") # 后续加载时导入 nlp = spacy.load("zh_core_web_sm") nlp.vocab.from_disk("./custom_vocab") - 训练自定义模型:将需要添加的词汇和特征加入训练数据集,重新训练模型。加载自定义模型时,这些词汇和特征会被自动加载。
- 保存自定义Vocab到磁盘,下次加载模型时导入:
三、关于Vocab存在性检查的误区修正
你之前使用word in list(nlp.vocab.strings)的方式效率极低,正确的检查方式如下:
- 检查词汇是否在字符串映射中:直接用
word in nlp.vocab.strings(无需转成列表,nlp.vocab.strings本身是可迭代的集合) - 检查词汇是否有对应的Lexeme:
nlp.vocab.has_word(word) - 你提到
word in nlp.vocab返回False,是因为nlp.vocab的__contains__方法检查的是哈希值而非字符串,正确用法是先将字符串转为哈希值:word_hash = nlp.vocab.strings[word] print(word_hash in nlp.vocab) has_vector和get_vector返回False,是因为该词汇没有对应的预训练词向量,和词汇是否存在于Vocab无关——即使词汇在Vocab中,未加载对应词向量时也会返回False。
内容的提问来源于stack exchange,提问作者Uwe.Schneider
相关产品推荐
相关产品推荐

