2. 实现精确匹配与包含匹配评测
任务目标
实现一个评测脚本,对模型生成的回答分别进行精确匹配(Exact Match)和包含匹配(Contains Match)评分,并输出两种指标的结果对比,用于观察宽松匹配对得分的影响。
核心实现
def exact_match(reference: str, prediction: str) -> int:
"""精确匹配:归一化后完全一致得1分,否则0分"""
return int(_normalize(reference) == _normalize(prediction))
def contains_match(reference: str, prediction: str) -> int:
"""包含匹配:归一化后参考答案是预测答案的子串得1分"""
return int(_normalize(reference) in _normalize(prediction))
def _normalize(text: str) -> str:
"""轻量归一化:去首尾空白、统一小写、去除内部多余空格"""
return " ".join(text.strip().lower().split())
def evaluate(predictions: list, references: list) -> dict:
"""对成对样本计算两种指标,返回汇总统计与逐样本结果"""
if len(predictions) != len(references):
raise ValueError("predictions 与 references 长度不一致")
em_scores, cm_scores = [], []
details = []
for pred, ref in zip(predictions, references):
em = exact_match(ref, pred)
cm = contains_match(ref, pred)
em_scores.append(em)
cm_scores.append(cm)
details.append({
"prediction": pred,
"reference": ref,
"exact_match": em,
"contains_match": cm,
})
return {
"exact_match_accuracy": sum(em_scores) / len(em_scores),
"contains_match_accuracy": sum(cm_scores) / len(cm_scores),
"sample_count": len(predictions),
"details": details,
}
if __name__ == "__main__":
# 最小可运行示例:3个样本
preds = [
"北京是中国的首都",
"机器学习是人工智能的一个分支",
"Transformer 架构由 Google 提出",
]
refs = [
"北京是中国的首都。",
"机器学习是人工智能的分支",
"Transformer架构由Google在2017年提出",
]
result = evaluate(preds, refs)
print(f"样本数: {result['sample_count']}")
print(f"精确匹配准确率: {result['exact_match_accuracy']:.2%}")
print(f"包含匹配准确率: {result['contains_match_accuracy']:.2%}")
print("\n逐样本明细:")
for i, d in enumerate(result["details"]):
print(f"样本{i+1}: EM={d['exact_match']} CM={d['contains_match']} | "
f"预测: {d['prediction'][:20]}... | 参考: {d['reference'][:20]}...")
运行方式
python evaluate_match.py
无需安装第三方库,Python 3.6+ 即可直接运行。
验证方法与预期输出
运行脚本后观察控制台输出,满足以下条件即判定通过:
- 程序正常结束,无异常报错;
- 输出包含两种指标的准确率,且包含匹配准确率 ≥ 精确匹配准确率;
- 逐样本明细中,每个样本的 EM 和 CM 值符合定义(EM=1 时 CM 必为 1,反之不一定)。
针对示例数据,预期输出为:
样本数: 3
精确匹配准确率: 33.33%
包含匹配准确率: 100.00%
逐样本明细:
样本1: EM=0 CM=1 | 预测: 北京是中国的首都... | 参考: 北京是中国的首都。...
样本2: EM=0 CM=1 | 预测: 机器学习是人工智能的一个分支... | 参考: 机器学习是人工智能的分支...
样本3: EM=1 CM=1 | 预测: Transformer 架构由 Google 提出... | 参考: Transformer架构由Google在2017年提出...
其中样本1因标点差异精确匹配失败但包含匹配成功;样本2因“一个”多余词导致精确匹配失败;样本3因空格和年份补充导致精确匹配失败。三种情况直观展示了两种指标的差异。