想象你把一盒乐高倒在地上:有 12 块红色方砖、8 块蓝色长条、几扇窗户和一个小人。如果只看清单,你只知道有哪些零件,却不知道下一步该把它们拼成什么。对机器来说,读一个句子也是这个道理。分词能告诉它句子里有“我”“爱”“自然语言处理”这些词,但“谁爱谁”“爱什么”这种拼接关系,只有句法分析能讲清楚。 句法分析(Parsing)要做的事,就是让机器像对照乐高说明书一样,把线性的一串词重组成一棵有层次的“语法树”。站在城堡旁,你可以用两种视角观察:一种看“承重关系”——哪块积木托着哪块,这叫依存句法;另一种看“模块嵌套”——城堡先分成塔楼、城墙,再层层拆成小零件,这叫成分句法。现代的 spaCy、stanza 等工具,就像随身携带的扫描仪,把这座积木城堡变成可操作的结构图纸;评测时,再把图纸和官方说明书比对,用 UAS、LAS 量出准确率。 学完这篇,你会发现句法分析并不是理论研究,而是很多真实 NLP 工程的第一步:从客服机器人抽取订单意图,到知识图谱抽取“谁发布了什么”,都和这张结构图有关。

岗位关联

句法分析是文本从“词序列”走向“结构化语义”的第一步,掌握它,你就能为问答、抽取、翻译等下游任务搭好稳定骨架。对 NLP 从业者而言,这是文本预处理阶段最能拉开差距的硬技能。

目录
  1. 可视化演示
  2. 句法分析概述
  3. 依存句法
  4. 成分句法
  5. 主流工具
  6. 评测方法
  7. 应用与选型
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示依存句法的词间弧线关系、成分句法的层次语法树结构,及两种解析方式的并排对比。

本节配有交互动效(进入视口后自动加载,约 3KB)。

依存句法分析 弧线从核心词指向依存词 根节点sat是句子中心谓词 head \u2192 dependent 扁平结构揭示词间修饰关系

句法分析概述

拿到一堆积木时,你首先会做什么?大概率是先看说明书:城堡分几层,哪里是门,哪里是塔楼。句法分析之于机器,就像是给“句子城堡”找到说明书。它把一维的词序列转成有父子关系的树状结构,让“爱”不再只是第三个词,而是整句话的主心骨。

所谓语法树,就是句法分析的核心产物。树的根通常是整句核心(例如谓词),边则表示词或短语之间如何组合。以“我 爱 NLP”为例,“爱”是根节点,指向“我”和“NLP”,一个表示施动者,一个表示受动者。树不是凭空生成的,在它之前机器通常还要做两件事:分词和词性标注。分词把句子切成积木块,词性标注给每块积木贴上“名词”“动词”的标签,句法分析再把贴好标签的积木按规则拼接起来。

这一节最重要的理解是:句法分析的输入是词序列,输出是结构树。结构树把线性顺序变成了层级关系,方便后续程序直接问“这句话的主语是谁”“宾语是什么”。可以说,它是文本从“一串字”变成“可计算的命题”的枢纽。

当然,说明书不止一种。有人喜欢看承重关系,有人喜欢看模块划分,于是就有了后面两节:依存句法和成分句法。两种视角并不矛盾,就像同一座城堡,既可以用受力图描述,也可以用装配图描述。

依存句法

先看第一种说明书:承重图。城堡里,每一块不是承重墙的砖都会被某块“上级”砖托住,而最上面那根主梁承受全屋重量。依存句法把这种关系搬到句子上:每个词都有一个支配词(head),除根节点外,每个词都从属于另一个词。

在“我爱 NLP”中,“爱”是根节点(root);“我”以 nsubj(主语)关系挂在“爱”下面;“NLP”以 dobj(宾语)关系挂在“爱”下面。这样一条条带箭头的依存弧,就组成了一棵依存树。相比成分句法,依存句法更强调“谁依赖谁”,而不太关心“哪些词组成一个短语”,所以它非常擅长回答“谁对谁做了什么”。

