你是一家连锁餐厅的质量总监。招牌主厨只有一位,但每天要从后厨端出几百道菜,让他逐道品尝把关根本不现实。于是你让主厨把几十年的经验浓缩成几条简单易行的“试吃规则”:宫保鸡丁必须见到花生米,麻婆豆腐必须够麻够辣,一道菜里连主料都看不出,就直接退回。然后把规则交给普通试吃员执行——每道菜只要照着几条规则打勾打叉,很快就能贴上“合格”或者“退回”的标签。 乍一看,每一条规则都很“笨”:只看有没有花生、辣不辣,完全不能代表一道菜的全部水准。但当几条规则放在一起综合判断时,结果却常常相当可靠。这个思路,正是人工智能训练中“弱监督”的灵魂:用批量廉价的规则,代替逐条昂贵的人工标注。把规则变成代码、设计出高质量规则集合的过程,就叫标注函数设计。 接下来,我们会用这家餐厅的日常贯穿全文,从认识标注函数开始,讲透规则模板、覆盖率与准确率、冲突消解、迭代优化,最后把这些环节组装成一条半自动数据流水线。读完你会发现,弱监督不是魔法,而是一套“用经验换成本”的工程艺术。

岗位关联

掌握标注函数设计,你就能在没有充足人工标注的条件下,依然快速搭建高质量训练数据集,这是数据工程岗位的核心竞争力,也是降本增效的实战利器。

目录
  1. 可视化演示
  2. 标注函数基础
  3. 模板函数设计
  4. 覆盖与准确率
  5. 标签冲突消解
  6. 迭代优化流程
  7. 半自动标注管线
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

三步展示弱监督标注函数pipeline:函数类型与数据流、覆盖率与冲突处理、标签聚合与生成式去噪模型。

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

标注函数类型与数据流 KW关键词规则:检查文本含特定关键词 REG正则匹配:模式提取结构化标签 DS远程监督:知识库对齐自动标注 LF(x)→label∈{−1,0,1} 三种函数将专家知识编码为程序化规则批量生成噪声标签。

标注函数基础

想象你现在管理一家连锁餐厅,为了保证每一家分店出品稳定,你决定不再依赖主厨逐道品尝,而是把“什么算一道合格的菜”写成几条固定的检查规则:宫保鸡丁必须见到花生米,麻婆豆腐必须够麻够辣,一道菜看不出主料就要打回。每一条规则都不复杂,恰恰是这种朴素规则,成为整个弱监督体系的基石。

在机器学习的数据标注与管理中,这些规则就是“标注函数”(Labeling Function,简称 LF)。一个标注函数接收一条未标注的数据 x,返回一个“倾向性标签”,返回值只有三个:+1 表示“我倾向于这是正样本”,-1 表示“我倾向于这是负样本”,0 表示“这条规则拿不准,弃权”。多个标注函数组成一个“规则集合”,像一组各持己见的试吃员。

为什么这是弱监督的核心?传统监督学习要求每条数据都有人工标签,而弱监督用大量便宜的规则代替昂贵的人力,先给所有数据粗略打标,再用聚合步骤把噪声消掉。标注函数天然是启发式规则:它不一定每一条都正确,但每一条都携带了领域经验。在设计时,一条规则命中一种可解释的模式,比如“出现'退款'就倾向投诉类工单”,这比一个黑箱模型更容易被检验和迭代。

Λj(x)∈{−1,0,+1}\displaystyle \Lambda_j(x) \in \{-1, 0, +1\}

1. Λ(lambda):希腊大写字母 lambda,这里表示一条标注函数,也就是后厨里的一条试吃规则。

Λj\Lambda_j

2. 下标 j:规则的编号,如主厨A、主厨B、主厨C,对应第 j 条具体规则。

j∈{1,2,…,m}j \in \{1, 2, \dots, m\}

3. x:一条输入样本,比如一份宫保鸡丁的出品描述文本,或任意一条待标注数据。

x∈Xx \in X

