Skip to content

Commit

Permalink
Merge pull request #566 from mdekstrand/feature/rename-scorer
Browse files Browse the repository at this point in the history
Rename scorers to consistently be called 'Scorer'
  • Loading branch information
mdekstrand authored Dec 21, 2024
2 parents 0721094 + af8d677 commit a33f6ff
Show file tree
Hide file tree
Showing 16 changed files with 80 additions and 78 deletions.
8 changes: 4 additions & 4 deletions docs/guide/GettingStarted.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"metadata": {},
"outputs": [],
"source": [
"from lenskit.als import BiasedMF\n",
"from lenskit.als import BiasedMFScorer\n",
"from lenskit.batch import recommend\n",
"from lenskit.data import ItemListCollection, UserIDKey, load_movielens\n",
"from lenskit.knn import ItemKNNScorer\n",
Expand Down Expand Up @@ -184,7 +184,7 @@
"outputs": [],
"source": [
"model_ii = ItemKNNScorer(20)\n",
"model_als = BiasedMF(50)"
"model_als = BiasedMFScorer(50)"
]
},
{
Expand Down Expand Up @@ -6145,7 +6145,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"display_name": "dev-full",
"language": "python",
"name": "python3"
},
Expand All @@ -6159,7 +6159,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
"version": "3.12.8"
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/pipeline.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ matrix factorization:

.. code:: python
als = ImplicitMF(50)
als = ImplicitMFScorer(50)
pipe = topn_pipeline(als)
The :class:`RecPipelineBuilder` class provides a more flexible mechanism to
Expand All @@ -73,7 +73,7 @@ that class, do:

.. code:: python
als = ImplicitMF(50)
als = ImplicitMFScorer(50)
builder = RecPipelineBuilder()
builder.scorer(als)
pipe = builder.build('ALS')
Expand Down
6 changes: 3 additions & 3 deletions docs/old/mf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ LensKit provides alternating least squares implementations of matrix factorizati
for explicit feedback data. These implementations are parallelized with Numba, and perform
best with the MKL from Conda.

.. autoclass:: BiasedMF
.. autoclass:: BiasedMFScorer
:show-inheritance:
:members:

.. autoclass:: ImplicitMF
.. autoclass:: ImplicitMFScorer
:show-inheritance:
:members:

Expand All @@ -47,7 +47,7 @@ SciKit SVD
This code implements a traditional SVD using scikit-learn. It requires ``scikit-learn`` to
be installed in order to function.

.. autoclass:: BiasedSVD
.. autoclass:: BiasedSVDScorer
:show-inheritance:
:members:

Expand Down
2 changes: 1 addition & 1 deletion docs/releases/2025.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ however, documented here.
(:math:`1.75 \times 10^{-38}`).
* The :mod:`implicit` bridge algorithms no longer look at rating values when
they are present.
* Bias is no longer optional for :class:`~lenksit.als.BiasedMF` and
* Bias is no longer optional for :class:`~lenksit.als.BiasedMFScorer` and
:class:`~lenskit.funksvd.FunkSVD`; both are inherently biased models, and
FunkSVD is not commonly used.

Expand Down
2 changes: 1 addition & 1 deletion lenskit-funksvd/lenskit/funksvd.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def _align_add_bias(bias, index, keys, series):
return bias, series