现代依存句法模型通常用打分的方式找最优树:对句子中每一个可能的父子词对,模型都算出一个置信度,然后选择总体得分最高的那棵结构树。用公式可以写成:

把公式翻译回乐高语言:你要在所有“拼接方案”里,找一种最能用已有积木搭建、最符合常规结构受力逻辑的方案。依存树就是这份受力图。

T^=arg⁡max⁡T∏(h,m)∈Tp(rh,m∣S)\hat{T}=\arg\max_{T}\prod_{(h,m)\in T} p(r_{h,m}\mid S)
这个公式想表达:句法分析不是拍脑袋,而是把所有候选结构放在一起打分,选总分最高者。
  1. 句子 S 与候选树 TS 是待分析的词序列,T 是某棵候选依存树,可以看作一组依存边的集合。
    S={w1,w2,…,wn},T={(h,m)}S=\{w_1,w_2,\dots,w_n\},\quad T=\{(h,m)\}
  2. 依存弧 (h,m)从支配词 h 指向从属词 m 的一条有向边,表示“m 挂在 h 下面”。
    (h,m)∈T(h,m)\in T
  3. 标签概率 p(r_{h,m}\mid S)模型对该弧携带句法关系标签 r 的置信度,例如主语、宾语。
    p(rh,m∣S)p(r_{h,m}\mid S)
  4. 连乘 Π把所有弧的得分乘起来,代表整棵树作为句子解释的合理程度。
    ∏(h,m)∈Tp(rh,m∣S)\prod_{(h,m)\in T} p(r_{h,m}\mid S)
  5. argmax 输出从所有候选树中选择总分最高的一棵,作为最终依存树。
    T^=arg⁡max⁡T∏(h,m)∈Tp(rh,m∣S)\hat{T}=\arg\max_{T}\prod_{(h,m)\in T} p(r_{h,m}\mid S)

成分句法

第二种说明书是装配图。它不直接回答“谁托着谁”,而是先把城堡分成大模块:塔楼、城墙、主楼;再把塔楼拆成窗户、砖块、屋顶。成分句法正是这样一层层“套盒子”的。

给定“我爱 NLP”,成分句法会得到一棵成分树:S(句子)下面分出 NP(名词短语“我”)和 VP(动词短语“爱 NLP”);VP 又继续拆成 V(动词“爱”)和 NP(名词短语“NLP”)。每个内部节点都是一个短语,叶子才是真正的词。

这种嵌套拆解可以用上下文无关文法(CFG)描述。CFG 提供一组“重写规则”,告诉计算机一个大结构可以替换成哪些小结构。例如:

装配图虽然更细致,但要维护很多语法规则,代价也更高;它和承重图一样,只是观察城堡的一个角度,并不互相替代。

S→NP  VPVP→V  NPNP→N\begin{aligned}\mathrm{S} &\to \mathrm{NP} \; \mathrm{VP}\\\mathrm{VP} &\to \mathrm{V} \; \mathrm{NP}\\\mathrm{NP} &\to \mathrm{N}\end{aligned}
这三条规则相当于“配方”:句子 = 名词短语 + 动词短语;动词短语 = 动词 + 名词短语;名词短语 = 名词。
  1. 起始符 SS 代表一个完整的句子,它是整棵成分树的根。
    S\mathrm{S}
  2. 规则 S → NP VP一个句子可以拆成“名词短语 + 动词短语”两大块,相当于城堡先分成塔楼和城墙。
    S→NP  VP\mathrm{S} \to \mathrm{NP} \; \mathrm{VP}
  3. 规则 VP → V NP动词短语继续展开为“动词 + 名词短语”,这里“爱 NLP”就满足这个结构。
    VP→V  NP\mathrm{VP} \to \mathrm{V} \; \mathrm{NP}
  4. 规则 NP → N名词短语可以继续展开为名词,例如“我”或“NLP”。
    NP→N\mathrm{NP} \to \mathrm{N}

主流工具

手动画语法树太累,幸好有“扫描仪”一样的现成工具。spaCy 是工业界最常见的扫描仪:加载快、调用简单,开箱即用;stanza 则更接近学术界的万能工具箱,对多语言支持更好,还能同时给出依存树和成分树。

用 spaCy 做依存句法分析,只需要三行核心逻辑:加载模型、把句子丢给模型、遍历 token 的 head 和 dep_。中文用户可以用 zh_core_web_sm 这类预训练模型,stanza 同样能处理中文。对刚入门的人,spaCy 的 API 最友好;对想要更全面结构的场景,stanza 更合适。

快速上手时要注意:模型是“包装好的积木包”,下载后直接调用 nlp(text) 即可;不要再自己写分词和词性规则,工具会按预训练 pipeline 自动完成。你需要关心的,是把结构树取出来可视化,并落到下游任务中。扫描仪拿到手后,下一步要判断它扫得准不准——这就是评测。

评测方法

扫描仪扫出的图纸永远会有误差,怎么知道准不准?拿着它的输出和官方说明书逐块比对。句法分析的“官方说明书”是人工标注的树库,例如 CoNLL 共享任务和 Universal Dependencies 系列语料。

最常用的两个指标是 UAS(未标记依存准确率)和 LAS(标记依存准确率)。UAS 只看弧头连得对不对,LAS 还要求弧上的关系标签也正确。公式如下:

现代工具的 UAS 往往能达到 85% 以上,LAS 通常低几个点。所以评测很像乐高质检:先看拼接口数量对没对上(UAS),再看每个接口是不是用了正确的卡扣型号(LAS)。

UAS=#正确依存弧#全部依存弧×100%,LAS=#完全正确(含标签)弧#全部依存弧×100%.\begin{aligned}\mathrm{UAS} &= \frac{\#\text{正确依存弧}}{\#\text{全部依存弧}}\times 100\%,\\\mathrm{LAS} &= \frac{\#\text{完全正确(含标签)弧}}{\#\text{全部依存弧}}\times 100\%.\end{aligned}
UAS 就像检查“每个接口是否插对了孔”,LAS 还要检查“每个接口是否用了正确的卡扣型号”。
  1. 分子“正确依存弧”在 UAS 中只要求弧的父节点正确;在 LAS 中要求父节点和关系标签都正确。
    #正确依存弧\#\text{正确依存弧}
  2. 分母“全部依存弧”模型预测出的所有依存弧数量,包括正确和错误的部分。
    #全部依存弧\#\text{全部依存弧}
  3. 乘以 100%把比值转换成百分比,便于直观比较。
    ×100%\times 100\%
  4. 两个指标的关系LAS 比 UAS 更严格,所以通常情况下 LAS 会小于等于 UAS。
    LAS≤UAS\mathrm{LAS} \le \mathrm{UAS}

应用与选型

结构图纸不是用来收藏的。拿到“谁托着谁”的依存树后,机器可以直接回答“主语是谁”“动作是什么”“宾语是谁”,这正是信息抽取、意图识别和知识图谱构建最需要的中间表示。

选型就像选扫描仪:线上实时服务优先考虑 spaCy,因为它快、内存友好;离线做高精度分析,或者需要成分句法树时,优先考虑 stanza,因为它更强也更容易拿到丰富结构。无论选哪个,都建议先在自己的领域数据上跑一遍 UAS/LAS,看看“官方图纸”上达不达标。

实际工程里,句法分析往往放在“分词 → 词性标注 → 依存解析”这个管道后面。它不负责理解词义,但负责把句子骨架立起来,让下游模型少走弯路。对初学者来说,把一座句子城堡拆成受力图和装配图,是理解自然语言的一把钥匙;这把钥匙会一直陪你走到语义理解那扇门。

AI 应用场景

智能客服意图识别

阶段:文本预处理与语义特征抽取

解决的问题:传统关键词匹配会把“帮我查一下昨天的订单”和“昨天订单有问题吗”都当成“订单”相关,却分不清用户到底要“查询”还是“投诉”。句法分析把“我—查—订单”的依存结构显式抽出后,机器能区分“动词+宾语”的动作对象。

