题目:AI 视觉质检(或 OCR、缺陷检测)项目上线前,需要拿人工标注结果和模型预测结果做一次离线评估。给定两个等长列表 labels(真实标签,1=有缺陷/正样本,0=正常)和 preds(模型预测标签),实现函数 eval_cls,统计混淆矩阵并返回下列指标(浮点数保留 4 位小数):
tp / fp / fn / tn-
precision(精确率)、recall(召回率)、f1 -
fpr(误报率 = FP/(FP+TN))、fnr(漏报率 = FN/(FN+TP)) accuracy
约束:① 两个列表长度不一致必须抛 ValueError;② 任何分母为 0 的指标返回 0.0,不许抛 ZeroDivisionError;③ 不许调用 sklearn 等第三方库。
代码框架:
def eval_cls(labels: list[int], preds: list[int], pos: int = 1) -> dict:
"""离线二分类评估:统计混淆矩阵并计算 P/R/F1/误报率/漏报率。
Args:
labels: 人工标注真实标签,取值 0/1
preds: 模型预测标签,取值 0/1
pos: 正样本标签值,默认 1
Returns:
dict,键为 tp/fp/fn/tn/precision/recall/f1/fpr/fnr/accuracy,
指标保留 4 位小数,分母为 0 时该指标返回 0.0
Raises:
ValueError: labels 与 preds 长度不一致
"""
pass
自测断言:
labels = [1, 1, 1, 1, 0, 0, 0, 0, 0, 0]
preds = [1, 1, 1, 0, 1, 0, 0, 0, 0, 0]
r = eval_cls(labels, preds)
assert (r["tp"], r["fn"], r["fp"], r["tn"]) == (3, 1, 1, 5)
assert r["precision"] == 0.75 and r["recall"] == 0.75 and r["f1"] == 0.75
assert r["fpr"] == 0.1667 and r["fnr"] == 0.25 and r["accuracy"] == 0.8
assert eval_cls([0, 0], [0, 0])["precision"] == 0.0 # 无正预测,不能崩
assert eval_cls([1, 1, 0, 0], [1, 1, 0, 0])["f1"] == 1.0 # 完美预测
try:
eval_cls([1, 0], [1])
raise AssertionError("should raise")
except ValueError:
pass
难度:中级
题型:笔试(编程题)