目录
基于 SpaCy DependencyMatcher 编写复杂依存关系规则实战指南
1️⃣ 引言
2️⃣ DependencyMatcher 基本原理
3️⃣ 快速入门:安装和导入
4️⃣ DependencyMatcher 工作流程
5️⃣ 详细讲解 pattern 结构
6️⃣ 示例结果
7️⃣ 复杂用法示例
7.1 匹配 “主语 + 动作 + 地点状语” 结构
7.2 动态调整 pattern
8️⃣ 实战场景建议
8.1 产品级 QA 系统增强
8.2 法律条款关系抽取
8.3 知识图谱构建
9️⃣ 小结
为什么用 DependencyMatcher?
使用建议
10️⃣ 参考资料
11️⃣ 下一步进阶?
在前一篇《基于 SpaCy 框架的依存句法分析实战指南》中,我们讲解了如何用 SpaCy 做基本的依存句法分析,并基于 token.dep_
和 token.children
自定义简单规则。
但是,随着业务复杂度提高(如:
RAG 系统中的实体关系提取
问答系统中针对特定结构的问题理解
法律/医疗/电商领域的专业信息抽取
单纯靠 for 循环遍历 token 就显得吃力。
这时,SpaCy 的 DependencyMatcher
提供了强大而高效的工具,能用“模式匹配”方式定义复杂依存关系规则,简洁易维护,性能更优。
DependencyMatcher 是一个基于依存关系树的匹配工具,核心思想:
定义一组 pattern(依存关系匹配模式)
matcher 遍历依存树,自动匹配出符合 pattern 的结构
可以提取出你想要的 token 或 token 组合
优势:
✅ 不必手写遍历逻辑
✅ 可以跨越 token 层级灵活匹配
✅ 规则可复用、组合
✅ 适合产品级规则增强、RAG QA、结构化信息提取
pip install spacy
pip install https://github.com/jiangxiluning/spacy-zh-model/releases/download/v0.3.0/zh_core_web_sm-3.5.0-py3-none-any.whl
import spacy
from spacy.matcher import DependencyMatcher
# 加载模型
nlp = spacy.load("zh_core_web_sm")
1️⃣ 初始化 DependencyMatcher:
matcher = DependencyMatcher(nlp.vocab)
2️⃣ 定义 pattern:
pattern = [
{
"RIGHT_ID": "verb", # 目标谓语
"RIGHT_ATTRS": {"POS": "VERB"}
},
{
"LEFT_ID": "verb",
"REL_OP": ">", # verb 的直接子节点
"RIGHT_ID": "subj",
"RIGHT_ATTRS": {"DEP": "nsubj"} # 主语
},
{
"LEFT_ID": "verb",
"REL_OP": ">", # verb 的直接子节点
"RIGHT_ID": "obj",
"RIGHT_ATTRS": {"DEP": {"IN": ["obj", "obl"]}} # 宾语或介宾
}
]
3️⃣ 添加到 matcher 中:
matcher.add("SVO_PATTERN", [pattern])
4️⃣ 匹配:
text = "百度在北京发布了新一代人工智能模型。"
doc = nlp(text)
matches = matcher(doc)
# 展示匹配结果
for match_id, token_ids in matches:
print(f"匹配模式: {nlp.vocab.strings[match_id]}")
for token_id in token_ids:
token = doc[token_id]
print(f"→ {token.text} ({token.dep_}, {token.pos_})")
关键字段 | 说明 |
---|---|
RIGHT_ID |
当前 pattern 单元的 ID(字符串,任意起名) |
RIGHT_ATTRS |
这个 token 要满足的属性条件(支持 POS, DEP, TEXT, LEMMA 等) |
LEFT_ID |
依赖关系中 LEFT 节点是谁(引用之前定义过的 RIGHT_ID ) |
REL_OP |
定义依存关系方向 <, >, <<, >>(通常用 > 匹配子节点) |
> :LEFT 节点 → 直接子节点是 RIGHT 节点
< :RIGHT 节点 → 直接子节点是 LEFT 节点
匹配模式: SVO_PATTERN
→ 发布 (ROOT, VERB)
→ 百度 (nsubj, PROPN)
→ 模型 (obj, NOUN)
pattern = [
{"RIGHT_ID": "verb", "RIGHT_ATTRS": {"POS": "VERB"}},
{"LEFT_ID": "verb", "REL_OP": ">", "RIGHT_ID": "subj", "RIGHT_ATTRS": {"DEP": "nsubj"}},
{"LEFT_ID": "verb", "REL_OP": ">", "RIGHT_ID": "obl_place", "RIGHT_ATTRS": {"DEP": "obl", "ENT_TYPE": "LOC"}} # 地点
]
matcher = DependencyMatcher(nlp.vocab)
matcher.add("ACTION_AT_PLACE", [pattern])
text = "小明在图书馆认真地读书。"
doc = nlp(text)
matches = matcher(doc)
for match_id, token_ids in matches:
print(f"匹配模式: {nlp.vocab.strings[match_id]}")
for token_id in token_ids:
token = doc[token_id]
print(f"→ {token.text} ({token.dep_}, {token.pos_})")
想加修饰语?加 advmod
节点
想匹配主动/被动?灵活设置 DEP 属性
想匹配动词短语?可用 LEMMA
统一不同词形
例子:
用户问:“小明什么时候读书?”
用 DependencyMatcher 快速抽取 (主语,动作,时间/地点)
,映射到知识库。
“XX 公司应在 30 日内支付欠款。”
匹配 pattern 提取 (行为主体,公司)
→ (行为,支付)
→ (时间限制,30 日内)
大规模新闻流 → 匹配 “主谓宾” → 自动生成 RDF 三元组。
✅ 编写规则更清晰、层次分明
✅ 易于复用维护
✅ 性能高(Cython 实现,快于 for-loop 手写)
✅ 非常适合结构明确的语言模式场景
小规模业务规则 → 直接用 DependencyMatcher 足够
大规模复杂场景 → 可以结合 SpaCy Matcher / DependencyMatcher + 机器学习 model 提供 fallback
配合可视化工具(displacy
)调试 pattern 效果最佳!
SpaCy DependencyMatcher 文档
SpaCy Matcher vs DependencyMatcher 对比
实战经验分享