具体案例:某电商客服机器人收到“帮我把张三的订单退款”,依存树让系统找到核心动作“退款”和对象“订单”,再结合命名实体“张三”,自动生成退款工单。

知识图谱事件抽取

阶段:结构化信息抽取

解决的问题:新闻、公告是非结构化文本,人工录入实体关系成本高。依存句法把“主语—谓语—宾语”变成可落库的三元组,让“华为发布Mate60”直接转为(华为,发布,Mate60)。

具体案例:金融舆情系统定期扫描公告,用依存句法提取“公司”“收购”“子公司”的关系,更新产业链知识图谱,省去大量人工标注。

Python 演示

python20 行
# -*- coding: utf-8 -*-"""依存句法分析小演示首次运行前请安装模型:python -m spacy download en_core_web_sm"""import spacy nlp = spacy.load("en_core_web_sm")text = "Alice loves natural language processing."doc = nlp(text) print("Token\tHead\tRelation")for token in doc:    print(f"{token.text}\t{token.head.text}\t{token.dep_}") print("\n依存弧:")for token in doc:    if token.dep_ != "ROOT":        print(f"  {token.head.text} --{token.dep_}--> {token.text}")
目的:用 spaCy 将一句话解析成依存关系,直观看到每个词的支配词和关系标签。
  1. nlp = spacy.load("en_core_web_sm")加载预训练模型,相当于给扫描仪装上镜头。
  2. doc = nlp(text)执行分词、词性、句法一整套 pipeline,返回结构对象。
  3. for token in doc:遍历句子中的每个词符。
  4. token.dep_当前词与支配词的关系标签,如 nsubj、dobj。
  5. token.head.text当前词在依存树上的支配词,也就是“托着它的上级积木”。
  6. if token.dep_ != "ROOT":跳过树根节点,只输出真正有父节点的依存弧。

常见误区

误区我一直以为句法分析就是分词,把“我爱自然语言处理”切成词就算完成。

正解分词只把句子变成零件清单,句法分析还要给出零件间的“拼接图”。同样是“小明看这本书”,分词后如果不分析,机器不知道“看”的对象是“书”,也不知道隐含的主语。

为何常见:分词的“切词”结果肉眼可见,而句法树要额外画出来;初学者容易把可见的前置步骤当成全部。

误区依存句法更简洁,所以成分句法已经过时,根本不用学。

正解两者是不同视角。依存树回答“谁依赖谁”,成分树回答“哪些词组成什么短语”。机器翻译、句法生成常需要成分树,依存句法更适合抽取关系。实际系统经常互补使用。

为何常见:现代工具默认输出依存树,而成分树需要额外配置,导致大家误以为成分句法没用。

误区句法分析工具误差很高,所以结果一定不能信,还不如直接拿原文。

正解现代模型的 UAS 通常能到 90% 左右,对常见句式足够可靠。真正要注意的是长难句和领域迁移,上线前用标注数据评估。

为何常见:偶尔看到一条错误的弧线,就会放大对整体精度的怀疑,而忘记准确率是统计数据。

误区中文不像英文有空格,做句法分析太难,所以只能用英文文本。

正解中文只要先做分词和词性标注,同样能进入依存或成分分析。spaCy 和 stanza 都提供中文预训练模型,线上中文 NLP 系统已经很常见。

为何常见:英文单词之间有天然空格,让人误以为空格是句法分析的前提;其实空格只是便于切词,句法结构分析和语种没有必然绑定。

误区UAS 都到 95% 了,解析质量肯定没问题。

正解UAS 只检查“弧头”对不对,不关心关系标签。如果关系标签总标错,UAS 高但下游抽取照样乱。LAS 更严格,工程上两类指标都要看。

为何常见:人眼看到数字高就安心,忽略了 UAS 的定义里没有包含标签信息。

面试题

Q1. 句法分析任务的输入和输出通常是什么?

单选题 · easy

  • A.输入单词表并输出情感分数
  • B.输入句子并输出结构化语法树← 正确答案
  • C.输入段落并输出每个字的拼音
  • D.输入全文并输出文档主题分类