4. {-1, 0, +1} 三值集合:输出被限制在三个值中,+1 表示正例倾向,-1 表示负例倾向,0 表示弃权;LF 不允许输出 2 或 0.5 这类模糊值,这是它与普通打分函数最本质的区别。

Λj(x)=1或−1或0\Lambda_j(x) = 1 \quad \text{或} \quad -1 \quad \text{或} \quad 0

回到餐厅的比喻:每条试吃规则都只回答一个简单问题——“这条菜够不够格?”它可能看走眼,但至少给了方向。几十条这样的规则放在一起,就构成了弱监督系统的“经验库”,这正是后续所有聚合与优化动作的起点。

模板函数设计

餐厅里每位试吃员的特长不一样:有人擅长认食材,一眼就能看出有没有花生;有人擅长看摆盘,能从描述文字的格式里读出信息;还有人手边有一本厚厚的“食材档案册”,随手一翻就能查表。设计标注函数也是同样的道理——围绕不同数据形态,形成了若干可复用的模板。

最常用的模板是关键词匹配:数据文本中命中某个词,就给出一个倾向。例如文本中出现“退款”,就倾向标记为投诉工单。更复杂一点的是正则表达式,它不止匹配一个词,而是匹配一套模式,比如“13 位手机号”“订单号 ZX 开头加 8 位数字”这种模式,用正则表达式可以精准取值。此外还有知识库查询:把黑名单词库、领域词典、地理信息表等外部数据引入,命中即触发;以及模型辅助:复用已经训练好的小模型或外部 API 的输出,把模型的预测当作一个新的“试吃员”。

在实际部署中,这些模板常常互相叠加。比如判断一条菜品评价是否合格,“主料缺失”用关键词,而“疑似过火”可能用正则匹配“焦|糊”这类字眼。为了让模板组合更可控,工程师通常会给每个关键词设计权重,再用加权求和的方式把多条规则的判断合成一个分数。下面这个公式就是关键词匹配模板的典型打分方式:

score(x)=∑k1(tk∈x)⋅wk\displaystyle \text{score}(x) = \sum_{k} \mathbb{1}(t_k \in x) \cdot w_k

1. 特征词 \(t_k\):第 k 个我们关注的关键词,如“花生”、“辣”、“退款”。

tk∈{’花生’,’辣’,’退款’,… }t_k \in \{ \text{'花生'}, \text{'辣'}, \text{'退款'}, \dots \}

2. 指示函数 \(\mathbb{1}(\cdot)\):括号内条件成立取 1,不成立取 0。这个词出现了,就贡献一份力量;没出现,就完全沉默。

1(tk∈x)=1当且仅当tk∈x\mathbb{1}(t_k \in x) = 1 \quad \text{当且仅当} \quad t_k \in x

3. 权重 \(w_k\):这个词对标签的“话语权”,正权重把分数推向正例,负权重把分数推向负例,权重绝对值越大越有影响力。

wk∈Rw_k \in \mathbb{R}

4. 求和 \(\sum\):把所有命中词的贡献累加,最终 score 大于 0 则取正标签,小于 0 取负标签,等于 0 则弃权。

score(x)=wa+wb+wc+…\text{score}(x) = w_{a} + w_{b} + w_{c} + \dots

回到餐厅:关键词模板就像“看到花生就给宫保鸡丁加一分”,正则模板像“只要描述里有 13 位数字就怀疑是订餐电话”,知识库模板则像掏出食材档案核对产地。设计标注函数时,优先选模板,把领域知识翻译成这些可解释、可复用的“试吃动作”,就能快速建起一个初版规则库。

覆盖与准确率

规则库搭起来了,你却发现另一个麻烦:主厨写的规则有的太严,比如“必须见到花生米”只对宫保鸡丁有效,其他菜全部弃权,导致大量菜品无人评审;有的又太松,比如“有点辣就合格”,结果把大量不该合格的菜也放过了。这就是标注函数设计的核心矛盾——覆盖率与准确率之间的跷跷板。

