某天你收到一位旅游博主寄来的明信片集。每张明信片都是一张风景照:有阳光沙滩、雪山星空、夜市烟火、古堡钟楼……但博主故意没写照片是在哪座城市拍的。你的任务,是仅凭这些照片,推断出一路依次到访的城市类型:是先到海滨,再去山城,还是被古城墙包围了一路? 这听起来像玄学,但人类语言恰好拥有类似的“线索”。一个句子里,“名词之都”常拍出人名地名,“动词之城”多产出奔跑跳跃,“形容词之乡”盛产美丽可爱;而城市之间又有固定的“交通习惯”——名词之后常接动词,动词之后常见代词。如果给每个词对应的词性做一张“旅行地图”,我们就能用概率推演出整条路线最可能的版本。 这正是本文的主角:隐马尔可夫模型(HMM)词性标注,以及帮我们高效找到最优路线的维特比算法。前者负责把世界装进概率表,后者负责在亿万条岔路中抄捷径。

岗位关联

对 AI 从业者来说,HMM 词性标注是最能“立竿见影”的统计 NLP 武器:它能在 Prompt 工程、大模型输出校验和结构化文本处理中快速搭建可解释的语法骨架,是通往现代序列模型的一级阶梯。

目录
  1. 可视化演示
  2. 问题建模
  3. HMM三要素
  4. 发射概率
  5. 转移概率
  6. 维特比解码
  7. 参数估计
  8. 实战应用
  9. 局限与优化
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

动态演示HMM词性标注与维特比解码实的核心机制,通过采集/分析/决策/反馈四种模式展示关键概念与交互流程。

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

HMM词性标注与维特比解码实:HMM词 HMM词性标注模型原理 发射概率参数估计 核心机制可视化 HMM词性标注与维特比解码实整体架构与关键组件

问题建模

你面前摊开一本神秘游记,里面只有照片没有地名,你要按顺序猜出每一张照片对应的城市类型。NLP 世界里的词性标注正是同样的任务:给一个句子里的每个词打上名词、动词、形容词等“城市类型”标签。比如“我 爱 小猫”这个句子,我们要输出“代词、动词、名词”。

从技术视角看,句子里的词是可见的,称为观测序列;而每个词背后的词性不可直接看到,称为状态序列。词性标注的本质,就是根据可见的观测序列,反推最合理的状态序列。这一步在 AI 领域有专门的名字——序列标注:输入是一个序列,输出是等长的另一个序列,逐位对齐、一一对应。

那么怎么判断“最合理”?一个朴素的想法是:对所有可能的词性序列打分,挑总分最高的那一个。形式化地写成:

你可能会说:候选词性序列的数量随句子长度指数爆炸,逐条打分根本不现实。别急——这正是 HMM 登场的地方。它用几张“概率表”把所有路线压缩成可计算的模型,再用维特比算法优雅地完成搜索。下一节,我们就来拆解这几张表。

t∗=arg⁡max⁡t1,t2,…,tnP(t1,t2,…,tn∣w1,w2,…,wn)t^* = \arg\max_{t_1, t_2, \ldots, t_n} P(t_1, t_2, \ldots, t_n \mid w_1, w_2, \ldots, w_n)
  1. 候选标注序列一条完整的“城市路线”,每个词吃一个词性标签。
    t1,t2,…,tnt_1, t_2, \ldots, t_n
  2. 条件概率给定这串词(照片集),这条词性路线成立的可能性有多大。
    P(t1,t2,…,tn∣w1,w2,…,wn)P(t_1, t_2, \ldots, t_n \mid w_1, w_2, \ldots, w_n)
  3. 取最大在所有候选路线里,把概率最大的那一条挑出来作为答案。
    arg⁡max⁡\arg\max

HMM三要素

想象旅行社推出了一套“语法城市旅行手册”,里面只有三张表:第一张写“整个行程第一站是某类城市的概率”,第二张写“从一类城市换乘到另一类城市的概率”,第三张写“在某类城市里拍到某张照片的概率”。有了这三张表,任何一条路线的可能性都能算出来。这三张表,就是隐马尔可夫模型(HMM) 的三个要素:初始概率、转移概率、发射概率。

