AI 评测集按样本标签拆分结果的统计方案
来源:17golang原创
时间:2026-11-13 15:15:09 324浏览 收藏
我在看一批模型评测结果时,最容易误判的不是准确率公式,而是把“整体准确率”当成了所有样本类型都表现一致。更稳妥的做法是把每条结果保留为一行,明确记录评测集分片、样本标签和是否答对,再按 split + label 聚合。
官方地址:https://huggingface.co/docs/transformers/
按样本标签拆分统计时,至少输出每组的样本数、正确数和准确率;最终报告再同时给出按样本数加权的整体准确率与各标签准确率的宏平均。没有分母的分数,不足以判断某个标签真的更好或更差。
先把评测结果整理成可统计的行
如果使用 Hugging Face Transformers 的评测流程,compute_metrics 会接收预测与标签并返回指标。本文不把指标回调当成唯一存储点,而是建议在回调之外保留一份行式结果。最小字段可以是:
| 字段 | 示例 | 用途 |
|---|---|---|
split | validation | 区分评测集分片 |
label | 长文本 | 样本本身的业务或难度标签 |
correct | true | 统一为是否答对 |
score | 0.84 | 可选的连续评分,不替代 correct |
这里的 label 是“样本标签”,不是模型预测类别。两者混在同一列里,后面的分组表会失去解释力。

按 split 和样本标签得到分组计数
先统计分母,再计算比率。这样即使某个标签只有很少样本,报告也会把这个事实显式展示出来,而不是只留下一个看似精确的小数。
from collections import defaultdict
import json
def load_rows(path):
# 每行是一条已经完成模型评测的记录;空行直接跳过,避免产生幽灵样本。
with open(path, "r", encoding="utf-8") as source:
for line_no, line in enumerate(source, start=1):
if not line.strip():
continue
row = json.loads(line)
# 用行号补足缺失 id,便于回溯坏数据,但不改变原始标签。
row.setdefault("id", f"line-{line_no}")
yield row
def summarize(rows):
groups = defaultdict(lambda: {"n": 0, "correct": 0})
unknown = []
for row in rows:
split = row.get("split") or "unknown-split"
label = row.get("label") or "unknown-label"
# correct 必须是布尔语义;缺失值进入异常清单,不悄悄按答错处理。
if not isinstance(row.get("correct"), bool):
unknown.append(row.get("id"))
continue
bucket = groups[(split, label)]
bucket["n"] += 1
bucket["correct"] += int(row["correct"])
report = []
for (split, label), value in sorted(groups.items()):
n = value["n"]
report.append({
"split": split,
"label": label,
"n": n,
"correct": value["correct"],
"accuracy": round(value["correct"] / n, 4),
})
return {"groups": report, "invalid_ids": unknown}
result = summarize(load_rows("eval-results.jsonl"))
print(json.dumps(result, ensure_ascii=False, indent=2))
这段代码的关键不是 round,而是同时保存 n 与 correct。建议把 invalid_ids 当作报告的一部分:如果把缺失字段直接记成 false,整体准确率会被数据质量问题拉低,却很难分清模型问题和输入问题。
把整体准确率和标签宏平均分开
同一张表里可以同时有两种视角。整体准确率是所有样本的正确数除以总样本数,样本多的标签权重更大;宏平均则先求每个标签的准确率,再对标签做等权平均。前者回答“这批数据整体答对多少”,后者更接近“各类样本是否都被照顾到”。
def aggregate_metrics(group_rows):
# 只对同一个 split 的分组行做汇总,避免 validation 和 test 互相稀释。
total_n = sum(item["n"] for item in group_rows)
total_correct = sum(item["correct"] for item in group_rows)
label_scores = [item["accuracy"] for item in group_rows if item["n"] > 0]
# 没有有效分组时返回 None,调用方可以把它标记为“无数据”而非 0 分。
overall = round(total_correct / total_n, 4) if total_n else None
macro = round(sum(label_scores) / len(label_scores), 4) if label_scores else None
return {
"n": total_n,
"correct": total_correct,
"overall_accuracy": overall,
"label_macro_accuracy": macro,
}
例如两个标签分别有 95%(100 条)和 60%(10 条),整体准确率约为 91.8%,宏平均却是 77.5%。这不是两个公式谁“更正确”,而是它们回答不同问题。产品上线门槛通常需要预先决定采用哪一个,不能看到结果后再挑更好看的数字。

小样本、缺失标签和重复样本要单独处理
按标签拆分后,最值得关注的往往是数据边界。第一,给每组输出 n,并为低于团队最低样本量的组加标记;小组的准确率可以保留,但不要把它写成稳定结论。第二,把空标签统一为 unknown-label 并单列数量,等确认上游字段后再决定是否纳入总分。第三,重复样本要在统计前按稳定的样本 ID 去重,否则同一条题目被多次评测会放大它的权重。
如果样本是多标签的,不要直接把数组转成逗号拼接字符串后分组。应先约定统计口径:按主标签统计,还是把一条样本展开到多个标签并在报告中明确“样本可重复计数”。这两种结果不能混在同一张单标签表里。
建议把统计结果做成版本化报告
我最后会把四类信息一起保存:输入字段契约、模型与评测配置、每个 split + label 的分组表、异常与口径说明。Hugging Face 的评测接口可以负责产出任务指标,但标签统计的分组规则仍应由项目自己的报告代码固定下来。这样下次换模型、换数据或重新抽样时,差异来自明确的输入变化,而不是隐藏在临时 Notebook 里。
| 报告项 | 至少包含 |
|---|---|
| 分组行 | split、label、n、correct、accuracy |
| 整体汇总 | 总样本、总正确、overall accuracy |
| 公平观察 | 标签宏平均、最低样本量、最低标签分数 |
| 异常说明 | 缺失标签、非法 correct、重复 ID |
相关问题
整体准确率很高,还要看标签拆分吗?
要看。整体值可能被大样本标签主导,至少应查看样本量和每个标签的准确率。
标签样本数很少时应该删除吗?
不建议静默删除。保留分组并标记低样本,等补充数据或改变结论表述。
标签统计能替代混淆矩阵吗?
不能。它回答样本子群的通过率;分类任务还需要按真实类别和预测类别查看混淆关系。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
346 收藏
-
139 收藏
-
459 收藏
-
318 收藏
-
科技周边 · 人工智能 | 36分钟前 | python · dataset Hugging Face Datasets DatasetDict save_to_disk load_from_disk 离线加载365 收藏
-
323 收藏
-
科技周边 · 人工智能 | 46分钟前 | 人工智能 · 深度学习 · PyTorch Accelerate mixed precision Accelerator accelerate launch370 收藏
-
397 收藏
-
451 收藏
-
科技周边 · 人工智能 | 51分钟前 | 人工智能 · 工具调用 · Transformers JSON Schema 工具调用 chat template apply_chat_template tool_calls495 收藏
-
科技周边 · 人工智能 | 53分钟前 | python · Hugging Face Datasets Dataset.filter with_indices input_columns load_from_cache_file num_proc225 收藏
-
134 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习