-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_another_dataset_metrics.py
More file actions
111 lines (91 loc) · 4.39 KB
/
Copy pathtest_another_dataset_metrics.py
File metadata and controls
111 lines (91 loc) · 4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# BIO标签抽取实体
def extract_entities(sentence, bio):
words = list(sentence) # 句子按字拆分
bio_tags = bio.split() # BIO 标签按空格拆分
if len(words)>len(bio_tags):
words = words[:len(bio_tags)]
assert len(words) == len(bio_tags), f"句子长度和BIO标签长度不匹配!{len(sentence)},{len(bio)},{words},{bio_tags}"
entities = []
current_entity = []
current_label = None
for char, tag in zip(words, bio_tags):
if tag.startswith("B-"): # 遇到新的实体
if current_entity: # 先存储上一个实体
entities.append("".join(current_entity))
current_entity = [char] # 记录当前字符
current_label = tag[2:] # 提取实体类别(去掉B-前缀)
elif tag.startswith("I-") and current_label == tag[2:]: # 继续当前实体
current_entity.append(char)
else: # 遇到 "O" 或者 I- 但不匹配当前实体
if current_entity:
entities.append("".join(current_entity))
current_entity = []
current_label = None
if current_entity: # 处理最后一个实体
entities.append("".join(current_entity))
return entities
# 计算recall,precision,f1分数
def calculate_metrics(true_labels, predicted_labels):
# 计算TP, FP, FN
true_set = set(true_labels)
predicted_set = set(predicted_labels)
# 计算交集、并集
true_positive = len(true_set & predicted_set) # 交集
false_positive = len(predicted_set - true_set) # 预测正确但实际没有的实体
false_negative = len(true_set - predicted_set) # 实际正确但未预测出的实体
# 计算precision, recall, f1
precision = true_positive / (true_positive + false_positive) if true_positive + false_positive > 0 else 0
recall = true_positive / (true_positive + false_negative) if true_positive + false_negative > 0 else 0
f1 = 2 * precision * recall / (precision + recall) if precision + recall > 0 else 0
return precision, recall, f1
if __name__=="__main__":
# predict_file = 'D:/PyProject/bert_github/BERT-for-Sequence-Labeling-and-Text-Classification-master/output_model/ChemNER+_bertcrf_epoch50/test_predictions.txt'
predict_file = 'D:/PyProject/bert_github/BERT-for-Sequence-Labeling-and-Text-Classification-master/result/ours_roberta_on_ChemNER+_predictions.txt'
sentence_file = 'ChemNER+/test/seq.in'
label_file = 'ChemNER+/test/seq.out'
sentences = []
real_bios = []
predict_bios = []
with open(sentence_file, 'r', encoding='utf-8') as f1: #句子
lines = f1.readlines()
for line in lines:
sentences.append(line)
with open(label_file, 'r', encoding='utf-8') as f2: #真实标签
lines = f2.readlines()
for line in lines:
real_bios.append(line)
with open(predict_file, 'r', encoding='utf-8') as f3: #预测结果
lines = f3.readlines()
for i,line in enumerate(lines):
tokens = line.strip().split()
tokens = [t for t in tokens if t not in ["[CLS]","[SEP]"]]
predict_bios.append(" ".join(tokens))
# print(predict_bios[i])
real = []
predict = []
precisions, recalls,f1s = [], [], []
for i in range(len(sentences)):
sentence = sentences[i]
real_bio = real_bios[i]
predict_bio = predict_bios[i]
real_entities = extract_entities(sentence, real_bio)
predict_enities = extract_entities(sentence, predict_bio)
# print(real_entities)
# print(predict_enities)
# 跳过空标签
if not real_entities:
# print(real_entities)
continue
precision, recall, f1 = calculate_metrics(real_entities, predict_enities)
# 记录结果
precisions.append(precision)
recalls.append(recall)
f1s.append(f1)
real.append(real_entities)
predict.append(predict_enities)
avg_precision = sum(precisions) / len(precisions) if precisions else 0
avg_recall = sum(recalls) / len(recalls) if recalls else 0
avg_f1 = sum(f1s) / len(f1s) if f1s else 0
print(f"Average Precision: {avg_precision:.4f}")
print(f"Average Recall: {avg_recall:.4f}")
print(f"Average F1 Score: {avg_f1:.4f}")