PAYATHON 2026

如何设计并验证 Prada 的 context disambiguation 方案?

技术老齐

建议先建立小规模人工标注集和规则基线,再决定是否引入 bootstrapping 或 active learning。无需给全部帖子打标签,但要有一批独立且具有代表性的人工标注样本,用来评估结果质量。规则覆盖率、模型置信度和伪标签数量都不能替代人工评估。

对于 Prada 这类已经通过关键词召回的数据,可以直接把任务定义为上下文相关性分类:根据帖子及可用上下文,判断它是否在讨论目标品牌。知识库和 NER 可以提供特征,无需把它们作为整个方案的前提。

先定义什么算“与 Prada 品牌相关”

先确定分类单位是整篇帖子,还是其中某一次“Prada”提及,这会直接影响标注和评估。如果目标是筛选品牌相关帖子,可以采用以下口径:

标签判定标准示例或处理方式
相关内容实质讨论 Prada 品牌、产品或品牌比较购买体验、产品评价、与其他品牌比较
不相关Prada 只出现在其他含义中人名、与品牌无关的文字游戏、仅讨论同名作品
无法判断现有上下文不足以确定只有一个词、缺失正文或依赖未提供的图片

不宜因为出现 The Devil Wears Prada 就排除整条帖子。只讨论电影、小说或乐队时,可以按业务口径标为不相关;如果帖子借作品名称讨论 Prada 的产品或品牌,仍可能相关。

竞争品牌名称也只能提供线索,不能单独证明帖子与 Prada 相关。prada me 同样需要结合上下文判断,不能仅凭字符串匹配确定语义。

如果一篇帖子同时讨论作品和品牌,需要提前规定保留条件:只要有实质性的品牌讨论就保留,还是必须以品牌为主要话题。两种口径都可以,训练和评估时要保持一致。

把正负词表写成允许弃权的规则

你计划整理的 positive labels 和 negative labels,可以作为正负线索或弱监督规则使用。它们产生的是候选标签,尚未经过人工确认。

每条规则最好输出:

  • 1:支持品牌相关。
  • 0:支持品牌无关。
  • ABSTAIN:证据不足,暂不判断。

例如,明确描述购买 Prada 商品的句子可以提供正向证据;明确讨论作品剧情且没有品牌讨论的内容,可以提供负向证据。如果只有一个竞争品牌名称、正负线索同时出现,或文本太短,应允许规则弃权。

记录规则的命中原因,便于检查错误。来自同一词表的几条相似规则,不能简单算作几份独立证据,否则多数投票可能只是在重复计算同一种偏差。

把规则输出用于训练之前,先抽查各条规则命中的样本,确认精确率和常见误判。

用少量人工数据建立可靠的评估集

没有完整的标注数据集,也可以开展评估,但需要注意抽样方式,并保证评估数据独立。

从目标数据中随机抽样

从实际要处理的 Prada 检索结果中随机抽取样本,保留自然的正负比例。不要只标注明显命中规则的帖子,否则评估会漏掉规则未覆盖的表达。

可以先标注几百条,了解类别分布和常见歧义,再根据置信区间决定是否扩大样本。这只是起步时的数量建议,不保证足以验证某个质量目标。如果相关帖子很少,随机样本中的正例可能不足以稳定估计 recall。

对于罕见但重要的用法,可以另建挑战集,例如:

  • 作品名称与品牌讨论混合出现;
  • 人名、谐音和拼写变体;
  • 极短文本或依赖上下文的帖子;
  • 竞争品牌与作品名称同时出现。

挑战集可以帮助发现薄弱点,但其中的类别比例经过人为调整,不能直接代表整体效果。如果用分层抽样估计总体指标,需要按各层在总体中的比例加权。

检查人工标签本身是否可靠

请两位标注者独立标注一部分相同的样本,再讨论分歧,修订标注指南。除了报告原始一致率和 Cohen’s kappa,还应说明分歧集中在哪些情形。“作品讨论是否算品牌相关”这样的口径问题,无法靠一个一致性数值解释清楚。

对于“无法判断”的样本,应单独记录数量、原因和后续处理方式。如果评估时排除了这些样本,需要明确说明指标只适用于可判定样本。

保持测试集独立

用于编写规则、选择特征和调整阈值的样本都属于开发数据。最终测试集应留到方案确定后使用,不能用于伪标签训练,也不能进入 active learning 的选样池。

划分数据时,应把重复帖子、近重复文本,以及需要共同处理的同一讨论线程放在同一分组中。否则,训练集和测试集可能出现几乎相同的内容,使评估结果偏高。

如果系统将用于未来数据,最好再保留一个较晚时间段的测试集,检查新梗和话题变化的影响。

先比较简单方案,再增加训练复杂度

建议按以下顺序推进:

方案用途主要检查点
全部保留基线,表示关键词召回后不做过滤当前数据中无关内容占多少
人工规则建立可解释的筛选基线规则精确率、覆盖率和冲突情况
少量人工标签训练分类器判断简单模型是否已够用与规则相比是否减少漏判和误判
弱监督或 bootstrapping利用未标注数据扩充训练信号增益是否稳定,伪标签是否引入偏差

