Long-Term Proportionality: fair sequential group recommendation via proportional, cross-session selection.
Project description
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.
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 positionpupdates state with weightexp(-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 weightsw; 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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ltp_rs-0.1.0.tar.gz.
File metadata
- Download URL: ltp_rs-0.1.0.tar.gz
- Upload date:
- Size: 9.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
205509741fd65575f456837b60ef23c5de65d653e2dbb28663093894c87ff663
|
|
| MD5 |
07a02e439dd8c80b6309271d5f74b848
|
|
| BLAKE2b-256 |
bbbde9729cb408cc9e2efcba998fa2c912934a038d3e6c9152d1a7d29d8a6661
|
File details
Details for the file ltp_rs-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ltp_rs-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3207e60b45f765e3545b162fdc558a853c236a8a9cb07a7aa979ae7ed519af65
|
|
| MD5 |
8c7e959b1e5961be0d23ecfbb4da0c55
|
|
| BLAKE2b-256 |
84c2482ec26b8a5081933917c0125f9ccd5aa524d4623277978614a94b167b76
|