某天你收到一位旅游博主寄来的明信片集。每张明信片都是一张风景照:有阳光沙滩、雪山星空、夜市烟火、古堡钟楼……但博主故意没写照片是在哪座城市拍的。你的任务,是仅凭这些照片,推断出一路依次到访的城市类型:是先到海滨,再去山城,还是被古城墙包围了一路? 这听起来像玄学,但人类语言恰好拥有类似的“线索”。一个句子里,“名词之都”常拍出人名地名,“动词之城”多产出奔跑跳跃,“形容词之乡”盛产美丽可爱;而城市之间又有固定的“交通习惯”——名词之后常接动词,动词之后常见代词。如果给每个词对应的词性做一张“旅行地图”,我们就能用概率推演出整条路线最可能的版本。 这正是本文的主角:隐马尔可夫模型(HMM)词性标注,以及帮我们高效找到最优路线的维特比算法。前者负责把世界装进概率表,后者负责在亿万条岔路中抄捷径。
对 AI 从业者来说,HMM 词性标注是最能“立竿见影”的统计 NLP 武器:它能在 Prompt 工程、大模型输出校验和结构化文本处理中快速搭建可解释的语法骨架,是通往现代序列模型的一级阶梯。
可视化演示
动态演示HMM词性标注与维特比解码实的核心机制,通过采集/分析/决策/反馈四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
HMM词性标注与维特比解码实:HMM词 HMM词性标注模型原理 发射概率参数估计 核心机制可视化 HMM词性标注与维特比解码实整体架构与关键组件
问题建模
你面前摊开一本神秘游记,里面只有照片没有地名,你要按顺序猜出每一张照片对应的城市类型。NLP 世界里的词性标注正是同样的任务:给一个句子里的每个词打上名词、动词、形容词等“城市类型”标签。比如“我 爱 小猫”这个句子,我们要输出“代词、动词、名词”。
从技术视角看,句子里的词是可见的,称为观测序列;而每个词背后的词性不可直接看到,称为状态序列。词性标注的本质,就是根据可见的观测序列,反推最合理的状态序列。这一步在 AI 领域有专门的名字——序列标注:输入是一个序列,输出是等长的另一个序列,逐位对齐、一一对应。
那么怎么判断“最合理”?一个朴素的想法是:对所有可能的词性序列打分,挑总分最高的那一个。形式化地写成:
你可能会说:候选词性序列的数量随句子长度指数爆炸,逐条打分根本不现实。别急——这正是 HMM 登场的地方。它用几张“概率表”把所有路线压缩成可计算的模型,再用维特比算法优雅地完成搜索。下一节,我们就来拆解这几张表。
- 候选标注序列一条完整的“城市路线”,每个词吃一个词性标签。
- 条件概率给定这串词(照片集),这条词性路线成立的可能性有多大。
- 取最大在所有候选路线里,把概率最大的那一条挑出来作为答案。
HMM三要素
想象旅行社推出了一套“语法城市旅行手册”,里面只有三张表:第一张写“整个行程第一站是某类城市的概率”,第二张写“从一类城市换乘到另一类城市的概率”,第三张写“在某类城市里拍到某张照片的概率”。有了这三张表,任何一条路线的可能性都能算出来。这三张表,就是隐马尔可夫模型(HMM) 的三个要素:初始概率、转移概率、发射概率。
HMM 还倚仗两条简化假设。第一条叫齐次马尔可夫假设:当前城市的类型只由上一站城市决定,之前的行程都被“遗忘”——这就像旅行中你只关心“上一站在哪”,不翻更早的旧账。第二条叫观测独立假设:当前照片只由当前城市决定,跟其他照片无关——就像每张照片是独立投递的明信片,互相不串门。
有了三张表和两条假设,一条路线“照片集 + 城市类型串”的联合概率可以写成一个连乘公式:
这条公式是整个 HMM 的“主心骨”。只要把三张概率表填好,理论上就能给任意句子打分。接下来的两节分别放大这两张表——发射概率管“照片像哪类城市”,转移概率管“城市之间的交通习惯”。
- 第一站概率整个行程从某类城市出发的初始概率。
- 第一张照片在第一个城市类型下拍出第一张照片的概率。
- 连乘记号从第二个位置开始,一站一站连乘下去。
- 换乘概率从上一个词性转移到当前词性的概率,对应旅行手册里的“换乘表”。
- 当站照片概率在当前词性下“生成”当前词的概率,对应“拍照表”。
发射概率
旅行手册里最直观的一张表是“城市拍照习惯表”:在“名词之都”,拍到“猫”“桌”“风”这类照片的比率很高;在“动词之城”,拍到“跑”“吃”“想”的比率很高。这张表描述的是一种发射概率——在某个词性状态下,发出某个词的可能性有多大。它回答的问题是:“这个词,有多像这个词性?”
发射概率的定义式很朴素,就是从标注语料里数数:某个名词标签下出现过多少次“猫”,再除以所有名词标签出现的总次数。例如语料里“名词”一共出现 200 次,其中“猫”跟着出现 62 次,那么发射概率就是 0.31。写成公式:
值得注意的是,发射概率的方向是“词性生成词”,而不是“词生成词性”。这就像我们说“名词之都盛产猫的照片”,而不是“看到猫的照片就一定是名词之都”。有了这张表,模型就能回答“某个词落在某个词性下有多合理”。但只有这一张表还不够——句子毕竟是按语法顺序排列的,词性之间的先后约束,要由另一张表来负责。
- 分子含义统计“词性 t 同时搭配词 w”的共现次数。
- 分母含义统计词性 t 在语料中出现的总次数。
- 频率近似概率两者相除得到一个 0 到 1 的比率,用它近似真实发射概率。
转移概率
城市与城市之间并非随意连接:名词之都的下一站,最常见的是动词之城;形容词之乡的下一站,常常通向名词之都。这些“换乘习惯”构成了 HMM 的第二张关键表——转移概率,描述从一个词性跳到另一个词性的可能性。它捕捉的正是词性之间的语法依赖:中文里“形容词→名词”“名词→动词”是高频通道,“介词→动词”则相当罕见。
转移概率的定义同样来自统计:数一数语料里“名词后面紧跟着动词”出现了多少次,再除以“名词”出现的总次数。比如“名词→动词”出现 80 次,名词总次数 200 次,转移概率就是 0.4。公式:
把转移概率和发射概率合在一起,HMM 就有了双重保险:转移概率保证“路线走得顺”,发射概率保证“照片对得上”。接下来只剩最后一个问题:面对指数级爆炸的候选路线,怎么高效找到全局最优的那一条?这就是维特比算法的主场。
- 分子含义统计词性 ti 后紧跟词性 tj 的相邻共现次数。
- 分母含义统计词性 ti 出现的全部次数。
- 条件频率两者相除得到“前一个是 ti 时,后一个是 tj”的条件概率。
维特比解码
从北京到巴黎,如果每个中转站都有三种选择,全程十站就有 3 的十次方种走法,穷举不现实。聪明的旅行者会沿途记账:每到一个城市,只记下“以这座城市为终点时,我走过的最优路线总分”和“这一步是从哪个城市来的”。到终点后,再沿着账本一路倒推,就得到全局最优路线。这是动态规划思想,也是维特比算法的核心。
具体到词性标注:用 δ_t(j) 表示“处理到第 t 个词、且第 t 个词被标为词性 j 的最大概率”,用 ψ_t(j) 记录“达到这个最大概率时,前一个词采用了哪个词性”。递推公式如下:
计算完成后,在最后一个时刻找到 δ 最大的状态作为终点,再沿着 ψ 记录的“前驱指针”一路回溯,就得到了完整的词性序列。维特比把指数级搜索压缩成了线性时间:句子长度 × 词性状态数的平方,这也是它成为统计 NLP 经典算法的根本原因。
- 前一步最优值第 t-1 个词采用词性 i 时的累计最大概率。
- 乘上转移概率从词性 i 换乘到词性 j 的语法顺畅度。
- 对所有前驱取最大值穷举所有可能的上一词性,取“上一站最好成绩×换乘分”的最高者。
- 乘上发射概率再乘以当前词在第 j 个词性下的生成概率,得到 δ_t(j)。
参数估计
前面那些概率表不是天上掉下来的,而是“翻遍成千上万本已标好城市的游记”统计出来的。这个过程叫参数估计,在 HMM 中通常用最大似然估计:统计语料中的各类频次,用频率近似概率。训练语料长得像这样:每个词旁边已经人工标好了词性,比如“小明/名词 喜欢/动词 漂亮的/形容词 猫咪/名词”。
有了标注语料,估计就是一个数数过程:发射概率数“词性-词”对,转移概率数“词性-词性”对,初始概率数“句子第一个词性”。但这里藏着一个隐患——数据稀疏。如果某个词在训练语料里从未出现过,或者某个“词性对”从未露过面,概率就会变成 0,导致整条路线被“一票否决”。
解决办法是为计数器加一个“保底”:加一平滑(拉普拉斯平滑)。对着眼“转移概率”来说,公式变成:
平滑不是 Hack,而是一种概率上的“先验信念”:我们相信即使没见过的搭配也不该绝对不可能。于是“少数的真实”被保留,“未知的世界”也留了一扇门。参数估计完成后,模型就训练好了,可以上线为陌生句子做词性标注了。
- 分子加一给每个“词性对”的计数都加上 1,保证非零底线。
- 分母加 N加上词性类别总数 N,保证所有概率加起来仍等于 1。
- 平滑后的概率既保留数据中的统计信号,又给未知情况留了余地。
实战应用
把 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 演示
# -*- 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()
self.emit_count[(tag, word)] += 1.0统计“词性-词”共现次数,这是发射概率的分子来源。self.trans_count[(prev, tag)] += 1.0统计“前一词性→当前词性”的转移次数,对应旅行手册里的换乘表。num = self.trans_count.get((prev, tag), 0.0) + self.smooth给每个转移对加一个平滑值,防止零概率“一票否决”。den = sum(...) + self.smooth * (len(self.tags) + 1)分母加上平滑扩展项,保证概率总和仍然归一化。dp[0][tag] = self.trans_prob('<S>', tag) * self.emit_prob(tag, words[0])初始化第一列的累计概率:初始转移 × 发射。score = dp[i - 1][prev] * self.trans_prob(prev, tag) * self.emit_prob(tag, words[i])维特比核心递推:上一步最优 × 转移 × 发射。back[i][tag] = best_prev记录最优前驱状态,供最后回溯路径使用。last = max(tags, key=lambda t: dp[n - 1][t])在最后一列选累计概率最大的状态作为路径终点。zip(sentence, tags)将原词与解码出的词性配对打印,直观看到标注结果。
常见误区
误区我一开始以为发射概率是“看到词‘猫’时,它是名词的概率”,也就是 P(词性 | 词)。统计的时候我就先数“猫”出现多少次,再看里面有几次是名词。
正解发射概率的方向恰好相反,它是 P(词 | 词性)——“在名词这个状态下,生成词‘猫’的概率”。这个方向对应的是 HMM 的生成过程:先有词性,再“拍出”词。就像旅行手册写的是“名词之都爱拍猫的照片”,而不是“看到猫就猜测是名词之都”。用反方向估计概率,会让贝叶斯公式里的条件关系全部错位。
为何常见:人在直觉上习惯从结果推测原因,所以容易把条件概率的方向顺成“看到词→猜词性”,而忽略了 HMM 是一个从状态生成观测的生成式模型。
误区维特比不就是每一步选概率最大的词性吗?比如第一个词选名词、第二个词选动词、第三个词选名词……一路选最大的就完事了。
正解贪心算法是“只看当下”,每一步都挑局部最优;维特比是“全局记账”,每一步都保留每个词性下的最优累计概率,而不是只保留一个。它同时维护 N 条候选路径(N 为词性数),最后才从终点回溯选全局最优。两者的区别就像旅行中“每站都选最近的旅馆”和“全程路线最短”可能是两回事。
为何常见:维特比的名字带有“最优”字样,初学者容易把它和“每步取最大”的贪心直觉画等号,忽略了动态规划中“并行保留所有状态”的关键细节。
误区有了转移概率表,不就能表示所有语法规律了吗?比如“名词后面跟动词”这种搭配都能查表得到,长距离依赖应该也能覆盖。
正解HMM 的转移概率只建模“相邻两个状态”的关系,即第 t 个词性只依赖于第 t-1 个词性。“因为……所以……”这种跨越多个词的呼应,一阶 HMM 根本看不见。它连“前两个词性”的约束都表达不了,更不用说长距离依赖。这也是后来 CRF、神经网络等更强模型存在的原因。
为何常见:转移概率表看起来可以“任意大”,让人误以为表越大表达力越强,忽略了模型结构本身限定了依赖的距离。
误区训练语料只有几百个句子,统计出来好多“词性对”次数是 0。反正频率就是概率,直接拿这些频率表去解码不就行了?
正解硬统计会让大量合理的词性搭配因为“样本中没出现”而概率为 0,解码时一遇到未知情况就整条路径崩溃。必须引入加一平滑等策略,给未出现事件一个“低保概率”。平滑的本质是承认“没有证据”不等于“不可能”,这在数据稀疏时尤其关键。
为何常见:最大似然估计的“频率即概率”在样本无穷大时才严格成立,初学者容易忽略小样本下的偏差,把数学课的极限结论直接搬到工程里用。
面试题
Q1. 发射概率描述的是下面哪一对关系?
- A.词性到词性的转移关系
- B.词性生成某个词的概率← 正确答案
- C.词在语料中的全局频率
- D.句子开头词性的分布
答案:B。发射概率是 P(w|t),表示在某个词性状态下生成某个词的概率,对应“名词之都拍出猫的照片”这个方向。A 是转移概率,C 是词频统计,D 是初始概率,都和“词性生成词”的含义无关。
Q2. HMM 的齐次马尔可夫假设是指什么?
- A.所有观测之间完全相互独立
- B.当前状态只依赖前一时刻状态← 正确答案
- C.所有状态的出现概率完全相等
- D.词性标注的结果必须唯一确定
答案:B。齐次马尔可夫假设规定当前隐藏状态只与前一个隐藏状态有关,更早的信息都被“遗忘”,这是 HMM 化简联合概率的基础。A 对应观测独立假设,C 和 D 均与 HMM 假设无关。
Q3. 若词性集合共有 N 种,则转移概率矩阵的形状是?
- 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. 维特比算法的本质是哪一类方法?
- A.随机采样近似搜索
- B.每步取最大的贪心算法
- C.动态规划求全局最优← 正确答案
- D.分治策略递归分解
答案:C。维特比通过维护每个时刻、每个状态下的最优累计概率和前驱指针,把指数级路径搜索压缩成多项式时间,是标准动态规划。贪心只保一条路,随机采样不保证最优,分治侧重问题分解而非路径搜索。
Q5. 与每步贪心相比,维特比解码的主要优势是什么?
- A.完全不需要任何概率表
- B.能够考虑整条路径的全局概率← 正确答案
- C.只需要发射概率即可工作
- D.只能处理两个词性的情况
答案:B。贪心只关注每一步局部最大,可能把整体最优路径“带偏”;维特比同时保留每个状态的候选路径,综合考虑转移与发射信息,最终回溯出全局概率最大的词性序列。A、C 均不成立,D 是错误限制。
Q6. 某转移对出现 8 次、源状态总次数为 20、状态数为 5,加一平滑后该转移概率为?
- 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 的三个基本要素?
- A.初始概率分布← 正确答案
- B.转移概率矩阵← 正确答案
- C.发射概率矩阵← 正确答案
- D.词频逆文档矩阵
答案:ABC。HMM 三要素是初始概率(第一站城市分布)、转移概率(城市间换乘频率)和发射概率(城市拍出照片的频率)。D 是 TF-IDF 中的概念,来自信息检索领域,与 HMM 结构无关。
Q8. 维特比算法在解码过程中需要维护哪些信息?
- A.每时刻每状态的最大累计概率← 正确答案
- B.每个状态最优路径的前驱表← 正确答案
- C.所有完整路径的穷举概率列表
- D.每个词与所有词性的联合计数
答案:AB。维特比用 δ 表保存累计最大概率、用 ψ 表保存前驱指针,供终点回溯使用。C 是穷举法的行为,正是维特比要避免的;D 是训练阶段统计参数的工作,不是解码阶段维护的内容。
Q9. “马尔可夫性”在词性标注中最直观的含义是?
- A.未来只与当前相关,与过去无关← 正确答案
- B.未来与过去完全相同
- C.所有词性出现概率完全相等
- D.概率值随时间线性增长
答案:A。马尔可夫性即“无后效性”:预测下一个词性时只需要看当前词性,无需追溯更早历史。B 是绝对相关的极端说法,C、D 与马尔可夫性无关。
Q10. 下列哪些是 HMM 词性标注的已知局限?
- A.观测独立假设忽略上下文信息← 正确答案
- B.数据稀疏会导致零概率问题← 正确答案
- C.一阶假设无法建模长距离依赖← 正确答案
- D.训练时无需任何标注语料
答案:ABC。HMM 假设观测独立,因此难以利用前后文线索;小语料下大量未出现事件需要平滑兜底;一阶马尔可夫假设限制了长距离语法关系的表达。D 恰好说反——HMM 参数估计依赖人工标注语料,是有监督方法。