简单分类器可以先尝试词级、字符级 TF-IDF 配合线性模型。由于所有数据都由“Prada”召回,模型需要学习的是周围语境,预处理时应保留作品名称、短语和拼写特征。

Active learning 可以用于人工标注环节:优先选出模型不确定、规则冲突或尚未覆盖的样本,交给人工标注,再重新训练。它是一种选样策略,并不自动等同于半监督学习。同时保留一部分随机抽样,可以减少只关注当前模型已知难例带来的偏差。

Bootstrapping 可以晚一些再用。每轮只引入经过开发集验证的高置信预测,限制新增数量,并抽查伪标签。如果开发集上的表现下降,就停止扩充或回退。预测分数高,不代表标签一定正确。

质量要用哪些指标说明

如果目标是获得干净的品牌讨论数据,应优先关注 precision;如果遗漏品牌讨论会影响分析,还需要同时看 recall。

[ \mathrm{Precision}=\frac{TP}{TP+FP} ]

[ \mathrm{Recall}=\frac{TP}{TP+FN} ]

其中,TP 是正确保留的相关帖子,FP 是错误保留的无关帖子,FN 是遗漏的相关帖子。

建议报告:

  • precision、recall、F1 和混淆矩阵;
  • 指标的置信区间及对应样本数;
  • 自动判定覆盖率、弃权率和人工复核比例;
  • 作品名称、人名、谐音等主要错误类型。

如果系统允许弃权,需要分别评估自动判定部分和整个流程的质量。只报告自动保留帖子的 precision,无法说明有多少相关帖子被排除,或仍在等待人工复核。

阈值应根据业务成本在开发集上选择。例如,先约定可接受的 precision 要求,再比较满足要求的候选阈值对应的 recall 和人工复核量。最终测试集只用于检验选定方案。

Python 示例:计算指标与置信区间

以下代码只使用 Python 标准库,适用于等概率随机抽取、人工标签已确认且预测结果为二分类的测试样本。它计算 precision、recall、F1,以及 precision 和 recall 的 Wilson 95% 置信区间。

from math import sqrt


def wilson_interval(successes, total, z=1.959963984540054):
    if total == 0:
        return None

    p = successes / total
    denominator = 1 + z * z / total
    center = (p + z * z / (2 * total)) / denominator
    margin = (
        z
        * sqrt(p * (1 - p) / total + z * z / (4 * total**2))
        / denominator
    )
    return center - margin, center + margin


def evaluate(y_true, y_pred):
    if len(y_true) != len(y_pred) or len(y_true) == 0:
        raise ValueError("Inputs must be non-empty and have equal length.")

    if any(x not in (0, 1) for x in [*y_true, *y_pred]):
        raise ValueError("Labels must be 0 or 1; resolve abstentions first.")

    tp = sum(t == 1 and p == 1 for t, p in zip(y_true, y_pred))
    fp = sum(t == 0 and p == 1 for t, p in zip(y_true, y_pred))
    fn = sum(t == 1 and p == 0 for t, p in zip(y_true, y_pred))
    tn = sum(t == 0 and p == 0 for t, p in zip(y_true, y_pred))

    precision = tp / (tp + fp) if tp + fp else None
    recall = tp / (tp + fn) if tp + fn else None
    f1 = 2 * tp / (2 * tp + fp + fn) if 2 * tp + fp + fn else None

    return {
        "n": len(y_true),
        "confusion_matrix": {"tp": tp, "fp": fp, "fn": fn, "tn": tn},
        "precision": precision,
        "precision_ci95": wilson_interval(tp, tp + fp),
        "recall": recall,
        "recall_ci95": wilson_interval(tp, tp + fn),
        "f1": f1,
    }

将人工确认的标签作为 y_true,方案冻结后的预测结果作为 y_pred。不要把规则生成的标签当作 y_true,否则测到的只是模型与规则的一致程度。

使用代码前需要先处理弃权。可以评估人工复核后的最终结果,也可以单独评估自动判定的子集;选择后者时,必须同时报告覆盖率。分层加权样本不能直接套用这段代码估计总体指标。如果样本存在明显的线程相关性,还应采用按线程分组的区间估计方法。

如何为方法的合理性提供依据

固定标注口径,在同一个独立测试集上比较规则、简单分类器和加入 bootstrapping 后的结果,并记录各方案使用的人工标签数量与复核成本,让对比和误差分析可以复查。

要验证伪标签是否有用,应在相同的人工标注预算下,对比“仅用人工标签”和“人工标签加伪标签”的效果。验证某组规则时,可以移除这组规则后重新评估,检查结果变化及其不确定性。数据有限时,微小差异不足以支持明确的优劣结论。

最终交付应包括抽样方式、标注指南、测试集规模、指标及置信区间、典型错误和适用范围。如果只测试了 Reddit 帖子,结论就应限定在对应的数据来源和时间范围内。规则或语言用法发生变化后,需要重新抽样复核。

完全没有人工确认的样本时,可以描述规则覆盖率和系统内部一致性,但无法据此可靠地声称系统达到了某个 precision 或 recall。

备注:内容仅供参考。