HMM 还倚仗两条简化假设。第一条叫齐次马尔可夫假设:当前城市的类型只由上一站城市决定,之前的行程都被“遗忘”——这就像旅行中你只关心“上一站在哪”,不翻更早的旧账。第二条叫观测独立假设:当前照片只由当前城市决定,跟其他照片无关——就像每张照片是独立投递的明信片,互相不串门。

有了三张表和两条假设,一条路线“照片集 + 城市类型串”的联合概率可以写成一个连乘公式:

这条公式是整个 HMM 的“主心骨”。只要把三张概率表填好,理论上就能给任意句子打分。接下来的两节分别放大这两张表——发射概率管“照片像哪类城市”,转移概率管“城市之间的交通习惯”。

P(w,t)=P(t1)×P(w1∣t1)×∏i=2nP(ti∣ti−1)×P(wi∣ti)P(\mathbf{w}, \mathbf{t}) = P(t_1) \times P(w_1 \mid t_1) \times \prod_{i=2}^{n} P(t_i \mid t_{i-1}) \times P(w_i \mid t_i)
  1. 第一站概率整个行程从某类城市出发的初始概率。
    P(t1)P(t_1)
  2. 第一张照片在第一个城市类型下拍出第一张照片的概率。
    P(w1∣t1)P(w_1 \mid t_1)
  3. 连乘记号从第二个位置开始,一站一站连乘下去。
    ∏i=2n\prod_{i=2}^{n}
  4. 换乘概率从上一个词性转移到当前词性的概率,对应旅行手册里的“换乘表”。
    P(ti∣ti−1)P(t_i \mid t_{i-1})
  5. 当站照片概率在当前词性下“生成”当前词的概率,对应“拍照表”。
    P(wi∣ti)P(w_i \mid t_i)

发射概率

旅行手册里最直观的一张表是“城市拍照习惯表”:在“名词之都”,拍到“猫”“桌”“风”这类照片的比率很高;在“动词之城”,拍到“跑”“吃”“想”的比率很高。这张表描述的是一种发射概率——在某个词性状态下,发出某个词的可能性有多大。它回答的问题是:“这个词,有多像这个词性?”

发射概率的定义式很朴素,就是从标注语料里数数:某个名词标签下出现过多少次“猫”,再除以所有名词标签出现的总次数。例如语料里“名词”一共出现 200 次,其中“猫”跟着出现 62 次,那么发射概率就是 0.31。写成公式:

值得注意的是,发射概率的方向是“词性生成词”,而不是“词生成词性”。这就像我们说“名词之都盛产猫的照片”,而不是“看到猫的照片就一定是名词之都”。有了这张表,模型就能回答“某个词落在某个词性下有多合理”。但只有这一张表还不够——句子毕竟是按语法顺序排列的,词性之间的先后约束,要由另一张表来负责。

P(w∣t)=count(t→w)count(t)P(w \mid t) = \frac{\text{count}(t \to w)}{\text{count}(t)}
  1. 分子含义统计“词性 t 同时搭配词 w”的共现次数。
    count(t→w)\text{count}(t \to w)
  2. 分母含义统计词性 t 在语料中出现的总次数。
    count(t)\text{count}(t)
  3. 频率近似概率两者相除得到一个 0 到 1 的比率,用它近似真实发射概率。
    count(t→w)count(t)\frac{\text{count}(t \to w)}{\text{count}(t)}

转移概率

城市与城市之间并非随意连接:名词之都的下一站,最常见的是动词之城;形容词之乡的下一站,常常通向名词之都。这些“换乘习惯”构成了 HMM 的第二张关键表——转移概率,描述从一个词性跳到另一个词性的可能性。它捕捉的正是词性之间的语法依赖:中文里“形容词→名词”“名词→动词”是高频通道,“介词→动词”则相当罕见。

转移概率的定义同样来自统计:数一数语料里“名词后面紧跟着动词”出现了多少次,再除以“名词”出现的总次数。比如“名词→动词”出现 80 次,名词总次数 200 次,转移概率就是 0.4。公式:

把转移概率和发射概率合在一起,HMM 就有了双重保险:转移概率保证“路线走得顺”,发射概率保证“照片对得上”。接下来只剩最后一个问题:面对指数级爆炸的候选路线,怎么高效找到全局最优的那一条?这就是维特比算法的主场。

