Skip to content

Commit f877fd3

Browse files
authored
Merge pull request #668 from mdekstrand/feature/flexmf
Add flexible Torch matrix factorizer
2 parents b7b5b03 + 1e2e5f4 commit f877fd3

23 files changed

+1078
-11
lines changed

docs/lenskit.bib

+1-1
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ @article{rbp
600600
abstract = {A range of methods for measuring the effectiveness of information retrieval systems has been proposed. These are typically intended to provide a quantitative single-value summary of a document ranking relative to a query. However, many of these measures have failings {\dots}}
601601
}
602602

603-
@inproceedings{rendleBPRBayesianPersonalized2009,
603+
@inproceedings{BPR,
604604
title = {{{BPR}}: {{Bayesian Personalized Ranking}} from {{Implicit Feedback}}},
605605
booktitle = {{{UAI}} '09},
606606
author = {Rendle, Steffen and Freudenthaler, Christoph and Gantner, Zeno and {Schmidt-Thieme}, Lars},

docs/releases/2025.rst

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ information on how to upgrade your code.
1515
----------------------
1616

1717
- Replace broken “softmax” sampler with a proper stochastic sampler (:pr:`667`).
18+
- :meth:`~lenskit.data.MatrixRelationshipSet.sample_negatives` now accepts
19+
``"popular"`` as an alias for ``"popularity"``.
1820

1921
.. _2025.2.0:
2022

src/lenskit/cli/doctor.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# This file is part of LensKit.
2+
# Copyright (C) 2018-2023 Boise State University
3+
# Copyright (C) 2023-2025 Drexel University
4+
# Licensed under the MIT license, see LICENSE.md for details.
5+
# SPDX-License-Identifier: MIT
6+
17
import os
28
import platform
39
import re

src/lenskit/data/builder.py

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# Copyright (C) 2023-2025 Drexel University
44
# Licensed under the MIT license, see LICENSE.md for details.
55
# SPDX-License-Identifier: MIT
6+
67
"""
78
Data set builder.
89
"""

src/lenskit/data/collection/__init__.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# This file is part of LensKit.
2+
# Copyright (C) 2018-2023 Boise State University
3+
# Copyright (C) 2023-2025 Drexel University
4+
# Licensed under the MIT license, see LICENSE.md for details.
5+
# SPDX-License-Identifier: MIT
6+
17
"""
28
Item list collections.
39
"""

src/lenskit/data/collection/_base.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# This file is part of LensKit.
2+
# Copyright (C) 2018-2023 Boise State University
3+
# Copyright (C) 2023-2025 Drexel University
4+
# Licensed under the MIT license, see LICENSE.md for details.
5+
# SPDX-License-Identifier: MIT
6+
17
from __future__ import annotations
28

39
import warnings

src/lenskit/data/collection/_list.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# This file is part of LensKit.
2+
# Copyright (C) 2018-2023 Boise State University
3+
# Copyright (C) 2023-2025 Drexel University
4+
# Licensed under the MIT license, see LICENSE.md for details.
5+
# SPDX-License-Identifier: MIT
6+
17
import warnings
28
from collections.abc import Iterator, Mapping, Sequence
39
from typing import Any, Generic, overload

src/lenskit/data/mtarray.py

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# Copyright (C) 2023-2025 Drexel University
44
# Licensed under the MIT license, see LICENSE.md for details.
55
# SPDX-License-Identifier: MIT
6+
67
"""
78
Multi-format array layout.
89
"""

src/lenskit/data/relationships.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,9 @@ def torch(self, attribute: str | None = None, *, layout: LAYOUT = "csr") -> torc
390390

391391
def sample_negatives(
392392
self,
393-
rows: np.ndarray[int, np.dtype[np.int32]],
393+
rows: np.ndarray[tuple[int], np.dtype[np.int32]],
394394
*,
395-
weighting: Literal["uniform", "popularity"] = "uniform",
395+
weighting: Literal["uniform", "popular", "popularity"] = "uniform",
396396
n: int | None = None,
397397
verify: bool = True,
398398
max_attempts: int = 10,
@@ -436,10 +436,12 @@ def sample_negatives(
436436
match weighting:
437437
case "uniform":
438438
columns = rng.choice(self.n_cols, size=shape, replace=True)
439-
case "popularity":
439+
case "popular" | "popularity":
440440
ccol = self._table.column(num_col_name(self.col_type)).to_numpy()
441441
trows = rng.choice(self._table.num_rows, size=shape, replace=True)
442442
columns = ccol[trows]
443+
case _:
444+
raise ValueError(f"unknown weighting strategy {weighting}")
443445
columns = np.require(columns, "i4")
444446

445447
if verify:

src/lenskit/flexmf/__init__.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# This file is part of LensKit.
2+
# Copyright (C) 2018-2023 Boise State University
3+
# Copyright (C) 2023-2025 Drexel University
4+
# Licensed under the MIT license, see LICENSE.md for details.
5+
# SPDX-License-Identifier: MIT
6+
7+
"""
8+
Flexible PyTorch matrix factorization models for LensKit.
9+
10+
The components in this package implement several matrix factorization models for
11+
LensKit, and also serve as an example for practical PyTorch recommender
12+
training.
13+
14+
.. stability:: internal
15+
"""
16+
17+
from ._base import FlexMFConfigBase, FlexMFScorerBase
18+
from ._explicit import FlexMFExplicitConfig, FlexMFExplicitScorer
19+
from ._implicit import FlexMFImplicitConfig, FlexMFImplicitScorer
20+
21+
__all__ = [
22+
"FlexMFConfigBase",
23+
"FlexMFScorerBase",
24+
"FlexMFExplicitConfig",
25+
"FlexMFExplicitScorer",
26+
"FlexMFImplicitConfig",
27+
"FlexMFImplicitScorer",
28+
]

0 commit comments

Comments
 (0)