准确率或 F1 能概括模型表现,却不能告诉你究竟哪些样本出了错。实际排查需要将预测、真值和原始编号逐行对应,区分误报和漏报,再把错误行交给人复核。这里用混淆矩阵核对错误计数,并导出包含原文和编号的 CSV。
先固定正类和编号
示例任务是判断客服反馈是否需要人工跟进:1 表示需要,0 表示不需要。以下八条文本、编号、真值和预测均为虚构,用来演示错误定位,未训练客服模型。接入真实数据时,预测和真值必须来自同一批样本,不能分别排序后直接拼接。

优先沿用采集时的稳定编号。若编号重复,先查明是否多版本、重复采集或标签冲突;不要临时用行号掩盖问题。文本若含个人资料,应在本地有权限的环境复核,导出文件也要遵循原数据的使用范围。
计算矩阵并导出错误行
以下示例在 Python 3.11、scikit-learn 1.7.2 的独立环境运行通过。先在练习目录创建虚拟环境并安装对应版本:
python -m venv .venv
# Windows PowerShell
.\.venv\Scripts\python.exe -m pip install "scikit-learn==1.7.2"
# 以下脚本统一用该环境的 Python 运行,例如:
.\.venv\Scripts\python.exe demo.py
import csv
from collections import Counter
from sklearn.metrics import confusion_matrix, classification_report
# 以下标签、编号及文本都是虚构的,模拟模型预测表的导出结果。
ids = [f"demo-{i:02d}" for i in range(8)]
texts = ["没有问题", "等待太久", "退款未到", "处理完成",
"无法登录", "谢谢解答", "商品损坏", "收不到短信"]
truth = [0, 1, 1, 0, 1, 0, 1, 1] # 1 表示需要人工跟进
prediction = [0, 1, 0, 0, 1, 1, 1, 0]
if not (len(ids) == len(texts) == len(truth) == len(prediction)):
raise ValueError("编号、原文、真值和预测必须逐行对应")
if len(set(ids)) != len(ids) or set(truth + prediction) - {0, 1}:
raise ValueError("编号重复或标签不符合 0/1 约定")
matrix = confusion_matrix(truth, prediction, labels=[0, 1])
tn, fp, fn, tp = matrix.ravel()
errors = []
for rid, text, actual, predicted in zip(ids, texts, truth, prediction):
if actual != predicted:
errors.append({"id":rid, "text":text, "truth":actual,
"prediction":predicted, "error_type":"FP" if predicted == 1 else "FN"})
assert int(matrix.sum()) == len(ids)
assert len(errors) == int(fp + fn)
with open("misclassified.csv", "w", encoding="utf-8-sig", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["id","text","truth","prediction","error_type"])
writer.writeheader()
writer.writerows(errors)
print("矩阵(行=真值,列=预测)", matrix.tolist())
print("TN FP FN TP", int(tn), int(fp), int(fn), int(tp))
print("误分类编号", [r["id"] for r in errors])
print("错误类型", dict(Counter(r["error_type"] for r in errors)))
print(classification_report(truth, prediction, labels=[0,1], zero_division=0))
当前环境输出:
矩阵(行=真值,列=预测) [[2, 1], [2, 3]]
TN FP FN TP 2 1 2 3
误分类编号 ['demo-02', 'demo-05', 'demo-07']
错误类型 {'FN': 2, 'FP': 1}
precision recall f1-score support
0 0.50 0.67 0.57 3
1 0.75 0.60 0.67 5
accuracy 0.62 8
macro avg 0.62 0.63 0.62 8
weighted avg 0.66 0.62 0.63 8
labels=[0,1] 固定矩阵顺序:行是真值,列是预测。左上为 TN,右上为 FP,左下为 FN,右下为 TP。本例 FP=1、FN=2,错误行共 3 条;导出的编号为 demo-02、demo-05、demo-07。断言要求矩阵总数等于样本数,CSV 错误行数等于 FP+FN。
怎样回查与记录原因
打开脚本运行目录中的 misclassified.csv。先按 id 找原始记录,再查看真值是如何产生的;“标签错误”与“模型没学会”需要不同修复。建议另外添加 review_reason 列,使用明确的原因,例如“人工真值需修订”“上下文缺失”“否定词误判”“业务标签定义含糊”,保留复核人和日期。
本例 demo-05 被预测为需要跟进,是误报;demo-02 与 demo-07 被预测为不需要,是漏报。它们说明错误类型的定位方法,不能据此推断某个真实模型存在相同缺陷。若补充上下文才能判断,将样本标为待复核,不能为了提高分数直接改成模型的预测。
排查后如何继续
用于开发的验证集可以帮助发现问题、修订标注规范并训练下一版;需要记录每次改动,再用保持独立的数据评估。最终测试集一旦被反复查看并用于改参数,就已参与开发,原来的测试分数不能继续作为一次独立检验。
多分类的混淆矩阵不再能直接 ravel 成四个数字。应固定全量类别顺序,按实际类别对查看混淆;某类没有预测样本时,zero_division=0 让报告输出零,但这不是该类表现良好的证据。长度不同、标签映射冲突或原始编号缺失时应先停止分析。
相关问答与依据
误报和漏报哪个更严重?由业务代价决定。漏掉必须人工跟进的投诉可能更严重,但不能替所有任务统一判断;先列明漏报成本和误报处理容量,再决定优化目标。
依据:confusion_matrix 官方文档规定行列含义和 labels 顺序;classification_report 文档说明逐类指标与零除处理。代码实际验证的是虚构列表的计数和导出一致性,没有证明模型达到上线标准。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30111.html