P(tj∣ti)=count(ti→tj)count(ti)P(t_j \mid t_i) = \frac{\text{count}(t_i \to t_j)}{\text{count}(t_i)}
  1. 分子含义统计词性 ti 后紧跟词性 tj 的相邻共现次数。
    count(ti→tj)\text{count}(t_i \to t_j)
  2. 分母含义统计词性 ti 出现的全部次数。
    count(ti)\text{count}(t_i)
  3. 条件频率两者相除得到“前一个是 ti 时,后一个是 tj”的条件概率。
    count(ti→tj)count(ti)\frac{\text{count}(t_i \to t_j)}{\text{count}(t_i)}

维特比解码

从北京到巴黎,如果每个中转站都有三种选择,全程十站就有 3 的十次方种走法,穷举不现实。聪明的旅行者会沿途记账:每到一个城市,只记下“以这座城市为终点时,我走过的最优路线总分”和“这一步是从哪个城市来的”。到终点后,再沿着账本一路倒推,就得到全局最优路线。这是动态规划思想,也是维特比算法的核心。

具体到词性标注:用 δ_t(j) 表示“处理到第 t 个词、且第 t 个词被标为词性 j 的最大概率”,用 ψ_t(j) 记录“达到这个最大概率时,前一个词采用了哪个词性”。递推公式如下:

计算完成后,在最后一个时刻找到 δ 最大的状态作为终点,再沿着 ψ 记录的“前驱指针”一路回溯,就得到了完整的词性序列。维特比把指数级搜索压缩成了线性时间:句子长度 × 词性状态数的平方,这也是它成为统计 NLP 经典算法的根本原因。

δt(j)=max⁡1≤i≤N[δt−1(i)×P(tj∣ti)]×P(wt∣tj)\delta_t(j) = \max_{1 \le i \le N} \left[ \delta_{t-1}(i) \times P(t_j \mid t_i) \right] \times P(w_t \mid t_j)
  1. 前一步最优值第 t-1 个词采用词性 i 时的累计最大概率。
    δt−1(i)\delta_{t-1}(i)
  2. 乘上转移概率从词性 i 换乘到词性 j 的语法顺畅度。
    P(tj∣ti)P(t_j \mid t_i)
  3. 对所有前驱取最大值穷举所有可能的上一词性,取“上一站最好成绩×换乘分”的最高者。
    max⁡1≤i≤N[⋅]\max_{1 \le i \le N} \left[ \cdot \right]
  4. 乘上发射概率再乘以当前词在第 j 个词性下的生成概率,得到 δ_t(j)。
    P(wt∣tj)P(w_t \mid t_j)

参数估计

前面那些概率表不是天上掉下来的,而是“翻遍成千上万本已标好城市的游记”统计出来的。这个过程叫参数估计,在 HMM 中通常用最大似然估计:统计语料中的各类频次,用频率近似概率。训练语料长得像这样:每个词旁边已经人工标好了词性,比如“小明/名词 喜欢/动词 漂亮的/形容词 猫咪/名词”。

有了标注语料,估计就是一个数数过程:发射概率数“词性-词”对,转移概率数“词性-词性”对,初始概率数“句子第一个词性”。但这里藏着一个隐患——数据稀疏。如果某个词在训练语料里从未出现过,或者某个“词性对”从未露过面,概率就会变成 0,导致整条路线被“一票否决”。

解决办法是为计数器加一个“保底”:加一平滑(拉普拉斯平滑)。对着眼“转移概率”来说,公式变成:

平滑不是 Hack,而是一种概率上的“先验信念”:我们相信即使没见过的搭配也不该绝对不可能。于是“少数的真实”被保留,“未知的世界”也留了一扇门。参数估计完成后,模型就训练好了,可以上线为陌生句子做词性标注了。

Psmooth(tj∣ti)=count(ti→tj)+1count(ti)+NP_{\text{smooth}}(t_j \mid t_i) = \frac{\text{count}(t_i \to t_j) + 1}{\text{count}(t_i) + N}
  1. 分子加一给每个“词性对”的计数都加上 1,保证非零底线。
    count(ti→tj)+1\text{count}(t_i \to t_j) + 1
  2. 分母加 N加上词性类别总数 N,保证所有概率加起来仍等于 1。
    count(ti)+N\text{count}(t_i) + N
  3. 平滑后的概率既保留数据中的统计信号,又给未知情况留了余地。
    count(ti→tj)+1count(ti)+N\frac{\text{count}(t_i \to t_j) + 1}{\text{count}(t_i) + N}

