@@ -15,28 +15,57 @@ def evaluate(
1515
1616
1717class StrictEvaluation (EvaluationStrategy ):
18- """Strict evaluation strategy - entities must match exactly."""
18+ """
19+ Strict evaluation strategy - entities must match exactly.
20+
21+ In in strategy, we check for overlap between the predicted entity and the true entity.
22+
23+ If there's a predicted entity that perfectly matches a true entity and they have the same label
24+ we mark it as correct.
25+ If there's a predicted entity that doesn't perfectly match any true entity, we mark it as spurious.
26+ If there's a true entity that doesn't perfecly match any predicted entity, we mark it as missed.
27+ All other cases are marked as incorrect.
28+ """
1929
2030 def evaluate (
2131 self , true_entities : List [Entity ], pred_entities : List [Entity ], tags : List [str ], instance_index : int = 0
2232 ) -> Tuple [EvaluationResult , EvaluationIndices ]:
2333 """
2434 Evaluate the predicted entities against the true entities using strict matching.
2535 """
26-
2736 result = EvaluationResult ()
2837 indices = EvaluationIndices ()
38+ matched_true = set ()
2939
3040 for pred_idx , pred in enumerate (pred_entities ):
31- if pred in true_entities :
32- result .correct += 1
33- indices .correct_indices .append ((instance_index , pred_idx ))
34- else :
41+ found_match = False
42+ found_incorrect = False
43+
44+ for true_idx , true in enumerate (true_entities ):
45+ if true_idx in matched_true :
46+ continue
47+
48+ # Check for perfect match (same boundaries and label)
49+ if pred .label == true .label and pred .start == true .start and pred .end == true .end :
50+ result .correct += 1
51+ indices .correct_indices .append ((instance_index , pred_idx ))
52+ matched_true .add (true_idx )
53+ found_match = True
54+ break
55+ # Check for any overlap
56+ if pred .start <= true .end and pred .end >= true .start :
57+ result .incorrect += 1
58+ indices .incorrect_indices .append ((instance_index , pred_idx ))
59+ matched_true .add (true_idx )
60+ found_incorrect = True
61+ break
62+
63+ if not found_match and not found_incorrect :
3564 result .spurious += 1
3665 indices .spurious_indices .append ((instance_index , pred_idx ))
3766
3867 for true_idx , true in enumerate (true_entities ):
39- if true not in pred_entities :
68+ if true_idx not in matched_true :
4069 result .missed += 1
4170 indices .missed_indices .append ((instance_index , true_idx ))
4271
@@ -47,9 +76,9 @@ def evaluate(
4776class PartialEvaluation (EvaluationStrategy ):
4877 """
4978 Partial evaluation strategy - allows for partial matches.
50-
79+
5180 In in strategy, we check for overlap between the predicted entity and the true entity.
52-
81+
5382 If there's a predicted entity that perfectly matches a true entity, we mark it as correct.
5483 If there's a predicted entity that has some minimum overlap with a true entity we mark it as partial.
5584 If there's a predicted entity that doesn't match any true entity, we mark it as spurious.
0 commit comments