Anton Pembek · Anton Klenitskiy · Alexander Savchenko · Alexey Vasilev
Popularity bias is a well-known challenge in recommender systems, often leading to the over-exposure of popular items and reduced catalog coverage. In this work, we propose PR-entmax, a sparse prior-regularized objective that makes popularity correction context-dependent. We derive our method from a generalized variational principle in which an item popularity prior is incorporated directly into a sparse probability mapping, yielding a popularity-aware active support: the set of items receiving non-zero probabilities and hence non-zero gradients is determined jointly by contextual relevance and item popularity. As a result, the prior affects not only item probabilities, but also which items participate in gradient updates during training. The method requires no architectural changes and can be integrated into existing training pipelines by modifying only the loss function. At inference time, the prior term is removed, and items are ranked by the learned contextual relevance alone. Experiments across multiple benchmark datasets and sequential recommendation architectures show that PR-entmax consistently reduces popularity bias while preserving or improving recommendation relevance, advancing the relevance-debiasing trade-off.
Illustration of the PR-entmax training pipeline. For each item, the contextual logit produced by the backbone model is combined with the corresponding popularity prior. The resulting scores are transformed by entmax into a sparse, popularity-aware output distribution. The active support of this distribution determines which items receive non-zero gradients during training.
PR-entmax introduces a popularity-aware sparse training objective.
For each item, the backbone produces a contextual relevance score, which is combined with a fixed popularity prior:
where:
z_i(x)— contextual logit produced by the recommendation model;q_i— item popularity prior estimated from the training data;γ— strength of the popularity correction;θ— temperature parameter;α— entmax sparsity parameter.
The adjusted scores are transformed using entmax:
Unlike softmax, entmax assigns exactly zero probability to part of the catalog. As a result, the popularity prior affects not only item probabilities, but also which items receive non-zero gradients during training.
At inference time, the popularity prior is removed and items are ranked using only the learned contextual relevance:
Experimental results on SASRec for all considered approaches at @10.
Double dagger (‡) marks the best result. Underlined numbers mark the second best. Asterisk (*) denotes a statistically significant improvement over Cross-Entropy for the best model.
| Dataset | Method | NDCG@10 | Novelty@10 | Coverage@10 |
|---|---|---|---|---|
| ML1M | Cross-Entropy | 0.047 | 0.274 | 0.463 |
| IPW | 0.047 | 0.290 | 0.496 | |
| PD | 0.040 | 0.306 | 0.514 | |
| Pop Sampling | 0.049 | 0.286 | 0.489 | |
| Logit Adjustment | 0.047 | 0.291 | 0.496 | |
| PR-entmax | 0.058‡* | 0.331‡* | 0.600‡* | |
| Tmall | Cross-Entropy | 0.274 | 0.657 | 0.351 |
| IPW | 0.265 | 0.704 | 0.431 | |
| PD | 0.249 | 0.705 | 0.332 | |
| Pop Sampling | 0.272 | 0.729‡* | 0.432 | |
| Logit Adjustment | 0.271 | 0.711 | 0.416 | |
| PR-entmax | 0.285‡* | 0.703 | 0.499‡* | |
| Yambda-50M | Cross-Entropy | 0.089 | 0.553 | 0.440 |
| IPW | 0.085 | 0.687‡* | 0.696 | |
| PD | 0.084 | 0.617 | 0.472 | |
| Pop Sampling | 0.092 | 0.647 | 0.668 | |
| Logit Adjustment | 0.089 | 0.626 | 0.550 | |
| PR-entmax | 0.098‡* | 0.671 | 0.785‡* | |
| Yoochoose | Cross-Entropy | 0.203 | 0.606 | 0.753 |
| IPW | 0.191 | 0.655 | 0.832 | |
| PD | 0.188 | 0.645 | 0.768 | |
| Pop Sampling | 0.200 | 0.663‡* | 0.866 | |
| Logit Adjustment | 0.194 | 0.653 | 0.839 | |
| PR-entmax | 0.209‡* | 0.646 | 0.876‡* | |
| Zvuk | Cross-Entropy | 0.218 | 0.550 | 0.163 |
| IPW | 0.199 | 0.655 | 0.182 | |
| PD | 0.199 | 0.618 | 0.176 | |
| Pop Sampling | 0.212 | 0.610 | 0.150 | |
| Logit Adjustment | 0.214 | 0.637 | 0.205 | |
| PR-entmax | 0.222‡* | 0.686‡* | 0.216‡* |
Below we present the trade-off between NDCG@10 and Novelty@10 across different loss functions and hyperparameter configurations for all datasets.
Figure 1: Trade-off between NDCG@10 and Novelty@10 for Tmall dataset.

Figure 2: Trade-off between NDCG@10 and Novelty@10 for Yambda-50M dataset.

Figure 3: Trade-off between NDCG@10 and Novelty@10 for Yoochoose dataset.

Figure 4: Trade-off between NDCG@10 and Novelty@10 for Zvuk dataset.

Install requirements:
pip install -r requirements.txtSpecify environment variables:
# path to the project
export PATH4SEQ="/your/path"
# path to the split data
export RECSYS_DATA_PATH="/your/path"Example of run via command line:
cd runs
# PR-Entmax on Tmall dataset
python dl.py datasets_info=Tmall dataset_params.num_negatives=50000 model_params.num_blocks=2 model_params.num_heads=4 model_params.dropout_rate=0.1 model_params.hidden_units=256 type_loss=entmax temp=1.71 gamma=0.05 seqrec_module.type_correction=logit
# Entmax on Tmall dataset
python dl.py datasets_info=Tmall dataset_params.num_negatives=50000 model_params.num_blocks=2 model_params.num_heads=4 model_params.dropout_rate=0.1 model_params.hidden_units=256 type_loss=entmax temp=1.71
# Logit Adjustment on Tmall dataset
python dl.py datasets_info=Tmall dataset_params.num_negatives=50000 model_params.num_blocks=3 model_params.num_heads=4 model_params.dropout_rate=0.1 model_params.hidden_units=256 type_loss=ce temp=1 seqrec_module.type_correction=logit gamma=0.4
# IPW on Tmall dataset
python dl.py datasets_info=Tmall dataset_params.num_negatives=50000 model_params.num_blocks=3 model_params.num_heads=4 model_params.dropout_rate=0.1 model_params.hidden_units=256 type_loss=ce temp=1 seqrec_module.type_correction=ipw gamma=0.75
# Pop Sampling on Tmall dataset
python dl.py datasets_info=Tmall dataset_params.num_negatives=50000 model_params.num_blocks=3 model_params.num_heads=4 model_params.dropout_rate=0.1 model_params.hidden_units=256 type_loss=ce temp=1 dataset_params.gamma=0.9
# PD on Tmall dataset
python dl.py datasets_info=Tmall dataset_params.num_negatives=50000 model_params.num_blocks=3 model_params.num_heads=4 model_params.dropout_rate=0.1 model_params.hidden_units=256 type_loss=ce temp=1 seqrec_module.type_correction=pd gamma=0.15
# Cross-Entropy on Tmall dataset
python dl.py datasets_info=Tmall dataset_params.num_negatives=50000 model_params.num_blocks=3 model_params.num_heads=4 model_params.dropout_rate=0.1 model_params.hidden_units=256 type_loss=ce temp=1
#Parameter tuning for Tmall with ce loss
python optuna_rec.py datasets_info=Tmall type_loss=ce --multirun
#Parameter tuning for Tmall with entmax loss
python optuna_rec.py datasets_info=Tmall type_loss=entmax --multirun
The main SASRec experiments can be reproduced using the provided script:
cd runs
sh run.sh