Source code for sorbetto.ranking.abstract_ranking

from abc import ABC, abstractmethod
from collections.abc import Iterable as iterable

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.axes import Axes
from matplotlib.figure import Figure

from sorbetto.core.entity import Entity


[docs] class AbstractRanking(ABC): """ See Axiom 1 in :cite:t:`Pierard2025Foundations`. """ def __init__(self, entities, performance_ordering, name=None): assert isinstance(entities, iterable) for entity in entities: assert isinstance(entity, Entity) self._entities = entities self._performance_ordering = performance_ordering self._name = name # TODO: help Sebastien # assert isinstance(performance_ordering, PerformanceOrderingInducedByOneScore) self._performance_ordering = performance_ordering if name is None: name = f"ranking of {len(entities)} entities induced by the ordering {performance_ordering.getName()}" self._name = name ABC.__init__(self) @property def entities(self) -> iterable: return self._entities @property def performance_ordering(self): return self._performance_ordering @property def name(self): return self._name @property @abstractmethod def values(self) -> np.ndarray: ...
[docs] @abstractmethod def getAllStableRanks(self) -> np.ndarray: ...
[docs] @abstractmethod def getStableRank(self, entity) -> int: ...
[docs] @abstractmethod def getAllMinRanks(self) -> np.ndarray: ...
[docs] @abstractmethod def getMinRank(self, entity) -> int: ...
[docs] @abstractmethod def getAllMaxRanks(self) -> np.ndarray: ...
[docs] @abstractmethod def getMaxRank(self, entity) -> int: ...
[docs] @abstractmethod def getEntitiesAtRank(self, rank: int) -> list: ...
[docs] def getAllAvgRanks(self) -> np.ndarray: min_ranks = self.getAllMinRanks() max_ranks = self.getAllMaxRanks() ranks = (min_ranks + max_ranks) * 0.5 return ranks
[docs] def getAvgRank(self, entity) -> float: min_ranks = self.getMinRank(entity) max_ranks = self.getMaxRank(entity) ranks = (min_ranks + max_ranks) * 0.5 return ranks
[docs] def draw( self, fig: Figure | None = None, ax: Axes | None = None, value_axis_label: str = "", ) -> tuple[Figure, Axes]: if fig is None: fig = plt.figure() ax = fig.gca() elif ax is None: ax = fig.gca() u = 0.03 # value axis ax.plot([0, 0], [0, 1.1], "k-") ax.plot([-u, 0, u], [1.1 - u, 1.1, 1.1 - u], "k-") ax.plot([-u, u], [0, 0], "k-") ax.text(-2 * u, 0, "0", ha="right", va="center") ax.plot([-u, u], [1, 1], "k-") ax.text(-2 * u, 1, "1", ha="right", va="center") ax.text( 0, 1.1 + u, value_axis_label, ha="left", va="bottom", ) n = len(self.entities) values = self.values if n == 1: e = self.entities[0] value = values[0] ax.plot([-u, u], [value, value], "-", c=e.color) y = 0.5 ax.plot([u, 0.5 - u], [value, y], ":", c=e.color) y = 0.5 ax.plot([0.5 - u, 0.5 + u], [y, y], "-", c=e.color) label = "{} ({:g})".format(e.name, value) ax.text(0.5 + 2 * u, y, label, ha="left", va="center", c=e.color) else: min_ranks = self.getAllMinRanks() max_ranks = self.getAllMaxRanks() stable_ranks = self.getAllStableRanks() for i, e in enumerate(self.entities): value = values[i] min_rank = min_ranks[i] max_rank = max_ranks[i] if min_rank != max_rank: ax.plot([-u, u], [value, value], "k-") min_y = (n - min_rank) / (n - 1) max_y = (n - max_rank) / (n - 1) ax.plot([0.5 - u, 0.5 - u], [min_y, max_y], "k-") mean_rank = (min_rank + max_rank) / 2 y = (n - mean_rank) / (n - 1) ax.plot([u, 0.5 - u], [value, y], "k:") else: ax.plot([-u, u], [value, value], "-", c=e.color) mean_rank = (min_rank + max_rank) / 2 y = (n - mean_rank) / (n - 1) ax.plot([u, 0.5 - u], [value, y], ":", c=e.color) stable_rank = stable_ranks[i] y = (n - stable_rank) / (n - 1) ax.plot([0.5 - u, 0.5 + u], [y, y], "-", c=e.color) label = "{} ({:.3f})".format(e.name, value) ax.text(0.5 + 2 * u, y, label, ha="left", va="center", c=e.color) ax.set_xlim([-0.2, 1.2]) ax.set_ylim([-0.1, 1.3]) ax.axis("off") return fig, ax
def __str__(self): return self.name