如何正确计算Transformer命名实体识别结果的Precision与Recall指标
NER任务Transformer模型输出指标的计算方法
核心计算逻辑
NER指标计算必须以完整实体为统计单位,不能直接在子词级别统计,避免子词拆分带来的指标失真,具体步骤如下:
- 第一步:合并模型输出的子词实体。根据子词的BIO标签、原文本中的起止坐标,将同类型的连续子词拼接为完整实体。比如你示例中
j、##ona、##than、da、##vis会拼接为完整的PER实体jonathan davis。 - 第二步:统一真值、预测实体的表示格式,每条实体需包含:实体文本、实体类型、原文本中的起止偏移量,用坐标匹配比文本匹配更精准,避免同文本不同位置的实体匹配错误。
- 第三步:采用CoNLL标准匹配规则:仅当预测实体的坐标完全匹配+实体类型完全匹配时,才记为真阳性(TP)。
以你给出的示例为例,计算结果如下:
真值实体共3个:jonathan davis(PER)、Chicago(LOC)、Illinois(LOC)
预测正确的实体共2个:jonathan davis(PER)、Chicago(LOC)
模型输出的有效预测实体共2个
- Precision = TP / 预测实体总数 = 2/2 = 100%
- Recall = TP / 真值实体总数 = 2/3 ≈ 66.67%
- F1值为两者的调和平均,约为80%
你之前采用的基于实体匹配的计算逻辑是适配当前场景的,只需提前完成子词合并的预处理即可。
Hugging Face内置工具用法
无需手动实现匹配逻辑,直接使用官方维护的evaluate库的seqeval指标即可,该工具完全符合CoNLL序列标注评估标准,自动处理BIO标签合并、实体匹配逻辑:
- 首先安装依赖:
pip install evaluate seqeval
- 使用示例代码:
import evaluate # 加载seqeval指标 metric = evaluate.load("seqeval") # 真值标签:按完整词级别的BIO标签序列,1条样本示例 true_labels = [ ['O', 'O', 'O', 'B-PER', 'I-PER', 'O', 'O', 'O', 'O', 'B-LOC', 'B-LOC'] ] # 预测标签:合并子词后和真值长度对齐的BIO标签序列 pred_labels = [ ['O', 'O', 'O', 'B-PER', 'I-PER', 'O', 'O', 'O', 'O', 'B-LOC', 'O'] ] # 计算指标,会返回整体指标和分实体类型的指标 results = metric.compute(predictions=pred_labels, references=true_labels) print(results)
如果是直接用pipeline输出的结果,可以先将pipeline返回的子词实体按起止坐标拼接为完整实体,再转换为上述的标签序列格式传入即可。
内容的提问来源于stack exchange,提问作者hidden layer
相关产品推荐
相关产品推荐