实战应用

把 HMM 词性标注真正“跑起来”,是一条清晰的流水线:准备标注语料 → 统计训练参数 → 维特比解码。以中文为例,“我 爱 可爱 的 小猫”这句话经过分词后,模型先查发射概率表:代词和“我”配对、动词和“爱”配对、形容词和“可爱”配对……再查转移概率:代词→动词、动词→形容词、形容词→助词、助词→名词,这些通道都要比较通畅,最后维特比把它们串成整体最优路径。

工程上还要关注评估指标。最常用的是逐词准确率:标注正确的词数除以总词数;更严谨的系统还会用每个词性上的精确率、召回率和 F1 值。这些指标告诉我们模型“到底靠谱在哪、偏科在哪”。

在今天的 LLM 时代,HMM 词性标注还有了新的用武之地——大模型后处理。当大模型生成一段客服回复或结构化文本时,我们可以用 HMM 给输出打一遍词性标签,检查是否存在“动词后紧跟助词”“两个介词连用”等低概率序列,一旦发现就触发重写或提示修正。这比直接让模型自查成本更低、更可解释。

局限与优化

旅行攻略再厚,也有覆盖不到的小巷和秘境。HMM 词性标注同样存在明显的边界。第一是数据稀疏:真实语言中词汇量巨大,未登录词层出不穷,发射概率遇到“没见过的词”只能靠平滑硬撑,效果难免打折。第二是一阶马尔可夫假设太强:它只允许看上一站的词性,但真实语法常常需要更长的视野,比如“因为……所以……”这种跨越多词的长距离依赖,一阶 HMM 就力不从心了。

针对第一个问题,工程上会采用高阶 HMM:转移概率不只依赖前一个词性,而是前两个甚至前三个词性。代价是参数空间迅速膨胀,需要更大的语料来支撑。针对第二个问题,研究者把目光投向了更有表达力的模型:MEMM、CRF 允许引入任意上下文特征,BiLSTM/Transformer 等神经网络模型则用分布式表示缓解了数据稀疏。

但 HMM 并没有被淘汰。它的概率表透明可解释、训练成本极低、适合冷启动,依然是理解序列标注的最佳入门模型。就像纸质旅行攻略虽然不如手机地图智能,但当你走进没信号的深山,它反而成了最可靠的伙伴。

AI 应用场景

大模型输出语法的“巡逻兵”

阶段:后处理与质量校验

解决的问题:大模型生成文本偶尔出现“她 是 一个 非常 的 工程师”这类语序混乱、词性搭配异常的病句。传统做法靠人肉审阅效率低、覆盖不全;用 HMM 给生成文本打上词性标签后,可以自动检测低概率的转移序列(如“副词→助词→名词”等异常通道),并标记可疑片段供人工复核。

具体案例:某电商客服机器人每天生成上万条回复,接上 HMM 词性校验层后,把“词性病句”的检出率提升了约 40%,同时规则引擎可以直接解释是哪个词性对出了问题,方便运营团队快速定位 Prompt 缺陷。

搜索与对话系统的查询意图解析

阶段:输入理解与特征提取

解决的问题:用户输入“北京到上海的机票”,传统关键词匹配只能提取“北京”“上海”两个词,却无法判断它们分别是出发地和目的地。HMM 词性标注先给查询打上“地名/动词/名词”等标签,再把标注结果喂给槽位填充模块,显著提升意图识别的准确率。

具体案例:某语音助手在机票预订场景中,用 HMM 给 ASR 转写文本做词性标注,发现“到”字稳定地标注为介词后,系统便以此为锚点切分出“出发地→目的地”,让多轮对话的槽位填充成功率提升了 18%。

语音识别文本的快速纠错预筛

阶段:语音后处理

解决的问题:ASR 在嘈杂环境下容易出现同音误写,如把“我到南京”识别成“我到南宁”。孤立地看每个词很难发现问题,但 HMM 的转移概率会给出线索——“到”作为动词通常后接名词,“南京/南宁”都是名词,此时再结合历史检索热度和上下文地理常识,就能触发纠错。

