CoolFace
Apppublic

Linhz/ViMNer

sourceHugging Faceupdated 2y agoView on Hugging Face
1likes
ner_evaluate.py186 linesDownload Raw Back to MultimodelNER
1import codecs
2import numpy as np
3
4
5def get_chunks(seq, tags):
6    """
7    tags:dic{'per':1,....}
8    Args:
9        seq: [4, 4, 0, 0, ...] sequence of labels
10        tags: dict["O"] = 4
11    Returns:
12        list of (chunk_type, chunk_start, chunk_end)
13
14    Example:
15        seq = [4, 5, 0, 3]
16        tags = {"B-PER": 4, "I-PER": 5, "B-LOC": 3}
17        result = [("PER", 0, 2), ("LOC", 3, 4)]
18    """
19    default = tags['O']
20    idx_to_tag = {idx: tag for tag, idx in tags.items()}
21    chunks = []
22    # chunk_type用于判断是什么类型,LOC,PER
23    chunk_type, chunk_start = None, None
24    for i, tok in enumerate(seq):
25        # End of a chunk 1
26        if tok == default and chunk_type is not None:
27            # Add a chunk.
28            chunk = (chunk_type, chunk_start, i)
29            chunks.append(chunk)
30            chunk_type, chunk_start = None, None
31
32        # End of a chunk + start of a chunk!
33        elif tok != default:
34            # tok_chunk_class 判断是以B开头还是I开头
35            # tok_chunk_type 判断是什么类型,PER,LOC
36            tok_chunk_class, tok_chunk_type = get_chunk_type(tok, idx_to_tag)
37            if chunk_type is None:
38                chunk_type, chunk_start = tok_chunk_type, i
39            elif tok_chunk_type != chunk_type or tok_chunk_class == "B":
40                chunk = (chunk_type, chunk_start, i)
41                chunks.append(chunk)
42                chunk_type, chunk_start = tok_chunk_type, i
43        else:
44            pass
45    # end condition
46    if chunk_type is not None:
47        chunk = (chunk_type, chunk_start, len(seq))
48        chunks.append(chunk)
49    return chunks
50
51
52def get_chunk_type(tok, idx_to_tag):
53    """
54    Args:
55        tok: id of token, such as 4
56        idx_to_tag: dictionary {4: "B-PER", ...}
57    Returns:
58        tuple: "B", "PER"
59    """
60    tag_name = idx_to_tag[tok]
61    tag_class = tag_name.split('-')[0]
62    tag_type = tag_name.split('-')[-1]
63    return tag_class, tag_type
64
65
66# def run_evaluate(self, sess, test, tags):
67def evaluate(labels_pred, labels, words, tags):
68    """
69    words,pred, right: is a sequence, is label index or word index.
70    Evaluates performance on test set
71    Args:
72        sess: tensorflow session
73        test: dataset that yields tuple of sentences, tags
74        tags: {tag: index} dictionary
75    Returns:
76        accuracy
77        f1 score
78        ...
79    """
80
81    # file_write = open('./test_results.txt','w')
82
83    index = 0
84    sents_length = []
85
86    accs = []
87    correct_preds, total_correct, total_preds = 0., 0., 0.
88
89    for lab, lab_pred, word_sent in zip(labels, labels_pred, words):
90        word_st = word_sent
91        lab = lab
92        lab_pred = lab_pred
93        accs += [a == b for (a, b) in zip(lab, lab_pred)]
94        lab_chunks = set(get_chunks(lab, tags))
95        lab_pred_chunks = set(get_chunks(lab_pred, tags))
96        correct_preds += len(lab_chunks & lab_pred_chunks)
97        total_preds += len(lab_pred_chunks)
98        total_correct += len(lab_chunks)
99
100    # for i in range(len(word_st)):
101    # file_write.write('%s\t%s\t%s\n'%(word_st[i],lab[i],lab_pred[i]))
102    # file_write.write('\n')
103
104    p = correct_preds / total_preds if correct_preds > 0 else 0
105    r = correct_preds / total_correct if correct_preds > 0 else 0
106    f1 = 2 * p * r / (p + r) if correct_preds > 0 else 0
107    acc = np.mean(accs)
108
109    # file_write.close()
110    return acc, f1, p, r
111
112
113def evaluate_each_class(labels_pred, labels, words, tags, class_type):
114    # class_type:PER or LOC or ORG
115    index = 0
116
117    accs = []
118    correct_preds, total_correct, total_preds = 0., 0., 0.
119    correct_preds_cla_type, total_preds_cla_type, total_correct_cla_type = 0., 0., 0.
120
121    for lab, lab_pred, word_sent in zip(labels, labels_pred, words):
122        lab_pre_class_type = []
123        lab_class_type = []
124
125        word_st = word_sent
126        lab = lab
127        lab_pred = lab_pred
128        lab_chunks = get_chunks(lab, tags)
129        lab_pred_chunks = get_chunks(lab_pred, tags)
130        for i in range(len(lab_pred_chunks)):
131            if lab_pred_chunks[i][0] == class_type:
132                lab_pre_class_type.append(lab_pred_chunks[i])
133        lab_pre_class_type_c = set(lab_pre_class_type)
134
135        for i in range(len(lab_chunks)):
136            if lab_chunks[i][0] == class_type:
137                lab_class_type.append(lab_chunks[i])
138        lab_class_type_c = set(lab_class_type)
139
140        lab_chunksss = set(lab_chunks)
141        correct_preds_cla_type += len(lab_pre_class_type_c & lab_chunksss)
142        total_preds_cla_type += len(lab_pre_class_type_c)
143        total_correct_cla_type += len(lab_class_type_c)
144
145    p = correct_preds_cla_type / total_preds_cla_type if correct_preds_cla_type > 0 else 0
146    r = correct_preds_cla_type / total_correct_cla_type if correct_preds_cla_type > 0 else 0
147    f1 = 2 * p * r / (p + r) if correct_preds_cla_type > 0 else 0
148
149    return f1, p, r
150
151
152if __name__ == '__main__':
153    max_sent = 10
154    tags = {'0': 0,
155            'B-PER': 1, 'I-PER': 2,
156            'B-LOC': 3, 'I-LOC': 4,
157            'B-ORG': 5, 'I-ORG': 6,
158            'B-OTHER': 7, 'I-OTHER': 8,
159            'O': 9}
160    labels_pred = [
161        [9, 9, 9, 1, 3, 1, 2, 2, 0, 0],
162        [9, 9, 9, 1, 3, 1, 2, 0, 0, 0]
163    ]
164    labels = [
165        [9, 9, 9, 9, 3, 1, 2, 2, 0, 0],
166        [9, 9, 9, 9, 3, 1, 2, 2, 0, 0]
167    ]
168    words = [
169        [0, 0, 0, 0, 0, 3, 6, 8, 5, 7],
170        [0, 0, 0, 4, 5, 6, 7, 9, 1, 7]
171    ]
172    id_to_vocb = {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j'}
173    # new_words = []
174    # for i in range(len(words)):
175    # 	sent = []
176    # 	for j in range(len(words[i])):
177    # 		sent.append(id_to_vocb[words[i][j]])
178    # 	new_words.append(sent)
179    # class_type = 'PER'
180    # acc, f1,p,r = evaluate(labels_pred, labels,new_words,tags)
181    # print(p,r,f1)
182    # f1,p,r = evaluate_each_class(labels_pred, labels,new_words,tags, class_type)
183    # print(p,r,f1)
184
185    acc, f1, p, r = evaluate(labels_pred, labels, words, tags)
186    print(acc)