覆盖率衡量的是:所有待标注数据中,有多少比例至少被一条规则“接住”(也就是没被全部弃权)。准确率衡量的则是:被接住的那部分数据里,规则给出的倾向到底靠不靠谱。二者往往不可兼得:规则越宽,覆盖率高但误判多;规则越窄,准确率高但大量数据没人管。评估一条规则好不好,不能只看它自己,还要看它在整个数据集上的覆盖表现。

在实际工程中,覆盖率是第一个要监控的指标。如果覆盖率为 60%,意味着剩下 40% 的数据无法自动标注,只能走人工或放弃。围绕覆盖率,还需要同时记录冲突比率——有多少数据同时被正负方向的规则命中,冲突率越高,说明规则之间越缺乏一致性,聚合阶段的压力也越大。

coverage=∣{x∈D:Λ(x)≠0}∣∣D∣\displaystyle \text{coverage} = \frac{|\{x \in D : \Lambda(x) \neq 0\}|}{|D|}

1. 数据集 D:全部待标注数据集合,就像餐厅今天需要评审的所有菜品。

D={x1,x2,…,xN}D = \{x_1, x_2, \dots, x_N\}

2. 条件 \(\Lambda(x) \neq 0\):表示至少有一条标注函数在这个样本上没有弃权,也就是这条数据被规则集合“接住”了。

Λ(x)=max⁡j∣Λj(x)∣≠0\Lambda(x) = \max_j |\Lambda_j(x)| \neq 0

3. 集合基数 \(|\cdot|\):统计满足条件的样本个数。分子算出“被覆盖的样本数”,分母是总样本数。

∣{x∈D:Λ(x)≠0}∣|\{x \in D : \Lambda(x) \neq 0\}|

4. 比值:两者相除得到 0 到 1 之间的覆盖率。覆盖率为 0.8,就说明 80% 的数据可以走自动标注。

0≤coverage≤10 \leq \text{coverage} \leq 1

回到餐厅的场景:覆盖率就是“今天有多少菜能被试吃规则评审”,准确率则是“评审出来的合格/不合格,到底有多少是对的”。好的规则库设计,不是追求单条规则 100% 正确,而是让整个规则集合覆盖更多菜品,同时保持整体评审可信。为此,需要用一个小规模人工精标集来当“裁判”,持续称量这个跷跷板。

标签冲突消解

餐厅里最热闹的时刻,是三位试吃员吵起来了:主厨 A 看到花生,说这菜合格;主厨 B 尝了一口,觉得辣度不够,说退回;主厨 C 犹豫半天,干脆弃权。同一道菜,三个意见互不相同,到底听谁的?这就是标注函数设计里最经典的“标签冲突”问题。

最简单的消解策略是多数投票:把每条规则的输出相加,正票多于负票就取正标签,负票多就取负标签,恰好打平则视为“低置信”,送去人工复核。多数投票虽然朴素,但理论保证很强——只要各条规则的错误互相独立,规则越多,投票结果越可靠。进一步可以引入加权表决:给那些历史上更准确的规则更高的权重,让“资深试吃员”有更大的话语权。

更高级的做法是用生成模型来聚合。这类模型把每条规则看成一个“带噪的标注器”,通过观察它们在不同数据上的输出模式,估计出每条规则的准确率和倾向性,再反过来计算每个样本是正例的概率。这种方法的优势在于:它不把投票当平权,而是真的学会“谁更可靠”。最终,聚合器还会输出一个置信度分数,低置信度的样本专门留给人工处理。

y^=sign⁡(∑j=1mΛj(x))\displaystyle \hat{y} = \operatorname{sign}\left(\sum_{j=1}^{m} \Lambda_j(x)\right)

1. 求和 \(\sum_{j=1}^{m}\):把 m 位试吃员的意见全部相加。+1 是赞成,-1 是反对,0 是弃权。

∑j=1mΛj(x)=Λ1(x)+Λ2(x)+⋯+Λm(x)\sum_{j=1}^{m} \Lambda_j(x) = \Lambda_1(x) + \Lambda_2(x) + \cdots + \Lambda_m(x)

2. 符号函数 sign:输入为正数取 +1,为负数取 -1,恰好为 0 取 0。