具体案例:某会议转写工具对 ASR 文本执行 HMM 词性序列评分,对评分低于阈值的句子自动标记“疑似误写”,并推荐候选替换词。该预筛机制让后续纠错模型的调用量减少了 60%,降低了整体服务成本。

Python 演示

python80 行
# -*- coding: utf-8 -*-"""HMM 词性标注的最小实现:频率估计 + 加一平滑 + 维特比解码"""from collections import defaultdict  class HMMTagger:    def __init__(self, smooth=1.0):        self.smooth = smooth        self.emit_count = defaultdict(float)   # (tag, word) -> count        self.trans_count = defaultdict(float)  # (prev_tag, tag) -> count        self.tag_total = defaultdict(float)    # tag -> count        self.init_count = defaultdict(float)   # '<S>' -> tag count        self.tags = set()     def train(self, corpus):        for sent in corpus:            prev = '<S>'            for word, tag in sent:                self.emit_count[(tag, word)] += 1.0                self.trans_count[(prev, tag)] += 1.0                self.tag_total[tag] += 1.0                self.init_count[(prev, tag)] += 1.0                self.tags.add(tag)                prev = tag     def trans_prob(self, prev, tag):        num = self.trans_count.get((prev, tag), 0.0) + self.smooth        den = sum(self.trans_count[(p, t)] for p, t in self.trans_count if p == prev)        den += self.smooth * (len(self.tags) + 1)        return num / den     def emit_prob(self, tag, word):        num = self.emit_count.get((tag, word), 0.0) + self.smooth        den = self.tag_total.get(tag, 0.0) + self.smooth * (len(self.emit_count) + 1)        return num / den     def viterbi(self, words):        if not words:            return []        tags = sorted(self.tags)        n = len(words)        dp = [dict() for _ in range(n)]        back = [dict() for _ in range(n)]        for tag in tags:            dp[0][tag] = self.trans_prob('<S>', tag) * self.emit_prob(tag, words[0])            back[0][tag] = None        for i in range(1, n):            for tag in tags:                best_prev, best_score = None, -1.0                for prev in tags:                    score = dp[i - 1][prev] * self.trans_prob(prev, tag) * self.emit_prob(tag, words[i])                    if score > best_score:                        best_score, best_prev = score, prev                dp[i][tag] = best_score                back[i][tag] = best_prev        last = max(tags, key=lambda t: dp[n - 1][t])        result = [last]        for i in range(n - 1, 0, -1):            last = back[i][last]            result.append(last)        return list(reversed(result))  def main():    corpus = [        [("我", "代词"), ("爱", "动词"), ("可爱的", "形容词"), ("小猫", "名词")],        [("小明", "名词"), ("喜欢", "动词"), ("跑步", "动词")],        [("这", "代词"), ("是", "动词"), ("漂亮", "形容词"), ("花园", "名词")],        [("小猫", "名词"), ("在", "介词"), ("睡觉", "动词")],    ]    tagger = HMMTagger(smooth=0.1)    tagger.train(corpus)    sentence = ["小明", "爱", "漂亮", "小猫"]    tags = tagger.viterbi(sentence)    print(" ".join(f"{w}/{t}" for w, t in zip(sentence, tags)))    # 期望输出: 小明/名词 爱/动词 漂亮/形容词 小猫/名词  if __name__ == "__main__":    main()
目的:用最小可运行的 Python 实现训练一个 HMM 词性标注器,并利用维特比算法为未见过的句子解码最优词性序列。
  1. self.emit_count[(tag, word)] += 1.0统计“词性-词”共现次数,这是发射概率的分子来源。
  2. self.trans_count[(prev, tag)] += 1.0统计“前一词性→当前词性”的转移次数,对应旅行手册里的换乘表。
  3. num = self.trans_count.get((prev, tag), 0.0) + self.smooth给每个转移对加一个平滑值,防止零概率“一票否决”。
  4. den = sum(...) + self.smooth * (len(self.tags) + 1)分母加上平滑扩展项,保证概率总和仍然归一化。
  5. dp[0][tag] = self.trans_prob('<S>', tag) * self.emit_prob(tag, words[0])初始化第一列的累计概率:初始转移 × 发射。
  6. score = dp[i - 1][prev] * self.trans_prob(prev, tag) * self.emit_prob(tag, words[i])维特比核心递推:上一步最优 × 转移 × 发射。
  7. back[i][tag] = best_prev记录最优前驱状态,供最后回溯路径使用。
  8. last = max(tags, key=lambda t: dp[n - 1][t])在最后一列选累计概率最大的状态作为路径终点。
  9. zip(sentence, tags)将原词与解码出的词性配对打印,直观看到标注结果。