class FunkSVD(Component, Trainable):
class FunkSVDScorer(Component, Trainable):
"""
Algorithm class implementing FunkSVD matrix factorization. FunkSVD is a regularized
biased matrix factorization technique trained with featurewise stochastic gradient
Expand Down
22 changes: 11 additions & 11 deletions lenskit-funksvd/tests/test_funksvd.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from lenskit.data import Dataset, ItemList, from_interactions_df
from lenskit.data.bulk import dict_to_df, iter_item_lists
from lenskit.funksvd import FunkSVD
from lenskit.funksvd import FunkSVDScorer
from lenskit.metrics import call_metric, quick_measure_model
from lenskit.util.test import ml_100k, ml_ds, wantjit # noqa: F401

Expand All @@ -28,7 +28,7 @@


def test_fsvd_basic_build():
algo = FunkSVD(20, iterations=20)
algo = FunkSVDScorer(20, iterations=20)
algo.train(simple_ds)

assert algo.bias_ is not None
Expand All @@ -38,7 +38,7 @@ def test_fsvd_basic_build():


def test_fsvd_clamp_build():
algo = FunkSVD(20, iterations=20, range=(1, 5))
algo = FunkSVDScorer(20, iterations=20, range=(1, 5))
algo.train(simple_ds)

assert algo.bias_ is not None
Expand All @@ -48,7 +48,7 @@ def test_fsvd_clamp_build():


def test_fsvd_predict_basic():
algo = FunkSVD(20, iterations=20)
algo = FunkSVDScorer(20, iterations=20)
algo.train(simple_ds)

assert algo.bias_ is not None
Expand All @@ -66,7 +66,7 @@ def test_fsvd_predict_basic():


def test_fsvd_predict_clamp():
algo = FunkSVD(20, iterations=20, range=(1, 5))
algo = FunkSVDScorer(20, iterations=20, range=(1, 5))
algo.train(simple_ds)

assert algo.bias_ is not None
Expand All @@ -84,7 +84,7 @@ def test_fsvd_predict_clamp():


def test_fsvd_predict_bad_item():
algo = FunkSVD(20, iterations=20)
algo = FunkSVDScorer(20, iterations=20)
algo.train(simple_ds)

assert algo.bias_ is not None
Expand All @@ -101,7 +101,7 @@ def test_fsvd_predict_bad_item():


def test_fsvd_predict_bad_item_clamp():
algo = FunkSVD(20, iterations=20, range=(1, 5))
algo = FunkSVDScorer(20, iterations=20, range=(1, 5))
algo.train(simple_ds)

assert algo.bias_ is not None
Expand All @@ -118,7 +118,7 @@ def test_fsvd_predict_bad_item_clamp():


def test_fsvd_predict_bad_user():
algo = FunkSVD(20, iterations=20)
algo = FunkSVDScorer(20, iterations=20)
algo.train(simple_ds)

assert algo.bias_ is not None
Expand All @@ -137,7 +137,7 @@ def test_fsvd_predict_bad_user():
@wantjit
@mark.slow
def test_fsvd_save_load(ml_ds: Dataset):
original = FunkSVD(20, iterations=20)
original = FunkSVDScorer(20, iterations=20)
original.train(ml_ds)

assert original.bias_ is not None
Expand All @@ -163,7 +163,7 @@ def test_fsvd_save_load(ml_ds: Dataset):
@wantjit
@mark.slow
def test_fsvd_known_preds(ml_ds: Dataset):
algo = FunkSVD(15, iterations=125, lrate=0.001)
algo = FunkSVDScorer(15, iterations=125, lrate=0.001)
_log.info("training %s on ml data", algo)
algo.train(ml_ds)

Expand Down Expand Up @@ -195,7 +195,7 @@ def test_fsvd_known_preds(ml_ds: Dataset):
@mark.eval
def test_fsvd_batch_accuracy(ml_100k: pd.DataFrame):
ds = from_interactions_df(ml_100k)
results = quick_measure_model(FunkSVD(25, 125, damping=10), ds, predicts_ratings=True)
results = quick_measure_model(FunkSVDScorer(25, 125, damping=10), ds, predicts_ratings=True)

assert results.global_metrics().loc["MAE"] == approx(0.74, abs=0.025)
assert results.list_summary().loc["RMSE", "mean"] == approx(0.92, abs=0.05)
2 changes: 1 addition & 1 deletion lenskit-hpf/lenskit/hpf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
_logger = logging.getLogger(__name__)


class HPF(Component, Trainable):
class HPFScorer(Component, Trainable):
"""
Hierarchical Poisson factorization, provided by
`hpfrec <https://hpfrec.readthedocs.io/en/latest/>`_.
Expand Down
4 changes: 2 additions & 2 deletions lenskit-hpf/tests/test_hpf.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

@mark.slow
def test_hpf_train_large(tmp_path, ml_ratings):
algo = hpf.HPF(20)
algo = hpf.HPFScorer(20)
ratings = ml_ratings.assign(rating=ml_ratings.rating + 0.5)
ds = from_interactions_df(ratings)
algo.train(ds)
Expand Down Expand Up @@ -56,7 +56,7 @@ def test_hpf_train_large(tmp_path, ml_ratings):

@mark.slow
def test_hpf_train_binary(tmp_path, ml_ratings):
algo = hpf.HPF(20)
algo = hpf.HPFScorer(20)
ratings = ml_ratings.drop(columns=["timestamp", "rating"])
ds = from_interactions_df(ratings)
algo.train(ds)
Expand Down
4 changes: 2 additions & 2 deletions lenskit-sklearn/lenskit/sklearn/svd.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
_log = logging.getLogger(__name__)


class BiasedSVD(Component, Trainable):
class BiasedSVDScorer(Component, Trainable):
"""
Biased matrix factorization for implicit feedback using SciKit-Learn's SVD
solver (:class:`sklearn.decomposition.TruncatedSVD`). It operates by first
computing the bias, then computing the SVD of the bias residuals.
You'll generally want one of the iterative SVD implementations such as
:class:`lennskit.algorithms.als.BiasedMF`; this is here primarily as an
:class:`lennskit.algorithms.als.BiasedMFScorer`; this is here primarily as an
example and for cases where you want to evaluate a pure SVD implementation.
"""

Expand Down
12 changes: 6 additions & 6 deletions lenskit-sklearn/tests/test_svd.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

@need_skl
def test_svd_basic_build():
algo = svd.BiasedSVD(2)
algo = svd.BiasedSVDScorer(2)
algo.train(simple_ds)