sign⁡(z)={+1z>0−1z<00z=0\operatorname{sign}(z) = \begin{cases} +1 & z > 0\\ -1 & z < 0\\ 0 & z = 0 \end{cases}

3. 最终标签 \(\hat{y}\):聚合结果,即多数表决后的弱标签,对应最终写在数据上的“合格/退回/复核”。

y^∈{−1,0,+1}\hat{y} \in \{-1, 0, +1\}

加权表决的公式也很好理解:给每条规则乘以权重 \(w_j\),就相当于有些试吃员一票顶两票:

y^=sign⁡(∑j=1mwjΛj(x))\displaystyle \hat{y} = \operatorname{sign}\left(\sum_{j=1}^{m} w_j \Lambda_j(x)\right)

回到餐厅:多数投票就像“举手表决”,加权表决则是“让最有经验的主厨拥有更高票权”,而生成模型相当于在后台偷偷观察各位试吃员的历史战绩,自动调整他们的发言权。冲突并不可怕,它是信息,是规则库迭代的信号灯。

迭代优化流程

规则库不是写一次就能一劳永逸的。餐厅每周都会挑几道“样板菜”,请主厨亲自品尝并给出标准答案,再用这些标准答案去检验试吃员们的表现——哪条规则误判最多,哪条规则覆盖太窄,一目了然。这就是弱监督工程中最重要的迭代循环。

迭代的起点是错误分析。拿出金标集(人工精标的小样本),把聚合结果和人工标签逐条对比,找出系统性错误:是某条规则太激进,总是给出错误的正标签?还是规则之间相互冲突,导致原本正确的信号被抵消?经验表明,多数低质量规则库的问题不是“规则太少”,而是“规则太宽”。定位到具体问题规则后,进入第二步:增补或修改标注函数。可以收紧某个关键词的权重,也可以增加一条更精确的规则来覆盖之前漏掉的样本。

迭代的第三步是参数调优,包括调整投票阈值、规则权重、弃权判定标准等。最后一步是设“质量护栏”:在每次改动后用同一套金标集重新评估,只有整体准确率和覆盖率都达到预设阈值的改动才被保留。这个流程需要循环执行,直到指标稳定。

accagg=1∣G∣∑x∈G1(y^(x)=y∗(x))\displaystyle \text{acc}_{\text{agg}} = \frac{1}{|G|} \sum_{x \in G} \mathbb{1}(\hat{y}(x) = y^{*}(x))

1. 金标集 G:一小批由领域专家人工标注、可信度极高的样本,只用来做评估,不参与规则生成。

G={(x1,y1∗),(x2,y2∗),… }G = \{(x_1, y_1^{*}), (x_2, y_2^{*}), \dots\}

2. 真值标签 \(y^{*}(x)\):专家给出的人工答案,是判断对错的唯一依据。

y∗(x)∈{−1,+1}y^{*}(x) \in \{-1, +1\}

3. 指示函数 \(\mathbb{1}(\hat{y}(x) = y^{*}(x))\):聚合标签与人工标签一致记 1,不一致记 0,从而统计出“多少样本被正确标注”。

1(matches)=1matcheselse0\mathbb{1}(\text{matches}) = 1 \quad \text{matches} \quad \text{else} \quad 0

4. 平均 \(\frac{1}{|G|}\sum\):把所有样本的正确率取平均,得到聚合器在金标集上的整体准确率。

accagg∈[0,1]\text{acc}_{\text{agg}} \in [0, 1]

回到餐厅的比喻:金标集就是“主厨亲自品尝过的样板菜”,每次改动试吃规则后都要重新上桌对比。一个成熟的弱监督系统,不是靠一次性灵感,而是靠这样一轮又一轮“分析—修改—评估”的迭代,逐渐逼近人工标注的质量上限。

半自动标注管线

最后一步,是把散落的规则、投票、人工复核组装成一条真正的流水线。餐厅的完整流程变成了这样:菜品从后厨出来 → 试吃员依照规则批量评审 → 几位试吃员意见一致就直接出结果 → 意见相左或信心不足的菜,送到主厨桌前人工复核 → 复核结论再回头优化规则。这条流水线,就是“半自动标注”的典型形态。

在工程实现上,这条管线首先需要一个“数据管线”:定时从数据库、日志或上游数据源抽取未标注数据,批量送入标注函数库执行。接着是“主动学习”环节:聚合模型除了给出标签,还给出置信度,管线自动挑选置信度最低、最让模型困惑的样本优先送人工。这样,有限的人力被集中花在最值得确认的数据上,而不是均匀浪费在所有样本上。

最后是反馈闭环:人工复核的结果不仅用于修正标签,还会回流到规则库和聚合模型中。比如某条规则频繁在人工复核中被推翻,系统就自动降低它的权重。这种“机器批量处理 + 人工关键兜底 + 反馈持续进化”的结构,让标注成本大幅下降,同时质量保持在可接受范围。

x∗=arg⁡max⁡x∈U(1−P(y^∣x))\displaystyle x^{*} = \arg\max_{x \in U} \left(1 - P(\hat{y} \mid x)\right)

1. 未标注集合 U:等待分派的“待评菜品”,是管线中还没有拿到明确标签的数据池。

U={x:x∈D,未标注}U = \{x : x \in D, \text{未标注}\}

2. 置信度 \(P(\hat{y} \mid x)\):聚合模型给出标签时附带的信心分数,越接近 1 越有把握。

P(y^∣x)∈[0,1]P(\hat{y} \mid x) \in [0, 1]

3. 不确定度 \(1 - P\):用 1 减去置信度,得到“困惑程度”,数值越大说明越需要人工介入。

1−P(y^∣x)1 - P(\hat{y} \mid x)

4. argmax:在所有样本中挑出不确定度最大的那一个,这就是主动学习“先审谁”的答案。

x∗=最没把握的那条数据x^{*} = \text{最没把握的那条数据}

回看整条流水线:规则批量打标是“自动”,低置信和冲突样本送人工是“半自动”,复核结果回流优化是“闭环”。标注函数设计从来不止于写几个 if-else,它是一套完整的工程体系——用规则换取规模,用人工守住质量,用反馈持续进化,这就是弱监督与半自动标注留给数据工程最大的礼物。

AI 应用场景

电商客服工单自动分层

阶段:数据标注与管理(训练数据准备)

解决的问题:电商平台每天产生数万条客服工单,需要分成“退款、物流、售后”等类别才能分流处理。传统做法依靠人工逐条阅读后打标,成本高、速度慢,且标准容易漂移。用标注函数设计,可以把老客服的判别经验写成规则:命中“退款”“退货”等关键词,或匹配订单号正则、金额异常模式,就能批量生成弱标签。

具体案例:某电商团队设计了 8 条标注函数,覆盖 70 万条历史工单,覆盖率达到 85%。再用多数投票聚合,剔除掉覆盖不到和低置信的样本,用人工精标 5000 条做质量评估,自动聚合准确率约 87%。这套弱标签数据直接用于训练下游文本分类模型,将原先需要 20 名标注员两周完成的工作压缩到 1 名算法工程师两天完成。

内容风控的垃圾文本识别

阶段:数据审核与风控

解决的问题:社区评论、私信等场景每天新增海量文本,需要识别垃圾广告、恶意引流、色情低俗等风险。纯人工审核不可能覆盖全量,而标注函数可以通过“URL 模式正则、手机号正则、广告黑名单词库、账号历史特征”等模板快速生成风险标签。

具体案例:某社交平台搭建了 12 条标注函数组成的内容风控规则库,对 2000 万条评论批量标注,弱标签覆盖率为 78%。聚合后,系统自动筛出约 12% 的低置信样本送入人工审核,其余样本直接进入风控模型训练。上线后垃圾文本召回率提升了约 40%,而人工审核量相比纯人工时代减少 85%。

医疗文本实体的弱监督标注

阶段:专业领域数据工程

解决的问题:医疗文书中的症状、药物、剂量等实体标注,必须由具备医学背景的专业人员完成,人力稀缺且昂贵。标注函数设计可以用“领域词典 + 正则 + 辅助模型”的组合,给大批未标注文本自动贴标签,让专业标注员只负责审阅和纠错。

具体案例:某医院信息化项目中,团队用药品名词典、剂量模式正则、以及预训练的医学 NER 小模型组成 30 条标注函数,对 10 万份出院小结进行实体弱标注。整体覆盖率达到 82%,人工复核率仅有 20%,最终抽取模型在测试集上的 F1 值达到 0.83,与全人工标注方案训练出的模型相差不到 2 个百分点。

Python 演示

python88 行
import re class LabelingFunction:    """把一个函数包装成带名字的标注函数(LF)。     返回约定:+1 表示正标签,-1 表示负标签,0 表示弃权。    """     def __init__(self, name, fn):        self.name = name        self.fn = fn     def __call__(self, text):        return self.fn(text)  def lf_has_peanut(text):    return 1 if 'peanut' in text else 0  def lf_has_spicy(text):    return 1 if ('spicy' in text or 'numbing' in text) else 0  def lf_no_protein(text):    return -1 if not re.search(r'pork|chicken|fish|spareribs', text) else 0  def lf_tasty_word(text):    return 1 if 'taste' in text else 0  def lf_burnt(text):    return -1 if ('burnt' in text or 'scorch' in text) else 0  LFS = [    LabelingFunction('has_peanut', lf_has_peanut),    LabelingFunction('has_spicy', lf_has_spicy),    LabelingFunction('no_protein', lf_no_protein),    LabelingFunction('tasty_word', lf_tasty_word),    LabelingFunction('burnt', lf_burnt),] DISHES = [    'kung pao chicken, peanut crispy, spicy taste',    'mapo tofu, spicy and numbing',    'stir fried greens, light taste',    'braised pork, soft and tender',    'sweet sour spareribs, tangy sweet',    'boiled fish, oil smells burnt',] GOLD = [1, 1, 1, 1, 1, -1]  def aggregate(votes):    pos = votes.count(1)    neg = votes.count(-1)    if pos > neg:        return 1    if neg > pos:        return -1    return 0  def main():    n_labeled = 0    n_conflict = 0    correct = 0    for dish, gold in zip(DISHES, GOLD):        votes = [lf(dish) for lf in LFS]        label = aggregate(votes)        if votes.count(0) < len(votes):            n_labeled += 1        if votes.count(1) > 0 and votes.count(-1) > 0:            n_conflict += 1        if label == gold:            correct += 1        print('{0:<40} votes={1} label={2} gold={3}'.format(            dish, votes, label, gold))    print('coverage: {:.2f}'.format(n_labeled / len(DISHES)))    print('conflict: {:.2f}'.format(n_conflict / len(DISHES)))    print('accuracy: {:.2f}'.format(correct / len(DISHES)))  if __name__ == '__main__':    main()
目的:用 5 条“菜品规则”对 6 条菜品描述批量生成弱标签,用多数投票聚合,并在金标集上计算覆盖率、冲突率和准确率,带你体验最小化的弱监督标注全流程。
  1. class LabelingFunction:定义标注函数的包装类,给规则起名字、绑定执行函数。
  2. def __call__(self, text):让规则对象可以像 lf(dish) 一样被直接调用,简化批量执行。
  3. LFS = [...]把 5 条规则放进列表,构成规则库,也就是“试吃手册”。
  4. votes = [lf(dish) for lf in LFS]每一条规则对同一条数据各投一票,得到一个投票向量。
  5. if pos > neg: return 1多数表决:正票更多就返回 1,负票更多返回 -1,平局返回 0。
  6. if votes.count(0) < len(votes): n_labeled += 1只要有一条规则没弃权,就算这条数据被覆盖。
  7. if votes.count(1) > 0 and votes.count(-1) > 0: n_conflict += 1正负票同时存在,说明发生了规则冲突。
  8. 'coverage: {:.2f}'.format(...)输出覆盖率、冲突率、准确率三项核心指标,帮助你判断规则库质量。

常见误区

误区写几个 if-else 就能打标签,这东西又不难,逻辑跑通就算完成,后面就不用管了。

正解标注函数是“伪标签生成器”,代码正确不等于规则有效。它会影响下游所有训练数据的质量,因此必须用数据验证:在金标集上计算覆盖率和准确率,检查每条规则是否真的在做贡献。就像试吃规则写错了,会批量误判整批菜品,比人工犯错的影响大得多。

为何常见:因为 LF 在外观上就是普通函数,工程师容易把它等同于一般业务代码,忽略了它作为“数据标签来源”的高风险属性。

误区我的标注函数准确率不到 90%,肯定不能用,还是老老实实人工标注吧。

正解弱监督的精华恰恰在于容忍噪声。多个弱规则加权聚合后,个别规则的错误可以被其他正确规则抵消。只要规则间的错误不是系统性相关的,即使单条规则只有 60% 的准确率,投票聚合之后仍可能达到 85% 以上。判断一个规则库好不好,永远看整体,而不是单看某一条。

为何常见:人们习惯用“人工标注必须高准确率”的思维去衡量规则,忽略了聚合阶段有纠错能力。

误区我写一个大而全的规则,把所有数据都覆盖到,这样完成率就是 100%,多漂亮。

正解覆盖率和准确率是跷跷板。一条过于宽泛的规则通常会误伤大量不相关样本,导致聚合结果噪声极大。真正聪明的设计是接受“部分数据弃权”,让覆盖不到的低置信样本走人工审核路径。弱监督的目标不是 100% 覆盖,而是让“自动标注 + 人工复核”的总成本最低。

为何常见:来自人工标注时代的惯性思维——每条样本都该有个标签;但弱监督中“弃权”本身就是一个合法且重要的决策。

误区两条规则一个说正、一个说负,肯定是规则写错了,我要把冲突全部消灭掉。

正解LF 之间的冲突是宝贵的信息,往往说明数据边界本身很复杂,或者某条规则覆盖范围过宽。可以通过加权投票、生成模型等机制把冲突变为对标签概率的估计,也可以把冲突样本批量送人工复核。强行消除冲突,反而可能把有用的信号一起砍掉。

为何常见:传统程序思维要求逻辑无矛盾,而弱监督本质是“概率性标签”,天然允许不同信号同时存在。

误区标注函数写完跑起来,就是全自动了,不需要任何人再看数据了。

正解弱监督系统是“半自动”而非“全自动”——它大幅减少人工介入,但依然需要人工承担三件事:构建金标集评估质量、复核低置信和冲突样本、持续迭代规则。业务环境变化后,旧规则会失效,如果没有人维护,系统准确率会悄悄滑坡。

为何常见:产品和技术汇报时都喜欢强调“自动”两个字,容易让人忽略弱监督本质上是人机协同,而非彻底替代。

面试题

Q1. 一个标注函数接收一条数据后,返回值属于哪种集合?

单选题 · easy

  • A.真假布尔二值
  • B.三值标签集合← 正确答案
  • C.连续概率数值
  • D.任意浮点数值

答案:B。标注函数输出被限制在 +1、-1、0 三个值,分别表示正例倾向、负例倾向和弃权。布尔值只有真假两态,连续概率和浮点数都会让规则输出变得模糊,违背弱监督“可解释、可投票”的设计原则。

Q2. 标注函数返回 0 的含义是什么?

单选题 · easy

  • A.正类或负类标签
  • B.规则拿不准选择弃权← 正确答案
  • C.数据确实属于中性类
  • D.程序内部报错警告

答案:B。0 不代表数据属于“中性类别”,而是表示这条规则在这条数据上没有把握、主动弃权。这就像一个试吃员尝不出好坏时选择不投票,把决定权交给其他规则或人工复核。

Q3. 弱监督语境下“覆盖率”的定义是?

单选题 · mid

  • A.LF 代码行占全部代码的比例
  • B.至少一条 LF 命中的数据占比← 正确答案
  • C.人工复核样本占总样本比例
  • D.被正确标注的数据占总数据比

答案:B。覆盖率 = 至少有一条标注函数没有弃权的样本数 ÷ 总样本数。它衡量的是规则库“接住”了多少数据。代码行占比和人工复核比例与覆盖率无关,被正确标注的比例则属于准确率范畴,需要在金标集上才能计算。

Q4. 下列哪些属于常见的标注函数设计模板?

多选题 · mid

  • A.关键词匹配与正则表达式← 正确答案
  • B.领域知识库与黑名单查询← 正确答案
  • C.复用预训练模型的预测← 正确答案
  • D.强制要求真值标签参与规则

答案:ABC。关键词匹配、正则表达式、知识库查询、模型辅助是四大经典模板。D 选项的问题在于:弱监督的初衷就是避免依赖真值标签,真值标签只用于评估金标集,不参与规则本身的构建。

Q5. 某数据有 3 条规则投票:+1、+1、0,多数投票的最终结果是?

单选题 · mid

  • A.返回正标签,因为正票数最多← 正确答案
  • B.返回负标签,因为负票数较少
  • C.返回零标签,因为规则间存在冲突
  • D.触发人工复核,等所有规则重投

答案:A。多数投票把各规则输出相加:1+1+0=2,结果为正,符号函数返回 +1。弃权票不参与对抗,因此不需要人工复核。只有当正负票数打平(如 +1、-1、0)时才会返回 0 并触发低置信处理。

Q6. 关于弱监督与人工标注的关系,下列说法正确的是?

多选题 · hard

  • A.弱监督可以完全替代人工标注
  • B.弱监督显著减少人工标注成本← 正确答案
  • C.仍需少量人工核对与迭代← 正确答案
  • D.人工标注在弱监督中无作用

答案:BC。弱监督把大部分数据交给规则自动标注,人工只负责三件事:建金标集做评估、复核低置信样本、持续迭代规则。它把人工成本砍掉大半但不是归零,所以“完全替代”和“毫无作用”都是错误认知。

Q7. 多规则产生严重冲突时,最合理的处理方式是?

单选题 · hard

  • A.删除所有冲突规则保平安
  • B.生成模型估计权重来投票← 正确答案
  • C.随机选取一条规则的输出
  • D.数据量少的规则永远胜出

答案:B。生成模型可以观察规则间的一致性模式,估计出每条规则的可靠度并加权聚合,把冲突转化为概率信号。直接删除规则会丢失信息;随机选取和数据量优先都缺乏统计依据,无法保证聚合质量。

Q8. 出现“覆盖率上升但准确率下降”时,最可能的原因是什么?

单选题 · hard

  • A.增加针对性强的窄规则
  • B.增加宽泛规则误伤大量数据← 正确答案
  • C.删除过多重复冗余规则
  • D.增加对所有样本弃权的规则

答案:B。宽泛规则能覆盖更多数据,让覆盖率上涨,但也会把大量不相关的样本误标,导致准确率下滑。窄规则刚好相反。删除重复规则一般不影响覆盖率;全弃权的规则既不改变覆盖率也不改变准确率。

Q9. 弱监督规则库一次正确的迭代优化顺序是?

单选题 · mid

  • A.直接调参,然后跑全量数据集
  • B.错误分析后增补规则再评估← 正确答案
  • C.先删掉所有规则再重新编写
  • D.先增加数据量,再调整代码

答案:B。正确流程是“错误分析 → 增补/修改 LF → 用金标集评估”,形成一个可反馈的循环。跳过分析直接调参是盲调;推倒重建成本高且不一定更好;增加数据量属于数据侧动作,不是规则迭代的直接步骤。

Q10. 聚合模型给出“低置信度”标签,正确的理解是?

单选题 · easy

  • A.模型对该样本标签不确定← 正确答案
  • B.该样本一定是异常数据
  • C.该样本没有被任何规则覆盖
  • D.该样本不会出现在测试集中

答案:A。低置信度说明各规则意见分歧大或加权后胜出优势微弱,模型对最终标签没有把握,因此优先送人工复核。它不等同于异常数据,也不等同于未覆盖——有些规则全部弃权的样本是高置信“未知”,应单独归类。