常见误区

误区我一开始以为发射概率是“看到词‘猫’时,它是名词的概率”,也就是 P(词性 | 词)。统计的时候我就先数“猫”出现多少次,再看里面有几次是名词。

正解发射概率的方向恰好相反,它是 P(词 | 词性)——“在名词这个状态下,生成词‘猫’的概率”。这个方向对应的是 HMM 的生成过程:先有词性,再“拍出”词。就像旅行手册写的是“名词之都爱拍猫的照片”,而不是“看到猫就猜测是名词之都”。用反方向估计概率,会让贝叶斯公式里的条件关系全部错位。

为何常见:人在直觉上习惯从结果推测原因,所以容易把条件概率的方向顺成“看到词→猜词性”,而忽略了 HMM 是一个从状态生成观测的生成式模型。

误区维特比不就是每一步选概率最大的词性吗?比如第一个词选名词、第二个词选动词、第三个词选名词……一路选最大的就完事了。

正解贪心算法是“只看当下”,每一步都挑局部最优;维特比是“全局记账”,每一步都保留每个词性下的最优累计概率,而不是只保留一个。它同时维护 N 条候选路径(N 为词性数),最后才从终点回溯选全局最优。两者的区别就像旅行中“每站都选最近的旅馆”和“全程路线最短”可能是两回事。

为何常见:维特比的名字带有“最优”字样,初学者容易把它和“每步取最大”的贪心直觉画等号,忽略了动态规划中“并行保留所有状态”的关键细节。

误区有了转移概率表,不就能表示所有语法规律了吗?比如“名词后面跟动词”这种搭配都能查表得到,长距离依赖应该也能覆盖。

正解HMM 的转移概率只建模“相邻两个状态”的关系,即第 t 个词性只依赖于第 t-1 个词性。“因为……所以……”这种跨越多个词的呼应,一阶 HMM 根本看不见。它连“前两个词性”的约束都表达不了,更不用说长距离依赖。这也是后来 CRF、神经网络等更强模型存在的原因。

为何常见:转移概率表看起来可以“任意大”,让人误以为表越大表达力越强,忽略了模型结构本身限定了依赖的距离。

误区训练语料只有几百个句子,统计出来好多“词性对”次数是 0。反正频率就是概率,直接拿这些频率表去解码不就行了?

正解硬统计会让大量合理的词性搭配因为“样本中没出现”而概率为 0,解码时一遇到未知情况就整条路径崩溃。必须引入加一平滑等策略,给未出现事件一个“低保概率”。平滑的本质是承认“没有证据”不等于“不可能”,这在数据稀疏时尤其关键。

为何常见:最大似然估计的“频率即概率”在样本无穷大时才严格成立,初学者容易忽略小样本下的偏差,把数学课的极限结论直接搬到工程里用。

面试题

Q1. 发射概率描述的是下面哪一对关系?

单选题 · easy

  • A.词性到词性的转移关系
  • B.词性生成某个词的概率← 正确答案
  • C.词在语料中的全局频率
  • D.句子开头词性的分布

答案:B。发射概率是 P(w|t),表示在某个词性状态下生成某个词的概率,对应“名词之都拍出猫的照片”这个方向。A 是转移概率,C 是词频统计,D 是初始概率,都和“词性生成词”的含义无关。

Q2. HMM 的齐次马尔可夫假设是指什么?

单选题 · easy

  • A.所有观测之间完全相互独立
  • B.当前状态只依赖前一时刻状态← 正确答案
  • C.所有状态的出现概率完全相等
  • D.词性标注的结果必须唯一确定

