-
Notifications
You must be signed in to change notification settings - Fork 0
/
medprocner_evaluation.py
88 lines (75 loc) · 3.99 KB
/
medprocner_evaluation.py
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
"""
MedProcNER evaluation library main script.
Partially based on the DisTEMIST and MEDDOPLACE evaluation scripts.
@author: salva
"""
import sys
import os
import pandas as pd
from datetime import datetime
from argparse import ArgumentParser
import utils
def main(argv=None):
"""
Parse options and call the appropriate evaluation scripts
"""
# Parse options
parser = ArgumentParser()
parser.add_argument("-r", "--reference", dest="reference",
help=".TSV file with Gold Standard or reference annotations", required=True)
parser.add_argument("-p", "--prediction", dest="prediction",
help=".TSV file with your predictions", required=True)
parser.add_argument("-t", "--task", dest="task", choices=['ner', 'norm', 'index'],
help="Task that you want to evaluate (ner, norm or index)", required=True)
parser.add_argument("-o", "--output", dest="output",
help="Path to save the scoring results", required=True)
parser.add_argument("-v", "--verbose", dest="verbose", action="store_true",
help="Set to True to print the results for each individual file instead of just the final score")
args = parser.parse_args(argv)
# Set output file name
timedate = datetime.now().strftime('%Y%m%d_%H%M%S')
out_file = os.path.join(args.output, 'medprocner_results_{}_{}.txt'.format(args.task, timedate))
# Read gold_standard and predictions
print("Reading reference and prediction .tsv files")
df_gs = pd.read_csv(args.reference, sep="\t")
df_preds = pd.read_csv(args.prediction, sep="\t")
if args.task in ['ner', 'norm']:
df_preds = df_preds.drop_duplicates(
subset=["filename", "label", "start_span", "end_span"]).reset_index(drop=True) # Remove any duplicate predictions
if args.task == "ner":
calculate_ner(df_gs, df_preds, out_file, args.verbose)
elif args.task == "norm":
calculate_norm(df_gs, df_preds, out_file, args.verbose)
elif args.task == "index":
calculate_index(df_gs, df_preds, out_file, args.verbose)
else:
print('Please choose a valid task (ner, norm, index)')
def calculate_ner(df_gs, df_preds, output_path, verbose=False):
print("Computing evaluation scores for Task 1 (ner)")
# Group annotations by filename
list_gs_per_doc = df_gs.groupby('filename').apply(lambda x: x[[
"filename", 'start_span', 'end_span', "text", "label"]].values.tolist()).to_list()
list_preds_per_doc = df_preds.groupby('filename').apply(
lambda x: x[["filename", 'start_span', 'end_span', "text", "label"]].values.tolist()).to_list()
scores = utils.calculate_fscore(list_gs_per_doc, list_preds_per_doc, 'ner')
utils.write_results('ner', scores, output_path, verbose)
def calculate_norm(df_gs, df_preds, output_path, verbose=False):
print("Computing evaluation scores for Task 2 (norm)")
# Group annotations by filename
list_gs_per_doc = df_gs.groupby('filename').apply(lambda x: x[[
"filename", 'start_span', 'end_span', "text", "label", "code"]].values.tolist()).to_list()
list_preds_per_doc = df_preds.groupby('filename').apply(
lambda x: x[["filename", 'start_span', 'end_span', "text", "label", "code"]].values.tolist()).to_list()
scores = utils.calculate_fscore(list_gs_per_doc, list_preds_per_doc, 'norm')
utils.write_results('norm', scores, output_path, verbose)
def calculate_index(df_gs, df_preds, output_path, verbose=False):
print("Computing evaluation scores for Task 3 (index)")
# Group annotations by filename
list_gs_per_doc = df_gs.groupby('filename').apply(lambda x: x[[
"filename", "codes"]].values.tolist()).to_list()
list_preds_per_doc = df_preds.groupby('filename').apply(
lambda x: x[["filename", "code"]].values.tolist()).to_list()
scores = utils.calculate_fscore(list_gs_per_doc, list_preds_per_doc, 'index')
utils.write_results('index', scores, output_path, verbose)
if __name__ == "__main__":
main()