Skip to content

Commit

Permalink
fix .rank() method for multiple models
Browse files Browse the repository at this point in the history
  • Loading branch information
hieuddo committed Apr 22, 2024
1 parent cbdc8f2 commit 1b50cbd
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 15 deletions.
20 changes: 10 additions & 10 deletions cornac/models/comparer/recom_comparer_obj.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -663,39 +663,39 @@ class ComparERObj(Recommender):
item_score = self.U2[item_id, :].dot(self.U1[user_id, :]) + self.H2[item_id, :].dot(self.H1[user_id, :])
return item_score

def rank(self, user_id, item_ids=None):
def rank(self, user_idx, item_indices=None, **kwargs):
"""Rank all test items for a given user.
Parameters
----------
user_id: int, required
user_idx: int, required
The index of the user for whom to perform item raking.
item_ids: 1d array, optional, default: None
item_indices: 1d array, optional, default: None
A list of candidate item indices to be ranked by the user.
If `None`, list of ranked known item indices and their scores will be returned
Returns
-------
Tuple of `item_rank`, and `item_scores`. The order of values
in item_scores are corresponding to the order of their ids in item_ids
in item_scores are corresponding to the order of their ids in item_indices
"""
X_ = self.U1[user_id, :].dot(self.V.T)
X_ = self.U1[user_idx, :].dot(self.V.T)
most_cared_aspects_indices = (-X_).argsort()[:self.num_most_cared_aspects]
most_cared_X_ = X_[most_cared_aspects_indices]
most_cared_Y_ = self.U2.dot(self.V[most_cared_aspects_indices, :].T)
explicit_scores = most_cared_X_.dot(most_cared_Y_.T) / (self.num_most_cared_aspects * self.rating_scale)
item_scores = self.alpha * explicit_scores + (1 - self.alpha) * self.score(user_id)
item_scores = self.alpha * explicit_scores + (1 - self.alpha) * self.score(user_idx)

if item_ids is None:
if item_indices is None:
item_scores = item_scores
item_rank = item_scores.argsort()[::-1]
else:
num_items = max(self.num_items, max(item_ids) + 1)
num_items = max(self.num_items, max(item_indices) + 1)
item_scores = np.ones(num_items) * np.min(item_scores)
item_scores[:self.num_items] = item_scores
item_rank = item_scores.argsort()[::-1]
item_rank = intersects(item_rank, item_ids, assume_unique=True)
item_scores = item_scores[item_ids]
item_rank = intersects(item_rank, item_indices, assume_unique=True)
item_scores = item_scores[item_indices]
return item_rank, item_scores
2 changes: 1 addition & 1 deletion cornac/models/comparer/recom_comparer_sub.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ class ComparERSub(MTER):

return correct, skipped, loss, bpr_loss

def rank(self, user_idx, item_indices=None):
def rank(self, user_idx, item_indices=None, **kwargs):
if self.alpha > 0 and self.n_top_aspects > 0:
n_top_aspects = min(self.n_top_aspects, self.num_aspects)
ts1 = np.einsum("abc,a->bc", self.G1, self.U[user_idx])
Expand Down
2 changes: 1 addition & 1 deletion cornac/models/efm/recom_efm.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ class EFM(Recommender):
item_score = self.U2[item_idx, :].dot(self.U1[user_idx, :]) + self.H2[item_idx, :].dot(self.H1[user_idx, :])
return item_score

def rank(self, user_idx, item_indices=None):
def rank(self, user_idx, item_indices=None, **kwargs):
"""Rank all test items for a given user.
Parameters
Expand Down
2 changes: 1 addition & 1 deletion cornac/models/lrppm/recom_lrppm.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ class LRPPM(Recommender):
item_score = self.I[i_idx].dot(self.U[u_idx])
return item_score

def rank(self, user_idx, item_indices=None):
def rank(self, user_idx, item_indices=None, **kwargs):
if self.alpha > 0 and self.num_top_aspects > 0:
n_items = self.num_items
num_top_aspects = min(self.num_top_aspects, self.num_aspects)
Expand Down
6 changes: 4 additions & 2 deletions cornac/models/recommender.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ def rate(self, user_idx, item_idx, clipping=True):

return rating_pred

def rank(self, user_idx, item_indices=None, k=-1, **kwargs):
def rank(self, user_idx, item_indices=None, **kwargs):
"""Rank all test items for a given user.
Parameters
Expand All @@ -485,7 +485,7 @@ def rank(self, user_idx, item_indices=None, k=-1, **kwargs):
A list of candidate item indices to be ranked by the user.
If `None`, list of ranked known item indices and their scores will be returned.
k: int, required
k: int, optional
Cut-off length for recommendations, k=-1 will return ranked list of all items.
This is more important for ANN to know the limit to avoid exhaustive ranking.
Expand All @@ -502,6 +502,8 @@ def rank(self, user_idx, item_indices=None, k=-1, **kwargs):
except ScoreException:
known_item_scores = np.ones(self.total_items) * self.default_score()

k = kwargs.get("k", -1)

# check if the returned scores also cover unknown items
# if not, all unknown items will be given the MIN score
if len(known_item_scores) == self.total_items:
Expand Down

0 comments on commit 1b50cbd

Please sign in to comment.