答案:B。齐次马尔可夫假设规定当前隐藏状态只与前一个隐藏状态有关,更早的信息都被“遗忘”,这是 HMM 化简联合概率的基础。A 对应观测独立假设,C 和 D 均与 HMM 假设无关。

Q3. 若词性集合共有 N 种,则转移概率矩阵的形状是?

单选题 · mid

  • A.N 行 N 列← 正确答案
  • B.N 行 1 列
  • C.1 行 N 列
  • D.词表长度乘以 N

答案:A。转移矩阵的每个元素 P(tj|ti) 都对应“从词性 i 到词性 j”的组合,因此是所有 N 个源词性与 N 个目标词性的两两配对,形状为 N×N。B、C 是向量形状,D 混淆了词表长度与词性集合大小。

Q4. 维特比算法的本质是哪一类方法?

单选题 · mid

  • A.随机采样近似搜索
  • B.每步取最大的贪心算法
  • C.动态规划求全局最优← 正确答案
  • D.分治策略递归分解

答案:C。维特比通过维护每个时刻、每个状态下的最优累计概率和前驱指针,把指数级路径搜索压缩成多项式时间,是标准动态规划。贪心只保一条路,随机采样不保证最优,分治侧重问题分解而非路径搜索。

Q5. 与每步贪心相比,维特比解码的主要优势是什么?

单选题 · mid

  • A.完全不需要任何概率表
  • B.能够考虑整条路径的全局概率← 正确答案
  • C.只需要发射概率即可工作
  • D.只能处理两个词性的情况

答案:B。贪心只关注每一步局部最大,可能把整体最优路径“带偏”;维特比同时保留每个状态的候选路径,综合考虑转移与发射信息,最终回溯出全局概率最大的词性序列。A、C 均不成立,D 是错误限制。

Q6. 某转移对出现 8 次、源状态总次数为 20、状态数为 5,加一平滑后该转移概率为?

单选题 · hard

  • A.8/20
  • B.9/25← 正确答案
  • C.8/25
  • D.9/20

答案:B。加一平滑公式为 (count + 1) / (count_total + N),代入得 (8+1)/(20+5)=9/25。A 是未平滑的原始频率,C 分子未加一,D 分母未加状态数,三者都不符合平滑公式。

Q7. 下列哪些属于 HMM 的三个基本要素?

多选题 · mid

  • A.初始概率分布← 正确答案
  • B.转移概率矩阵← 正确答案
  • C.发射概率矩阵← 正确答案
  • D.词频逆文档矩阵

答案:ABC。HMM 三要素是初始概率(第一站城市分布)、转移概率(城市间换乘频率)和发射概率(城市拍出照片的频率)。D 是 TF-IDF 中的概念,来自信息检索领域,与 HMM 结构无关。

Q8. 维特比算法在解码过程中需要维护哪些信息?

多选题 · hard

  • A.每时刻每状态的最大累计概率← 正确答案
  • B.每个状态最优路径的前驱表← 正确答案
  • C.所有完整路径的穷举概率列表
  • D.每个词与所有词性的联合计数

答案:AB。维特比用 δ 表保存累计最大概率、用 ψ 表保存前驱指针,供终点回溯使用。C 是穷举法的行为,正是维特比要避免的;D 是训练阶段统计参数的工作,不是解码阶段维护的内容。

Q9. “马尔可夫性”在词性标注中最直观的含义是?

单选题 · easy

  • A.未来只与当前相关,与过去无关← 正确答案
  • B.未来与过去完全相同
  • C.所有词性出现概率完全相等
  • D.概率值随时间线性增长

答案:A。马尔可夫性即“无后效性”:预测下一个词性时只需要看当前词性,无需追溯更早历史。B 是绝对相关的极端说法,C、D 与马尔可夫性无关。

Q10. 下列哪些是 HMM 词性标注的已知局限?

多选题 · hard

  • A.观测独立假设忽略上下文信息← 正确答案
  • B.数据稀疏会导致零概率问题← 正确答案
  • C.一阶假设无法建模长距离依赖← 正确答案
  • D.训练时无需任何标注语料

答案:ABC。HMM 假设观测独立,因此难以利用前后文线索;小语料下大量未出现事件需要平滑兜底;一阶马尔可夫假设限制了长距离语法关系的表达。D 恰好说反——HMM 参数估计依赖人工标注语料,是有监督方法。