问答匹配(answer selection)
给定问题与问题的候选答案池,从中选择出最好的答案,如果说选择的答案在真实答案集中,说明问题被很好的回答了,否则的话,问题就没有被很好的回答,评价指标使用mAP与MRR等指标。开始本来尝试了召回率和准确率。但它们更适用于分类的场景。
概念:
MAP (Mean Average Precision,平均精度均值):mAP 是 Precision-Recall 曲线下的面积,用于评估检索系统的性能。在问答匹配中,首先计算每个问题的 Precision 和 Recall,然后计算所有问题的平均 Precision,即平均精度(AP)。最后,计算所有问题的 AP 的平均值,即 mAP。mAP 能够综合考虑检索系统在所有问题上的性能,是评估检索结果质量的重要指标。 MRR (Mean Reciprocal Rank,平均倒数排名):MRR 是在排名任务中常用的指标,用于评估系统在给定查询条件下返回的结果的排名质量。对于每个查询,MRR 是查询结果中第一个正确答案的倒数排名的平均值。在问答匹配中,MRR 表示检索系统返回的第一个正确答案的平均排名的倒数。MRR 能够反映检索系统在给定查询条件下找到正确答案的速度和效率。 这两个指标都是用于评估问答匹配任务的性能,通常情况下,更高的 mAP 和 MRR 值表示检索系统的性能更好
步骤一:数据准备
收集样本数据集,本次案例是读取doc文档,提取文本内容,分割导入测试模型L。
步骤二:准备标注数据集
可根据自身情况设计数据集,结构如下:
# 模拟 TrecQA 数据集,包含问题和对应的正确答案
trecqa_data = [
{"question": "公司组织机构包括哪些?", "true_answer": "AAAA。"},
{"question": "小组主要采用什么方式进行议事?",
"true_answer": "bbbb"}
]
步骤三:准备标注数据集
调用模型,根据模型返回答案使用模糊匹配来判断答案,我这里设置的阈值是75。
# 使用模糊匹配来判断答案是否正确
def evaluate_accuracy(predicted_answer, true_answer):
similarity_score = fuzz.ratio(predicted_answer, true_answer)
# 如果相似度超过阈值,则认为预测答案是正确的
return similarity_score >= threshold # 可调整阈值
步骤四:计算 MAP 和 MRR
# 计算 Mean Average Precision(mAP)
def calculate_map(ground_truth, predicted_answers):
if not predicted_answers:
return 0
y_true = [1 if fuzz.ratio(ans, ground_truth) >= threshold else 0 for ans in predicted_answers]
y_score = [fuzz.ratio(ans, ground_truth) / 100 for ans in predicted_answers]
return average_precision_score(y_true, y_score)
# 计算 MRR
def calculate_mrr(ground_truth, predicted_answers):
mrr = 0
found = False
for i, ans in enumerate(predicted_answers):
if fuzz.ratio(ans, ground_truth) >= threshold:
mrr += 1 / (i + 1)
found = True
if found:
if len(ans) < len(ground_truth):
return len(ans) / len(ground_truth)
else:
return len(ground_truth)/len(ans)
return 0
整体调用代码如下:
map_scores = []
mrr_scores = []
for data in trecqa_data:
question = data["question"]
true_answer = data["true_answer"]
predicted_answer = call_langchain_api(question)
if predicted_answer:
accuracy = evaluate_accuracy(predicted_answer, true_answer)
else:
accuracy = False
if predicted_answer:
map_score = calculate_map(true_answer, [predicted_answer])
mrr_score = calculate_mrr(true_answer, [predicted_answer])
else:
map_score = 0
mrr_score = 0
map_scores.append(map_score)
mrr_scores.append(mrr_score)
average_map = sum(map_scores) / len(map_scores)
average_mrr = sum(mrr_scores) / len(mrr_scores)
print("Mean Average Precision (mAP):", average_map)
print("Mean Reciprocal Rank (MRR):", average_mrr)
步骤五:查看实验结果,基本就是6个问题错了一个。
Mean Average Precision (mAP): 0.8333333333333334
Mean Reciprocal Rank (MRR): 0.6308518590262199