Skip to content

Commit 86238e9

Browse files
committed
correcting and fixing strict strategy
1 parent 29c03da commit 86238e9

2 files changed

Lines changed: 42 additions & 13 deletions

File tree

compare_versions.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
#
1616
# ['O', 'B-PER', 'I-PER', 'O', 'O', 'O', 'B-ORG', 'I-ORG'], # strict - correct: 2 incorrect: 0 partial: 0 missed: 0 spurious: 0
1717
# ['O', 'B-PER', 'I-PER', 'O', 'O', 'O', 'O', 'O'], # strict - correct: 1 incorrect: 0 partial: 0 missed: 1 spurious: 0
18-
# ['O', 'B-PER', 'I-PER', 'O', 'O', 'O', 'B-LOC', 'I-LOC'], # strict - correct: 1 incorrect: 1 partial: 0 missed: 0 spurious: 0 -> Needs fixing new code
19-
# ['O', 'B-PER', 'I-PER', 'O', 'O', 'O', 'B-LOC', 'O'], # strict - correct: 1 incorrect: 1 partial: 0 missed: 0 spurious: 0 -> Needs fixing new code
20-
# ['O', 'B-PER', 'I-PER', 'O', 'O', 'O', 'O', 'B-LOC'], # strict - correct: 1 incorrect: 1 partial: 0 missed: 0 spurious: 0 -> Needs fixing new code
21-
# ['O', 'B-PER', 'I-PER', 'O', 'B-PER', 'O', 'B-LOC', 'I-LOC'], # strict - correct: 1 incorrect: 1 partial: 0 missed: 0 spurious: 1 -> Needs fixing new code
18+
# ['O', 'B-PER', 'I-PER', 'O', 'O', 'O', 'B-LOC', 'I-LOC'], # strict - correct: 1 incorrect: 1 partial: 0 missed: 0 spurious: 0
19+
# ['O', 'B-PER', 'I-PER', 'O', 'O', 'O', 'B-LOC', 'O'], # strict - correct: 1 incorrect: 1 partial: 0 missed: 0 spurious: 0
20+
# ['O', 'B-PER', 'I-PER', 'O', 'O', 'O', 'O', 'B-LOC'], # strict - correct: 1 incorrect: 1 partial: 0 missed: 0 spurious: 0
21+
# ['O', 'B-PER', 'I-PER', 'O', 'B-PER', 'O', 'B-LOC', 'I-LOC'], # strict - correct: 1 incorrect: 1 partial: 0 missed: 0 spurious: 1
2222

2323

2424
# Type: must have the same tag and some minimum overlap between the system tagged entity and the gold annotation

src/nervaluate/evaluation_strategies.py

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,57 @@ def evaluate(
1515

1616

1717
class 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(
4776
class 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

Comments
 (0)