Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion sacrebleu/metrics/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ def format(
is_json: bool = False,
) -> str:
"""Returns a pretty representation of the score.

Includes a computed confidence interval even when its mean is zero.

:param width: Floating point decimal precision width.
:param score_only: If `True`, and the format is not `json`,
returns a single score string.
Expand All @@ -61,7 +64,7 @@ def format(

sc = f"{self.score:.{width}f}"

if self._mean > 0:
if self._mean >= 0:
confidence_mean = f"{self._mean:.{width}f}"
confidence_var = f"{self._ci:.{width}f}"
confidence_str = f"μ = {confidence_mean} ± {confidence_var}"
Expand Down
35 changes: 34 additions & 1 deletion test/test_metrics_base.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import json
from contextlib import nullcontext as does_not_raise

import pytest

from sacrebleu.metrics.base import Metric
from sacrebleu.metrics.base import Metric, Score


class ConcreteTestMetric(Metric):
Expand Down Expand Up @@ -353,3 +354,35 @@ def test_check_corpus_score_args(hyps, refs, expected_context):
metric = ConcreteTestMetric()
with expected_context:
metric._check_corpus_score_args(hyps=hyps, refs=refs)


@pytest.mark.parametrize("mean", [0.0, 1.0])
def test_score_format_confidence_interval(mean):
score = Score("TEST", mean)
score.estimate_ci([score] * 40)
confidence = f"\u03bc = {mean:.2f} \u00b1 0.00"

assert score.format() == f"TEST = {mean:.2f} ({confidence})"
assert score.format(score_only=True) == f"{mean:.2f} ({confidence})"
assert json.loads(score.format(signature="version:test", is_json=True)) == {
"name": "TEST",
"score": mean,
"signature": "version:test",
"version": "test",
"confidence_mean": mean,
"confidence_var": 0.0,
"confidence": confidence,
}


def test_score_format_without_confidence_interval():
score = Score("TEST", 0.0)

assert score.format() == "TEST = 0.00"
assert score.format(score_only=True) == "0.00"
assert json.loads(score.format(signature="version:test", is_json=True)) == {
"name": "TEST",
"score": 0.0,
"signature": "version:test",
"version": "test",
}