Calculate ranking recall from relevant items
This commit is contained in:
parent
1d088669d1
commit
946ad4486c
2 changed files with 25 additions and 12 deletions
|
|
@ -4,7 +4,7 @@ from typing import Dict, List, Optional, TypeVar
|
||||||
import matplotlib
|
import matplotlib
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from sklearn.metrics import average_precision_score
|
from sklearn.metrics import average_precision_score, precision_recall_curve
|
||||||
|
|
||||||
from ..unique import unique
|
from ..unique import unique
|
||||||
from .draw_f1_iso_lines import draw_f1_iso_lines
|
from .draw_f1_iso_lines import draw_f1_iso_lines
|
||||||
|
|
@ -68,16 +68,13 @@ def evaluate_ranking(
|
||||||
for v in expected
|
for v in expected
|
||||||
]
|
]
|
||||||
|
|
||||||
sorted_expected_actual = sorted(
|
precision_values, recall_values, _ = precision_recall_curve(
|
||||||
zip(binarized_expected, actual_scores), key=lambda v: v[1], reverse=True
|
binarized_expected, actual_scores
|
||||||
)
|
)
|
||||||
precision = []
|
# Score thresholds keep tied scores together. Exclude the synthetic
|
||||||
recall = []
|
# empty-prediction endpoint and order by increasing recall.
|
||||||
correct = 0
|
precision = precision_values[:-1][::-1].tolist()
|
||||||
for all, (e, score) in enumerate(sorted_expected_actual, start=1):
|
recall = recall_values[:-1][::-1].tolist()
|
||||||
correct += int(e)
|
|
||||||
precision.append(correct / all)
|
|
||||||
recall.append(all / len(sorted_expected_actual))
|
|
||||||
|
|
||||||
if not disable_interpolation:
|
if not disable_interpolation:
|
||||||
for j in range(len(precision) - 2, -1, -1):
|
for j in range(len(precision) - 2, -1, -1):
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ def test_default() -> None:
|
||||||
reverse_order=True,
|
reverse_order=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert results == {"d": 5 / 6, "c": 2 / 3, "b": 2 / 5}
|
assert results == {"d": 1.0, "c": 1.0, "b": 1 / 2}
|
||||||
|
|
||||||
results = evaluate_ranking(
|
results = evaluate_ranking(
|
||||||
["a", "a", "b", "b", "c", "d", "d", "d"],
|
["a", "a", "b", "b", "c", "d", "d", "d"],
|
||||||
|
|
@ -26,7 +26,23 @@ def test_default() -> None:
|
||||||
disable_interpolation=True,
|
disable_interpolation=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert results == {"a": 0.6, "b": 0.4, "c": 0.2}
|
assert results == {"a": 2 / 3, "b": 2 / 5, "c": 2 / 7}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("disable_interpolation", [False, True])
|
||||||
|
def test_perfect_ranking_at_full_recall(disable_interpolation: bool) -> None:
|
||||||
|
assert evaluate_ranking(
|
||||||
|
[1, 1, 0, 0],
|
||||||
|
[4, 3, 2, 1],
|
||||||
|
target_recall=1,
|
||||||
|
disable_interpolation=disable_interpolation,
|
||||||
|
plot=False,
|
||||||
|
) == {0: 1.0}
|
||||||
|
|
||||||
|
|
||||||
|
def test_tied_scores_cannot_be_separated_by_a_threshold() -> None:
|
||||||
|
for labels in ([1, 0], [0, 1]):
|
||||||
|
assert evaluate_ranking(labels, [1, 1], target_recall=1, plot=False) == {0: 0.5}
|
||||||
|
|
||||||
|
|
||||||
def test_mismatching_lengths() -> None:
|
def test_mismatching_lengths() -> None:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue