老版本Transformer的from datasets import load_metric
,在新版本中被替换成了evaluate
。
这个包挺难用的,而且不同版本的接口都有点不太一样,本博客以transformers==4.18.0
, evaluate==0.4.0
为例,示范一下如何使用evaluate进行常见的metrics的计算。
- 计算单个metric
pred = [0,1,2,2,3]
ref = [0,2,2,3,3]
acc_metric = evaluate.load("accuracy")
acc_metric.compute(predictions=pred, references=ref)
输出(python字典):
{'accuracy': 0.6}
- 同时计算多个metric
利用combine
可以同时load多个metric,compute
之后返回所有metric的分数。
pred = [0,1,1,1,0]
ref = [0,0,1,0,1]
metrics = evaluate.combine(["accuracy", "f1", "precision", "recall"])
metrics.compute(predictions=pred, references=ref)
输出:
{'accuracy': 0.4, 'f1': 0.4, 'precision': 0.3333333333333333, 'recall': 0.5}
这里要注意,f1的接口默认average
的方式是binary
,所以上述二分类问题直接计算不会有问题。但是如果是多分类,就不能使用combine了,因为acc是没有这个**kwargs
的。
- 计算多个metric(多分类)
这种情况下,得单独load每个metric,然后再分别compute。compute的时候,f1记得传入参数“average”:
pred = [0,1,2,2,3]
ref = [0,2,2,3,3]
acc_metric = evaluate.load("accuracy")
f_metric = evaluate.load("f1")
r_metric = evaluate.load('recall')
p_metric = evaluate.load('precision')
result = dict()
result.update(acc_metric.compute(predictions=pred, references=ref))
result.update(f_metric.compute(predictions=pred, references=ref,average="macro"))
result.update(p_metric.compute(predictions=pred, references=ref,average="macro"))
result.update(r_metric.compute(predictions=pred, references=ref,average="macro"))
print(result)
这样的话就能实现相同的效果,输出:
{'accuracy': 0.4, 'f1': 0.4, 'precision': 0.41666666666666663, 'recall': 0.41666666666666663}
总结
直接load
metric,然后compute
,就能获得一个字典。
如果要同时计算多个metric,而且这些metric的接口一致,则利用combine
;如果这些metrics的接口不一致(例如,f1相较于acc,会额外需要average参数),则只能分别load
和compute
。
注意,以上结论只针对于
evaluate==0.4.0
这个版本,可能不同版本结论不一样。例如:
有些版本可以这么写,直接在load的时候传入metric需要的参数:
参考:
- github-Multiclass evaluation not working
- Combining metrics for multiclass predictions evaluations
- Huggingface-metrics-tutorial