From e8065a006bc2766ec21504bec0c3082f48bf3989 Mon Sep 17 00:00:00 2001 From: Weishu Zhang Date: Thu, 2 Apr 2026 22:33:11 -0700 Subject: [PATCH] fix: add epsilon to prevent ZeroDivisionError in BPR-based models The BPR zero-division fix (+ 1e-8) was previously applied to recom_bpr.pyx but not to other models that use the same pattern: - cornac/models/companion/recom_companion.pyx - cornac/models/comparer/recom_comparer_sub.pyx - cornac/models/lrppm/recom_lrppm.pyx When all samples are skipped (e.g., on very small datasets), the denominator (n_samples - skipped) becomes 0, causing a ZeroDivisionError during training progress display. Related to #675 --- cornac/models/companion/recom_companion.pyx | 2 +- cornac/models/comparer/recom_comparer_sub.pyx | 2 +- cornac/models/lrppm/recom_lrppm.pyx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cornac/models/companion/recom_companion.pyx b/cornac/models/companion/recom_companion.pyx index c2bba091..32c9047b 100644 --- a/cornac/models/companion/recom_companion.pyx +++ b/cornac/models/companion/recom_companion.pyx @@ -497,7 +497,7 @@ class Companion(Recommender): progress.set_postfix({ "loss": "%.2f" % (loss / 3 / self.n_element_samples), "bpr_loss": "%.2f" % (bpr_loss / self.n_bpr_samples), - "correct": "%.2f%%" % (100.0 * correct / (self.n_bpr_samples - skipped)), + "correct": "%.2f%%" % (100.0 * correct / (self.n_bpr_samples - skipped + 1e-8)), "skipped": "%.2f%%" % (100.0 * skipped / self.n_bpr_samples), }) diff --git a/cornac/models/comparer/recom_comparer_sub.pyx b/cornac/models/comparer/recom_comparer_sub.pyx index 9b2bf661..5d5d7b4d 100644 --- a/cornac/models/comparer/recom_comparer_sub.pyx +++ b/cornac/models/comparer/recom_comparer_sub.pyx @@ -472,7 +472,7 @@ class ComparERSub(MTER): progress.set_postfix({ "loss": "%.2f" % (loss / 3 / self.n_element_samples), "bpr_loss": "%.2f" % (bpr_loss / self.n_bpr_samples), - "correct": "%.2f%%" % (100.0 * correct / (self.n_bpr_samples - skipped)), + "correct": "%.2f%%" % (100.0 * correct / (self.n_bpr_samples - skipped + 1e-8)), "skipped": "%.2f%%" % (100.0 * skipped / self.n_bpr_samples) }) diff --git a/cornac/models/lrppm/recom_lrppm.pyx b/cornac/models/lrppm/recom_lrppm.pyx index 236da8ac..3e87c12a 100644 --- a/cornac/models/lrppm/recom_lrppm.pyx +++ b/cornac/models/lrppm/recom_lrppm.pyx @@ -331,7 +331,7 @@ class LRPPM(Recommender): "loss": "%.2f" % (loss / self.n_samples), "ranking_loss": "%.2f" % (ranking_loss / (self.n_ranking_samples - skipped)), "r_loss": "%.2f" % (r_loss / (self.n_ranking_samples - skipped)), - "correct": "%.2f%%" % (100.0 * correct / (self.n_ranking_samples - skipped)), + "correct": "%.2f%%" % (100.0 * correct / (self.n_ranking_samples - skipped + 1e-8)), "skipped": "%.2f%%" % (100.0 * skipped / self.n_ranking_samples) }) if (