答案:B。句法分析的核心是从线性句子还原结构树,就像把散装乐高拼出图纸。A 是情感分析,C 是拼音转换,D 是主题分类,都与语法结构无关。

Q2. 依存句法分析中的 root 节点指什么?

单选题 · mid

  • A.整句的核心谓词或根节点← 正确答案
  • B.句子中长度最长的名词
  • C.总是出现在句首的词
  • D.标点符号所在的叶子节点

答案:A。root 是依存树的总根,通常是核心谓词,像城堡的主梁。它不是最长名词、不是句首词,更不是标点。

Q3. 下列哪些属于句法分析的常见结构表示?

多选题 · mid

  • A.依存树← 正确答案
  • B.成分树← 正确答案
  • C.词频向量
  • D.共现矩阵

答案:AB。依存树表示词与词之间的支配关系,成分树表示短语的层次嵌套;两者都是句法结构表示。词频向量和共现矩阵是统计特征,不包含语法结构。

Q4. 在依存句法评测中,UAS 指标衡量什么?

单选题 · hard

  • A.只看弧头是否预测正确← 正确答案
  • B.弧头和关系标签都要正确
  • C.只看关系标签是否正确
  • D.只看整棵树的深度是否一致

答案:A。UAS 全称是 Unlabeled Attachment Score,只判断每个依存弧的“父节点”是否找对,不检查关系标签。LAS 才同时要求弧头和标签正确。

Q5. 关于 spaCy 与 stanza,下列说法正确的是?

单选题 · mid

  • A.两者都能输出成分句法树
  • B.spaCy 偏速度,stanza 可出成分树← 正确答案
  • C.stanza 只能处理英文语料
  • D.spaCy 不能切分中文词

答案:B。spaCy 以工程速度见长,主要输出依存树;stanza 支持多语言,也能产生成分树。A 错在把 spaCy 也当成成分树工具,C、D 与事实不符。

Q6. 句法分析之前通常会做哪些预处理?

多选题 · easy

  • A.分词← 正确答案
  • B.词性标注← 正确答案
  • C.依存树训练
  • D.情感分类

答案:AB。分词把句子切成积木,词性标注给积木贴标签,都是句法分析的常见前置步骤。依存树训练是句法分析本身,情感分类是另一个任务。

Q7. LAS 与 UAS 的核心差异是什么?

单选题 · mid

  • A.LAS 只看弧头是否正确
  • B.LAS 要求弧头与关系标签都正确← 正确答案
  • C.LAS 要求整棵标准树完全一致
  • D.LAS 只统计所有叶子节点

答案:B。LAS 在 UAS 基础上多检查了关系标签,所以更严格。它不要求整棵树完全一致,也不是只看叶子节点。

Q8. 关于依存句法与成分句法,以下说法正确的有?

多选题 · hard

  • A.依存句法关注词间支配关系← 正确答案
  • B.成分句法强调短语层次嵌套← 正确答案
  • C.两者可以互相补充使用← 正确答案
  • D.成分句法不关注短语边界

答案:ABC。依存句法回答谁依赖谁,成分句法回答哪些词组成短语。两种结构可以互补,很多系统同时使用。D 说反了,成分句法恰恰非常关注短语边界。

Q9. 对于“小明喜欢学习”,依存句法最可能的 root 是?

单选题 · easy

  • A.小明
  • B.喜欢← 正确答案
  • C.学习
  • D.没有root

答案:B。“喜欢”是全句的核心谓词,支配“小明”和“学习”,所以最可能是 root。学习虽然也是动词,但在这里扮演“喜欢”的宾语成分。

Q10. 在句法分析工程选型中,合理的做法有哪些?

多选题 · hard

  • A.线上低延迟优先使用spaCy← 正确答案
  • B.离线高精度可选stanza← 正确答案
  • C.上线前用标注数据评测← 正确答案
  • D.所有任务必须做成分句法

答案:ABC。选型要权衡速度和精度,spaCy 适合线上,stanza 适合离线精耕,评测更是必需品。D 把成分句法绝对化了,实际任务不一定需要它。