Skip to main content

LTP

Group recommendations that are fair over time. If a member loses out this session, LTP prioritizes them next session — keeping result-level proportionality across a sequence of sessions while preserving group utility.

PyPI CI License: MIT Paper

Group recommender systems must balance conflicting member preferences, and within a single recommendation it's often impossible to be fair to everyone. But group decisions usually happen over several sessions — so fairness can be balanced across them. LTP (Long-Term Proportionality) does exactly that: it carries per-member fairness state between sessions and selects proportionally, so no member is consistently overlooked.

Algorithm: Patrik Dokoupil & Ladislav Peska (KAIS '26, see Citing). This implementation: Patrik Dokoupil — a standalone, packaged reimplementation.

Install

pip install ltp-rs

Quick start

Create one LTP per group; call recommend once per session — the fairness state carries across calls.

import numpy as np
from ltp import LTP

agg = LTP(gamma=1.0, beta=0.0)          # one aggregator per group

for session in range(n_sessions):
    # ratings[m, i] = predicted rating of item i for group member m, this session
    ratings = your_model.predict(group, session)     # shape (n_members, n_items)
    recommendation = agg.recommend(ratings, k=10)    # -> item indices

agg.reset()                              # start a fresh group

Items recommended in earlier sessions are not repeated (toggle with avoid_repeats=False).

What you can tune

  • gamma — memory of past sessions (1.0 = full; < 1.0 gradually forgets).
  • beta — in-list position discount; item at position p updates state with weight exp(-beta·p) (0.0 = all positions equal).
  • tie_breaking — fairness nudge when items score near-equally.
  • member_weights — relative importance of members (the paper's user weights w; default uniform).
  • normalize — per-member scaling each session: None, "minmax", "standard", "robust", "quantile".

How it works

Each session, LTP runs RLProp's mandate-allocation step over the group members (members play the role of "objectives"), but seeded with each member's accumulated gains from previous sessions, averaged by the number of sessions. A member who has been under-served carries a larger unfilled mandate and is favored until balance is restored. See the paper for the algorithm, the simulated-choice evaluation, and the fairness/utility trade-off.

python examples/quickstart.py shows cumulative per-member utility staying far more balanced under LTP than under a per-session additive baseline.

Relation to RLProp

LTP is the sequential, group generalization of RLProp: a single session of LTP with gamma=1, beta=0 is exactly RLProp over the group members. This package reuses RLProp's allocation kernel (rlprop.core.rlprop_step) and normalizers, so the two stay numerically consistent (a test asserts the single-session equivalence).

Citing

If you use this software, please cite the paper (GitHub's "Cite this repository" button reads CITATION.cff):

@article{dokoupil2026ltp,
  author  = {Dokoupil, Patrik and Peska, Ladislav},
  title   = {Long-term fairness in sequential group recommendations},
  journal = {Knowledge and Information Systems},
  volume  = {68},
  number  = {1},
  year    = {2026},
  doi     = {10.1007/s10115-025-02642-9}
}

License

MIT — see LICENSE.

Metadata

Release files for ltp-rs 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ltp-rs 0.1.0
File Size Uploaded
ltp_rs-0.1.0.tar.gz 9.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ltp-rs 0.1.0
File Interpreter ABI Platform
ltp_rs-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 16.1 kB

Release files / ltp_rs-0.1.0.tar.gz

Download URL ltp_rs-0.1.0.tar.gz
Size 9.1 kB
Tags Source
SHA-256 checksum
How to use checksums
205509741fd65575f456837b60ef23c5de65d653e2dbb28663093894c87ff663
BLAKE2b-256 checksum
How to use checksums
bbbde9729cb408cc9e2efcba998fa2c912934a038d3e6c9152d1a7d29d8a6661
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.12

Release files / ltp_rs-0.1.0-py3-none-any.whl

Download URL ltp_rs-0.1.0-py3-none-any.whl
Size 7.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3207e60b45f765e3545b162fdc558a853c236a8a9cb07a7aa979ae7ed519af65
BLAKE2b-256 checksum
How to use checksums
84c2482ec26b8a5081933917c0125f9ccd5aa524d4623277978614a94b167b76
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.12

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page