class CBFRecomender: def __init__(self, knn_artist=25, knn_album=45, shrink_artist=0, shrink_album=8, weight_artist=0.15): self.knn_artist = knn_artist self.knn_album = knn_album self.shrink_artist = shrink_artist self.shrink_album = shrink_album self.weight_artist = weight_artist self.helper = Helper() def compute_similarity_cbf(self, ICM, top_k, shrink, normalize=True, similarity="cosine"): #Compute similarities for weighted features recommender similarity_object = Compute_Similarity_Python(ICM.T, shrink=shrink, topK=top_k, normalize=normalize, similarity=similarity) w_sparse = similarity_object.compute_similarity() return w_sparse def fit(self, URM): # URM Loading self.URM = URM # Load ICMs from helper self.ICM_artist = self.helper.load_icm_artist() self.ICM_artist = self.helper.tfidf_normalization(self.ICM_artist) self.ICM_artist = self.helper.sklearn_normalization(self.ICM_artist) self.ICM_album = self.helper.load_icm_album() self.ICM_album = self.helper.bm25_normalization(self.ICM_album) # Computing SMs self.SM_artist = self.compute_similarity_cbf(self.ICM_artist, top_k=self.knn_artist, shrink=self.shrink_artist) self.SM_album = self.compute_similarity_cbf(self.ICM_album, top_k=self.knn_album, shrink=self.shrink_album) def compute_scores(self, playlist_id): tracks_list_train = self.URM[playlist_id] scores_artist = tracks_list_train.dot(self.SM_artist).toarray().ravel() scores_album = tracks_list_train.dot(self.SM_album).toarray().ravel() weight_album = 1 - self.weight_artist scores = (scores_artist * self.weight_artist) + (scores_album * weight_album) return scores def recommend(self, playlist_id, at=10, exclude_seen=True): # Compute scores of the recommendation scores = self.compute_scores(playlist_id) # Filter to exclude already seen items if exclude_seen: scores = self.filter_seen(playlist_id, scores) recommended_items = np.argsort(scores) recommended_items = np.flip(recommended_items, axis=0) return recommended_items[:at] def filter_seen(self, playlist_id, scores): start_pos = self.URM.indptr[playlist_id] end_pos = self.URM.indptr[playlist_id + 1] user_profile = self.URM.indices[start_pos:end_pos] scores[user_profile] = -np.inf return scores
class AssetCBF: def __init__(self, URM): self.URM_train = URM self.helper = Helper() def compute_similarity_cbf(self, ICM, top_k, shrink, normalize=True, similarity="cosine"): # Compute similarities for weighted features recommender similarity_object = Compute_Similarity_Python(ICM.T, shrink=shrink, topK=top_k, normalize=normalize, similarity=similarity) w_sparse = similarity_object.compute_similarity() return w_sparse def fit(self, topK, shrink): self.topK = topK self.shrink = shrink # Load ICMs from helper self.ICM_asset = self.helper.bm25_normalization( self.helper.load_icm_asset()) # Computing SMs self.SM_asset = self.compute_similarity_cbf(self.ICM_asset, top_k=self.topK, shrink=self.shrink) def compute_scores(self, user_id): users_list_train = self.URM_train[user_id] scores_asset = users_list_train.dot(self.SM_asset).toarray().ravel() return scores_asset def recommend(self, user_id, at=10, exclude_seen=True): # Compute scores of the recommendation scores = self.compute_scores(user_id) # Filter to exclude already seen items if exclude_seen: scores = self.filter_seen(user_id, scores) recommended_items = np.argsort(scores) recommended_items = np.flip(recommended_items, axis=0) return recommended_items[:at] def filter_seen(self, user_id, scores): start_pos = self.URM_train.indptr[user_id] end_pos = self.URM_train.indptr[user_id + 1] user_profile = self.URM_train.indices[start_pos:end_pos] scores[user_profile] = -np.inf return scores
class UserCBF(object): RECOMMENDER_NAME = "UserCBF" def __init__(self, URM_train, mode="dataset"): self.URM_train = URM_train self.W_sparse = None self.helper = Helper() self.mode = mode # UCMs loading self.UCM = hstack( [self.helper.load_ucm_age(), self.helper.load_ucm_region()]) self.SM = None self.asymmetric_alpha = 0.5 def get_URM_train(self): return self.URM_train def compute_similarity(self, UCM): similarity_object = Compute_Similarity_Python( UCM.T, shrink=self.shrink, topK=self.topK, normalize=self.normalize, similarity=self.similarity, asymmetric_alpha=self.asymmetric_alpha) return similarity_object.compute_similarity() def fit(self, topK=93 * 5, shrink=1, normalize=True, similarity="dice", asymmetric_alpha=0.5, suppress_interactions=True, bm_25_normalization=False): self.topK = topK self.shrink = shrink self.similarity = similarity self.asymmetric_alpha = asymmetric_alpha self.normalize = normalize if bm_25_normalization: self.UCM = self.helper.bm25_normalization(self.UCM) # Compute similarities self.SM = self.compute_similarity(self.UCM) # If necessary remove similarity with cold users if suppress_interactions: cold_users = Helper().get_cold_user_ids(split=self.mode) # warm_users = Helper().get_warm_user_ids(split=self.mode) self.SM = self.SM.tocsc() # Set to zero all similarities with cold users for cold in cold_users: csc_col_set_nz_to_val(self.SM, cold, 0) # And to remove zeros from the sparsity pattern: self.SM.eliminate_zeros() self.SM.tocsr() def compute_scores(self, user_id): return self.SM[user_id].dot(self.URM_train).toarray().ravel() def recommend(self, user_id, at=10, exclude_seen=True): # Compute scores of the recommendation scores = self.compute_scores(user_id) # Filter to exclude already seen items if exclude_seen: scores = self.filter_seen(user_id, scores) recommended_items = np.argsort(scores) recommended_items = np.flip(recommended_items, axis=0) return recommended_items[:at] def filter_seen(self, user_id, scores): start_pos = self.URM_train.indptr[user_id] end_pos = self.URM_train.indptr[user_id + 1] user_profile = self.URM_train.indices[start_pos:end_pos] scores[user_profile] = -np.inf return scores