assert algo.user_components_.shape == (3, 2)
Expand All @@ -37,7 +37,7 @@ def test_svd_basic_build():
@need_skl
def test_svd_predict_basic():
_log.info("SVD input data:\n%s", simple_df)
algo = svd.BiasedSVD(2, damping=0)
algo = svd.BiasedSVDScorer(2, damping=0)
algo.train(simple_ds)
_log.info("user means:\n%s", str(algo.bias_.user_biases))
_log.info("item means:\n%s", str(algo.bias_.item_biases))
Expand All @@ -54,7 +54,7 @@ def test_svd_predict_basic():

@need_skl
def test_svd_predict_bad_item():
algo = svd.BiasedSVD(2)
algo = svd.BiasedSVDScorer(2)
algo.train(simple_ds)

preds = algo(10, ItemList([4]))
Expand All @@ -67,7 +67,7 @@ def test_svd_predict_bad_item():

@need_skl
def test_svd_predict_bad_user():
algo = svd.BiasedSVD(2)
algo = svd.BiasedSVDScorer(2)
algo.train(simple_ds)

preds = algo(50, ItemList([3]))
Expand All @@ -81,7 +81,7 @@ def test_svd_predict_bad_user():
@need_skl
@mark.slow
def test_svd_save_load(ml_ds: Dataset):
original = svd.BiasedSVD(20)
original = svd.BiasedSVDScorer(20)
original.train(ml_ds)

mod = pickle.dumps(original)
Expand All @@ -99,7 +99,7 @@ def test_svd_save_load(ml_ds: Dataset):
@mark.eval
def test_svd_batch_accuracy(rng, ml_100k: pd.DataFrame):
data = from_interactions_df(ml_100k)
svd_algo = svd.BiasedSVD(25, damping=10)
svd_algo = svd.BiasedSVDScorer(25, damping=10)
results = quick_measure_model(svd_algo, data, predicts_ratings=True, rng=rng)

assert results.global_metrics()["MAE"] == approx(0.71, abs=0.025)
Expand Down
6 changes: 3 additions & 3 deletions lenskit/lenskit/als/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"""

from ._common import ALSBase
from ._explicit import BiasedMF
from ._implicit import ImplicitMF
from ._explicit import BiasedMFScorer
from ._implicit import ImplicitMFScorer

__all__ = ["ALSBase", "BiasedMF", "ImplicitMF"]
__all__ = ["ALSBase", "BiasedMFScorer", "ImplicitMFScorer"]
4 changes: 2 additions & 2 deletions lenskit/lenskit/als/_explicit.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
_log = logging.getLogger(__name__)


class BiasedMF(ALSBase):
class BiasedMFScorer(ALSBase):
"""
Biased matrix factorization trained with alternating least squares
:cite:p:`zhouLargeScaleParallelCollaborative2008`. This is a
Expand Down Expand Up @@ -143,7 +143,7 @@ def finalize_scores(
return ItemList(items, scores=scores)

def __str__(self):
return "als.BiasedMF(features={}, regularization={})".format(self.features, self.reg)
return "als.BiasedMFScorer(features={}, regularization={})".format(self.features, self.reg)


@torch.jit.script
Expand Down
18 changes: 9 additions & 9 deletions lenskit/lenskit/als/_implicit.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
_log = logging.getLogger(__name__)


class ImplicitMF(ALSBase):
class ImplicitMFScorer(ALSBase):
"""
Implicit matrix factorization trained with alternating least squares
:cite:p:`hu:implicit-mf`. This algorithm outputs
'predictions', but they are not on a meaningful scale. If its input data
contains ``rating`` values, these will be used as the 'confidence' values;
otherwise, confidence will be 1 for every rated item.
:cite:p:`hu:implicit-mf`. This algorithm outputs 'predictions', but they
are not on a meaningful scale. If its input data contains ``rating``
values, these will be used as the 'confidence' values; otherwise, confidence
will be 1 for every rated item.
See the base class :class:`.MFPredictor` for documentation on the estimated
parameters you can extract from a trained model.
Expand All @@ -40,7 +40,7 @@ class ImplicitMF(ALSBase):
\\times n` matrix of all 1s.
.. versionchanged:: 2025.1
``ImplicitMF`` no longer supports multiple training methods. It always uses
``ImplicitMFScorer`` no longer supports multiple training methods. It always uses
Cholesky decomposition now.
.. versionchanged:: 0.14
Expand Down Expand Up @@ -68,8 +68,8 @@ class ImplicitMF(ALSBase):
used, and multipled by ``weight``; if ``False``, ImplicitMF treats
every rated user-item pair as having a rating of 1.\
save_user_feature:
Whether to save the user feature vector in the model, or recompute it at
scoring time.
Whether to save the user feature vector in the model, or recompute
it at scoring time.
rng:
Random number seed or generator.
"""
Expand Down Expand Up @@ -160,7 +160,7 @@ def new_user_embedding(
return u_feat, None

def __str__(self):
return "als.ImplicitMF(features={}, reg={}, w={})".format(
return "als.ImplicitMFScorer(features={}, reg={}, w={})".format(
self.features, self.reg, self.weight
)

Expand Down
Loading

0 comments on commit a33f6ff

Please sign in to comment.