层级分类与置信度分类:官方两条分类路线
先说结论
- 层级分类适合类别多、层级深、标签体系有明确上下位关系的场景;它把一次“从根到叶”的分类拆成多步 Choice,逐步缩小候选,但代价是请求次数会随深度增加。
- 置信度分类适合“错判代价不一致”的场景:先做一次分类,再用返回的
confidence决定是自动采用,还是退回到更粗的粒度或转人工。 - 层级分类的贪心版本会放大早期错误,束搜索版本可以部分修复早期歧义;置信度分类通过低置信度降级,可以减少“具体但错”的结果,但不一定提高细粒度准确率。
- 官方两篇 cookbook 都基于 TypeSafe 的
Choice原语,但路线不同:层级分类把每个节点的候选当成一个 Choice,置信度分类只用一次 Choice 并读取其置信度。 - 两者可以叠加:先按层级找到候选节点,再在每个节点做置信度门控,用于风控、合规、复杂工单等场景。
证据与过程
路线一:层级分类,先粗后细
官方 cookbook 对层级分类的定义是:“Classifies documents through deep patent, retail product, biomedical, and source-code hierarchies using parallel beam search over TypeSafe Choice probabilities.”(Hierarchical classification)
也就是说,官方把专利、零售商品、生物医学主题词、源码目录树这类层级结构当作分类对象,目标是从根节点走到正确的叶子节点。官方给出的原始做法是:从根节点开始,在每个节点用 Choice 的概率分布作为该节点的子节点选择依据,然后继续走向概率最高的子节点,直到叶子。这个方法被称为 Greedy Search。
官方还给出了束搜索版本。在束搜索里,系统同时评估 K 条路径,而不是只保留当前最优子节点。官方写明的路径得分公式是:
path_score = product(edge_probabilities) ** (1 / decisions)
该公式用于剪枝和比较不同深度的路径。官方数据中没有给出“唯一正确”的 K 值,只说明束宽 K 是官方方法的一个可调参数。此外,官文还写了一个分离度指标:
separation = top_path_score / second_path_score
官方注明这个指标用于比较最优路径和次优路径的接近程度,但不用于剪枝。
这段内容需要区分两个概念:官方定义的是层级分类的目标和用 Choice 概率沿边往前走的方法;而“每次调用一个子节点”“把每条路径的评分并行发出”等写法,是官方 cookbook 里的实现方式,不是 TypeSafe 平台的强制要求。对于工程实践,用户也可以选择每次只问一个节点,或提前缓存若干层级结果。
路线二:置信度分类,先判该不该自动处理
官方置信度分类 cookbook 的定位是:“Classify SEC annual reports into 75 industry groups with one Choice each, then read the answer’s own confidence to decide whether to report that group or the broader division above it.”(Classification using confidence)
这篇 cookbook 用 SIC 行业分类做例子。它把 SEC 年报中的业务描述分类到 75 个行业组,而不是先走一个层级树。官方数据中写道,SIC 代码文件有 444 个四位代码,按前两位数字聚合后得到 75 个行业组,再按固定区间聚合成 10 个 division。这一步不涉及模型调用,只是由代码直接完成映射。
官方实验数据为:在 60 份年报样本上,如果把 confidence 阈值设为 0.9,则大约一半样本会被判定为高置信,另一半为低置信。高置信样本中,行业组分类准确率为 90%;低置信样本中,行业组准确率仅 40%;如果不报行业组而改报其所属的 division,准确率可提升到 70%。这些数字需要标注为官方数据,来自官方 cookbook 的已发布实验缓存,不是本文独立复现的结果。
需要注意的是,官方原文说的是“Across 60 filings, a confidence cutoff of 0.9 splits them in half.” 这里 0.9 是他们在一个具体数据集上展示的切分点,不是平台层面的默认推荐阈值。官方 Confidence 页面也明确写道:“The correct threshold values depend on your domain and the performance of the model for your use case.” 所以 0.9 只是一个实验例子。
官方原语:Choice 返回什么
层级分类和置信度分类都依赖 Choice。根据官方 Primitives 文档,Choice 回答“Which of these options?”,返回 choice、probabilities、confidence 三个字段(Primitives (Questions))。这解释了为什么两条路线都能拿到概率分布和置信度:
- 层级分类主要使用
probabilities作为边的权重; - 置信度分类主要使用
confidence作为门控变量。
官方 Confidence 文档进一步解释,confidence 是从概率分布计算出的一个 0 到 1 的单值(Confidence)。但官方没有公布该统计量的具体公式,因此不能把 confidence 当成简单的 top-1 概率。它是平台返回的一个现成数值,用户可以直接用于阈值判断。
对照表:适用场景、请求成本、错误传播、可解释性
| 维度 | 层级分类 | 置信度分类 |
|---|---|---|
| 适用场景 | 类别总数多,且大类之间语义边界较清楚;需要保留层级路径和节点统计 | 类别数中等、通常是单层多选;错判代价不同,需要引入人工复核或粗粒度回退 |
| 请求次数与成本 | 与树的深度和束宽成比例;束搜索会增加并发请求数,但官方称并行设计对墙钟时间影响不大 | 通常每个文档一次请求,成本较低;粗粒度回退不需要第二次模型调用 |
| 错误传播方式 | 贪心版本:早期选错子节点,后续会一路走到错误叶子;束搜索:多条路径并行,深层的证据有机会修正早期歧义 | 低置信时直接降级到较粗标签,避免输出过于具体的错误;但如果 ground truth 本身就是细粒度,提升的是“不犯错”的比例,而不是“更精确”的比例 |
| 可解释性 | 路径天然可解释:从根到叶的节点序列就是分类依据;官方还提到能观测哪些节点误分类最多 | 解释性主要是 confidence 数值和概率分布;若退回 division,用户只能看到“为什么不够自信”,看不到具体是哪个行业组更可能 |
上表是根据官方 cookbook 的描述整理的对比判断,不代表官方推荐。尤其“请求次数与成本”一栏中,关于成本随深度和束宽线性增加的推断,属于自己推算,官方两篇 cookbook 没有给出具体价格或 token 成本。层级分类官方只提到“extra exploration adds little wall-clock latency”,即并行探索对墙钟时间增加不大。
两段最小请求骨架
下面是基于官方示例精简的请求骨架。字段来源已在注释中标注:官方字段是 TypeSafe SDK 中 Choice 的 instructions、criteria 以及返回的 choice、probabilities、confidence;业务字段是本文为了说明路线加上的输入文本、阈值和向上映射函数。
层级分类路线(单层示意,可循环扩展)
from typesafe_sdk import Choice, TypeSafeClient
client = TypeSafeClient(api_key="...") # 官方客户端用法
# 官方字段:Choice、instructions、criteria
questions = {
"top_level": Choice(
instructions="Which top-level category does the document belong to?",
criteria={
"section_a": "human necessities",
"section_b": "operations and transporting",
"section_c": "chemistry and metallurgy",
},
),
}
resp = client.system_one(state=document_text, questions=questions)
answer = resp.answers["top_level"]
# 官方返回字段:choice, probabilities, confidence
# 业务字段:把最高概率的 candidate 作为下一层节点,递归或束搜索
next_node = answer.choice
print(answer.probabilities) # 官方字段,可拿到完整边概率
置信度分类路线(一次 Choice + 阈值门控)
from typesafe_sdk import Choice, TypeSafeClient
client = TypeSafeClient(api_key="...") # 官方客户端用法
# 官方字段:Choice、instructions、criteria
questions = {
"sic_group": Choice(
instructions="Which SIC industry group best fits the company's business description?",
criteria={
"60": "depository institutions",
"61": "non-depository credit institutions",
"62": "security and commodity brokers",
},
),
}
resp = client.system_one(state=company_business_text, questions=questions)
answer = resp.answers["sic_group"]
confidence = answer.confidence # 官方返回字段
threshold = 0.9 # 业务字段:阈值来自官方 cookbook 实验,非平台默认
if confidence >= threshold:
label = answer.choice # 官方返回字段
specificity = "group" # 业务字段
else:
label = division_of(answer.choice) # 业务函数:把行业组映射到 division
specificity = "division"
print(label, specificity, confidence)
我的判断与落地清单
如果让我给一条默认建议,我会这样分:
- 标签超过 20 个、且大类之间语义边界清楚时,优先考虑层级分类。 层级分类能把一次高难度选择拆成多次低难度选择,而且每一层都能输出可观测的中间路径,这对后续误差分析和标签体系维护很有用。
- 风控、合规、财务、医疗等“错判代价高”的场景,优先考虑置信度分类。 在这些场景里,宁可给一个较粗但可靠的标签,也不要给一个具体但可能错的标签。置信度路线用一次请求就能区分“放心自动处理”和“需要人工介入”。
- 两者可以叠加。 例如先按层级走到某个业务大类,再在该节点内做置信度门控;如果置信度不够,就不继续往下走,而是直接输出当前大类并转人工。这样同时得到层级可解释性和风险控制能力。
- 不要直接照搬 0.9 阈值。 官方 Confidence 页也提示阈值应按业务风险和实际数据调整。我建议从小样本标定开始,先用 0.8、0.9、0.95 三档观察误判率和人工介入率,再固定为一个可解释的运营指标。
- 成本管理上,层级分类不一定比置信度分类便宜。 如果层级较深且束宽很大,请求总数会上升。不过官方束搜索用并行问题降低墙钟时间,这更适合对延迟敏感、对并发成本不敏感的系统。
这次没核实的
confidence的具体统计公式:官方 Confidence 文档只说它是从概率分布计算出的单值,没有公布公式,无法核实它是否等同于 entropy、top1 概率或其他统计量。- 层级分类 cookbook 中四种层级源的具体节点数与版本号细节:在抓取到的片段里能看到 CPC、Shopify、MeSH、CookSafe files,但节点数量、层数等数据在截断处没有完全展示,本文不写具体数字。
- 官方是否对“束宽 K 取多少”有推荐值:未在抓取的官方页面里找到明确建议,因此不能把任何 K 值写成官方推荐。
- API 调用成本或价格:官方文档没有给出每千次调用或每 token 的价格,本文也没有任何价格推断,只做定性成本对比。
参考来源
评论区
登录后可评论。