diff --git a/docs/guide/evaluation/rankings.rst b/docs/guide/evaluation/rankings.rst index 83c67b730..cfc2c71c9 100644 --- a/docs/guide/evaluation/rankings.rst +++ b/docs/guide/evaluation/rankings.rst @@ -15,11 +15,17 @@ list and a test rating list, both as :py:class:`item lists `; most metrics require the recommendation item list to be :py:attr:`~lenskit.data.ItemList.ordered`. -All LensKit ranking metrics take `k` as a constructor argument to control the +All LensKit ranking metrics take ``n`` as a constructor argument to control the list of the length that is considered; this allows multiple measurements (e.g. HR@5 and HR@10) to be computed from a single set of rankings. +.. versionchanged:: 2026.1 + + The argument for the list length has changed from ``k`` to ``n``, for + consistency across LensKit. + .. versionchanged:: 2025.1 + The top-N accuracy metric interface has changed to use item lists, and to be simpler to implement. diff --git a/docs/releases/2026.rst b/docs/releases/2026.rst index b10e6850b..86d597419 100644 --- a/docs/releases/2026.rst +++ b/docs/releases/2026.rst @@ -74,6 +74,8 @@ Breaking Changes (:pr:`1052`). - Removed the ``n`` option to :func:`~lenskit.pipeline.predict_pipeline` (:issue:`835`). +- Removed the deprecated ``k=`` alias for the ``n=`` option in ranking metrics + (:issue:`889`, :pr:`1073`). - Removed the deprecated unrated and all-items candidate selectors, in favor of :class:`~lenskit.basic.TrainingItemsCandidateSelector` (:issue:`935`). diff --git a/src/lenskit/metrics/ranking/_base.py b/src/lenskit/metrics/ranking/_base.py index 2e28d16e2..fe9726182 100644 --- a/src/lenskit/metrics/ranking/_base.py +++ b/src/lenskit/metrics/ranking/_base.py @@ -4,8 +4,6 @@ # Licensed under the MIT license, see LICENSE.md for details. # SPDX-License-Identifier: MIT -import warnings - from lenskit.data import ItemList from .._base import ListMetric, Metric @@ -18,12 +16,14 @@ class RankingMetricBase(Metric): Base class for most ranking metrics, implementing an ``n`` parameter for truncation. + .. versionchanged:: 2026.1 + + Removed deprecated ``k`` alias for ``n``. + Args: n: Specify the length cutoff for rankings. Rankings longer than this will be truncated prior to measurement. - k: - Deprecated alias for ``n``. Stability: Caller @@ -32,12 +32,7 @@ class RankingMetricBase(Metric): n: int | None = None "The maximum length of rankings to consider." - def __init__(self, n: int | None = None, *, k: int | None = None): - if n is None: - if k is not None: - warnings.warn("k= is deprecated, use n=", DeprecationWarning) - n = k - + def __init__(self, n: int | None = None): if n is not None and n < 0: raise ValueError("n must be positive or None") self.n = n diff --git a/src/lenskit/metrics/ranking/_dcg.py b/src/lenskit/metrics/ranking/_dcg.py index 69efd8d62..7ca655cd5 100644 --- a/src/lenskit/metrics/ranking/_dcg.py +++ b/src/lenskit/metrics/ranking/_dcg.py @@ -78,12 +78,11 @@ def __init__( self, n: int | None = None, *, - k: int | None = None, weight: RankWeight = LogRankWeight(), discount: Discount | None = None, gain: str | None = None, ): - super().__init__(n, k=k) + super().__init__(n) self.weight = weight self.discount = discount if discount is not None: @@ -174,12 +173,11 @@ def __init__( self, n: int | None = None, *, - k: int | None = None, weight: RankWeight = LogRankWeight(), discount: Discount | None = None, gain: str | None = None, ): - super().__init__(n, k=k) + super().__init__(n) self.weight = weight self.discount = discount if discount is not None: diff --git a/src/lenskit/metrics/ranking/_gini.py b/src/lenskit/metrics/ranking/_gini.py index 27de0c62f..832b037f6 100644 --- a/src/lenskit/metrics/ranking/_gini.py +++ b/src/lenskit/metrics/ranking/_gini.py @@ -37,10 +37,9 @@ def __init__( self, n: int | None = None, *, - k: int | None = None, items: Vocabulary | Dataset, ): - super().__init__(n, k=k) + super().__init__(n) if isinstance(items, Dataset): self.item_vocab = items.items else: @@ -100,11 +99,10 @@ def __init__( self, n: int | None = None, *, - k: int | None = None, items: Vocabulary | Dataset, weight: RankWeight = GeometricRankWeight(), ): - super().__init__(n=n, k=k, items=items) + super().__init__(n=n, items=items) self.weight = weight @override diff --git a/src/lenskit/metrics/ranking/_pop.py b/src/lenskit/metrics/ranking/_pop.py index 949ad80c8..21cfdcd40 100644 --- a/src/lenskit/metrics/ranking/_pop.py +++ b/src/lenskit/metrics/ranking/_pop.py @@ -51,10 +51,9 @@ def __init__( data: Dataset, *, n: int | None = None, - k: int | None = None, count: Literal["users", "interactions"] = "users", ): - super().__init__(n, k=k) + super().__init__(n) stats = data.item_stats() match count: case "users": diff --git a/src/lenskit/metrics/ranking/_rbp.py b/src/lenskit/metrics/ranking/_rbp.py index 772985dc1..c75a12c1c 100644 --- a/src/lenskit/metrics/ranking/_rbp.py +++ b/src/lenskit/metrics/ranking/_rbp.py @@ -104,13 +104,12 @@ def __init__( self, n: int | None = None, *, - k: int | None = None, weight: RankWeight | None = None, patience: float = 0.85, normalize: bool = False, weight_field: str | None = None, ): - super().__init__(n, k=k) + super().__init__(n) self.patience = patience if weight is None and weight_field is None: weight = GeometricRankWeight(patience)