diff --git a/src/lighteval/metrics/normalizations.py b/src/lighteval/metrics/normalizations.py index ef55681b1..0dad8d3a9 100644 --- a/src/lighteval/metrics/normalizations.py +++ b/src/lighteval/metrics/normalizations.py @@ -68,7 +68,9 @@ def lower(text: str) -> str: def _tokenize(text): return re.split(" |-", text) - tokens = [white_space_fix(remove_articles(homogeneize_numbers(remove_punc(lower(t))))) for t in _tokenize(text)] + # homogeneize_numbers must run before remove_punc: otherwise remove_punc strips the decimal + # point first, so "1.0" -> "10" -> float -> "10.0" (distinct numbers collide, and 1.0 != 1). + tokens = [white_space_fix(remove_articles(remove_punc(homogeneize_numbers(lower(t))))) for t in _tokenize(text)] return " ".join([t for t in tokens if t != ""]).strip() diff --git a/tests/test_unit_base_metrics.py b/tests/test_unit_base_metrics.py index 575ebf595..51fb58d68 100644 --- a/tests/test_unit_base_metrics.py +++ b/tests/test_unit_base_metrics.py @@ -95,6 +95,15 @@ def test_quasi_exact_match(self): res = em.compute_one_item("", "") assert res == 0 + def test_quasi_exact_match_numbers(self): + em = ExactMatches(normalize_gold=helm_normalizer, normalize_pred=helm_normalizer) + + # Numbers that are equal but formatted differently must match (homogeneize_numbers' goal). + assert em.compute_one_item("1.0", "1") == 1 + # Distinct numbers must NOT be scored as an exact match. + assert em.compute_one_item("10", "1.0") == 0 + assert em.compute_one_item("3.14", "314") == 0 + def test_prefix_exact_match(self): em = ExactMatches( strip_strings=True,