11from __future__ import annotations
22
3+ import collections
34from typing import Optional
45
56import numpy as np
67import torch
7- from transformers .data .metrics .squad_metrics import compute_f1
8+ from transformers .data .metrics .squad_metrics import compute_f1 , get_tokens
89
910from ovqa .metrics .preprocessing import PrepC , get_preprocessing_fn
1011from ovqa .metrics .torchmetrics_ext import MetricExt
@@ -50,6 +51,14 @@ def get_f1_score_default_prep():
5051 )
5152
5253
54+ def get_metric_recall_default_prep ():
55+ return TextComparison (
56+ comparison_fn = compare_recall ,
57+ preproc_cand = PrepC .SIMPLE ,
58+ preproc_ref = PrepC .SIMPLE ,
59+ )
60+
61+
5362def compare_is_equal (cand : str , ref : str ):
5463 if cand == ref :
5564 return 1.0
@@ -69,6 +78,24 @@ def compare_f1(cand: str, ref: str):
6978 return float (compute_f1 (ref , cand ))
7079
7180
81+ def compare_recall (cand : str , ref : str ):
82+ """Token-level recall of the candidate against the reference.
83+
84+ Mirrors squad_metrics.compute_f1 but returns only the recall component
85+ (fraction of reference tokens that also appear in the candidate).
86+ """
87+ gold_toks = get_tokens (ref )
88+ pred_toks = get_tokens (cand )
89+ common = collections .Counter (gold_toks ) & collections .Counter (pred_toks )
90+ num_same = sum (common .values ())
91+ if len (gold_toks ) == 0 :
92+ # If the reference is empty, recall is 1.0 iff the candidate is also empty.
93+ return float (gold_toks == pred_toks )
94+ if num_same == 0 :
95+ return 0.0
96+ return num_same / len (gold_toks )
97+
98+
7299def check_length_of_cand (cand : str , ref : str ):
73100 return float (len (cand .split ()))
74101
0 commit comments