Compute the Bayesian personalised ranking (BPR) loss for implicit feedback.
Many systems only see clicks or views, never explicit ratings. BPR does not try
to predict a rating. It learns to rank: for a user u, an item p they
interacted with should score higher than an item n they did not. The score of
an item is the dot product of the user and item vectors. The loss for one
triple is
x = u . p - u . n
loss = -log(sigmoid(x)) = log(1 + exp(-x))
Return the mean loss over the batch of triples. Compute log(1 + exp(-x)) in a
stable way, for example with np.logaddexp(0, -x), so that large negative x
does not overflow.
def bpr_loss(user_vecs, pos_vecs, neg_vecs):
Input
bpr_loss(np.array([[1.0, 0.0]]), np.array([[1.0, 0.0]]), np.array([[0.0, 1.0]]))
Output
0.31326169
Reasoning
The positive item scores 1 and the negative item scores 0, so x = 1.
log(1 + exp(-1)) = 0.3133. When the positive item wins by a wide margin the
loss goes to 0. When the two items tie, the loss is log 2.
(batch, k). Row b of each forms one triple.Check runs the visible cases against a fresh kernel. Submit runs the hidden ones too.
⇧↵run cell