def get_recommendation_for_known_user_batch( self, user_ids: List[UserIdType], cutoff: int = 20, allowed_item_ids: Optional[List[ItemIdType]] = None, per_user_allowed_item_ids: Optional[List[List[ItemIdType]]] = None, forbidden_item_ids: Optional[List[List[ItemIdType]]] = None, n_threads: Optional[int] = None, ) -> List[List[Tuple[ItemIdType, float]]]: """Retrieve recommendation result for a list of known users. Args: user_ids: A list of user ids. cutoff: Maximal number of recommendations allowed. allowed_item_ids: If not ``None``, defines "a list of recommendable item IDs". Ignored if `per_user_allowed_item_ids` is set. per_user_allowed_item_ids: If not ``None``, defines "a list of list of recommendable item IDs" and ``len(allowed_item_ids)`` must be equal to ``score.shape[0]``. Defaults to ``None``. forbidden_item_ids: If not ``None``, defines "a list of list of forbidden item IDs" and ``len(allowed_item_ids)`` must be equal to ``len(item_ids)`` Defaults to ``None``. n_threads: Specifies the number of threads to use for the computation. If ``None``, the environment variable ``"IRSPACK_NUM_THREADS_DEFAULT"`` will be looked up, and if the variable is not set, it will be set to ``os.cpu_count()``. Defaults to None. Returns: A list of list of tuples consisting of ``(item_id, score)``. Each internal list corresponds to the recommender's recommendation output. """ user_indexes: UserIndexArray = np.asarray( [self.user_id_to_index[user_id] for user_id in user_ids], dtype=np.int64 ) score = self.recommender.get_score_remove_seen(user_indexes) return self.score_to_recommended_items_batch( score, cutoff=cutoff, allowed_item_ids=allowed_item_ids, per_user_allowed_item_ids=per_user_allowed_item_ids, forbidden_item_ids=forbidden_item_ids, n_threads=get_n_threads(n_threads=n_threads), )
def get_recommendation_for_new_user_batch( self, user_profiles: Sequence[Union[List[ItemIdType], Dict[ItemIdType, float]]], cutoff: int = 20, allowed_item_ids: Optional[List[ItemIdType]] = None, per_user_allowed_item_ids: Optional[List[List[ItemIdType]]] = None, forbidden_item_ids: Optional[List[List[ItemIdType]]] = None, n_threads: Optional[int] = None, ) -> List[List[Tuple[ItemIdType, float]]]: """Retrieve recommendation result for a previously unseen users using item ids with which they have interacted. Args: user_profiles: A list of user profiles. Each profile should be either the item ids the user had a cotact, or item-rating dict. Previously unseen item IDs will be ignored. cutoff: Maximal number of recommendations allowed. allowed_item_ids: If not ``None``, defines "a list of recommendable item IDs". Ignored if `per_user_allowed_item_ids` is set. per_user_allowed_item_ids: If not ``None``, defines "a list of list of recommendable item IDs" and ``len(allowed_item_ids)`` must be equal to ``score.shape[0]``. Defaults to ``None``. forbidden_item_ids: If not ``None``, defines "a list of list of forbidden item IDs" and ``len(allowed_item_ids)`` must be equal to ``len(item_ids)`` Defaults to ``None``. n_threads: Specifies the number of threads to use for the computation. If ``None``, the environment variable ``"IRSPACK_NUM_THREADS_DEFAULT"`` will be looked up, and if the variable is not set, it will be set to ``os.cpu_count()``. Defaults to None. Returns: A list of list of tuples consisting of ``(item_id, score)``. Each internal list corresponds to the recommender's recommendation output. """ X_input = self._list_of_user_profile_to_matrix(user_profiles) score = self.recommender.get_score_cold_user_remove_seen(X_input) return self.score_to_recommended_items_batch( score, cutoff, allowed_item_ids=allowed_item_ids, per_user_allowed_item_ids=per_user_allowed_item_ids, forbidden_item_ids=forbidden_item_ids, n_threads=get_n_threads(n_threads=n_threads), )
def __init__( self, X: InteractionMatrix, profiles: base.ProfileMatrix, mb_size: int = 1024, n_threads: Optional[int] = None, cutoff: int = 20, ): assert X.shape[0] == profiles.shape[0] self.core = EvaluatorCore(X.astype(np.float64), []) self.profiles = profiles self.n_users = X.shape[0] self.n_items = X.shape[1] self.dim_profile = profiles.shape[1] self.mb_size = mb_size self.n_threads = get_n_threads(n_threads) self.cutoff = cutoff
def __init__( self, ground_truth: InteractionMatrix, offset: int = 0, cutoff: int = 10, target_metric: str = "ndcg", recommendable_items: Optional[List[int]] = None, per_user_recommendable_items: Optional[List[List[int]]] = None, masked_interactions: Optional[InteractionMatrix] = None, n_threads: Optional[int] = None, recall_with_cutoff: bool = False, mb_size: int = 128, ) -> None: ground_truth = ground_truth.tocsr().astype(np.float64) ground_truth.sort_indices() if recommendable_items is None: if per_user_recommendable_items is None: recommendable_items_arg: List[List[int]] = [] else: recommendable_items_arg = per_user_recommendable_items else: recommendable_items_arg = [recommendable_items] self.core = EvaluatorCore(ground_truth, recommendable_items_arg) self.offset = offset self.n_users = ground_truth.shape[0] self.n_items = ground_truth.shape[1] self.target_metric = TargetMetric[target_metric] self.cutoff = cutoff self.target_metric_name = f"{self.target_metric.name}@{self.cutoff}" self.n_threads = get_n_threads(n_threads) self.mb_size = mb_size if masked_interactions is None: self.masked_interactions = None else: if masked_interactions.shape != ground_truth.shape: raise ValueError( "ground_truth and masked_interactions have different shapes. " ) self.masked_interactions = sps.csr_matrix(masked_interactions) self.recall_with_cutoff = recall_with_cutoff
def get_recommendation_for_known_user_batch( self, user_ids: List[Any], cutoff: int = 20, allowed_item_ids: Optional[List[List[Any]]] = None, forbidden_item_ids: Optional[List[List[Any]]] = None, n_threads: Optional[int] = None, ) -> List[List[Tuple[Any, float]]]: """Retrieve recommendation result for a list of known users. Args: user_ids: A list of user ids. cutoff: Maximal number of recommendations allowed. allowed_item_ids: If not ``None``, defines "a list of list of recommendable item IDs" and ``len(allowed_item_ids)`` must be equal to ``len(item_ids)``. Defaults to ``None``. forbidden_item_ids: If not ``None``, defines "a list of list of forbidden item IDs" and ``len(allowed_item_ids)`` must be equal to ``len(item_ids)`` Defaults to ``None``. Returns: A list of list of tuples consisting of ``(item_id, score)``. Each internal list corresponds to the recommender's recommendation output. """ user_indexes: UserIndexArray = np.asarray( [self.user_id_to_index[user_id] for user_id in user_ids], dtype=np.int64) score = self.recommender.get_score_remove_seen(user_indexes) return self._score_to_recommended_items_batch( score, cutoff=cutoff, allowed_item_ids=allowed_item_ids, forbidden_item_ids=forbidden_item_ids, n_threads=get_n_threads(n_threads=n_threads), )
def get_recommendation_for_new_user_batch( self, user_profiles: Sequence[Union[List[Any], Dict[Any, float]]], cutoff: int = 20, allowed_item_ids: Optional[List[List[Any]]] = None, forbidden_item_ids: Optional[List[List[Any]]] = None, n_threads: Optional[int] = None, ) -> List[List[Tuple[Any, float]]]: """Retrieve recommendation result for a previously unseen users using item ids with which they have interacted. Args: user_profiles: A list of user profiles. Each profile should be either the item ids the user had a cotact, or item-rating dict. Previously unseen item IDs will be ignored. cutoff: Maximal number of recommendations allowed. allowed_item_ids: If not ``None``, defines "a list of list of recommendable item IDs" and ``len(allowed_item_ids)`` must be equal to ``len(item_ids)``. Defaults to ``None``. forbidden_item_ids: If not ``None``, defines "a list of list of forbidden item IDs" and ``len(allowed_item_ids)`` must be equal to ``len(item_ids)`` Defaults to ``None``. Returns: A list of list of tuples consisting of ``(item_id, score)``. Each internal list corresponds to the recommender's recommendation output. """ X_input = self._list_of_user_profile_to_matrix(user_profiles) score = self.recommender.get_score_cold_user_remove_seen(X_input) return self._score_to_recommended_items_batch( score, cutoff, allowed_item_ids=allowed_item_ids, forbidden_item_ids=forbidden_item_ids, n_threads=get_n_threads(n_threads=n_threads), )
def score_to_recommended_items_batch( self, score: DenseScoreArray, cutoff: int, allowed_item_ids: Optional[List[ItemIdType]] = None, per_user_allowed_item_ids: Optional[List[List[ItemIdType]]] = None, forbidden_item_ids: Optional[List[List[ItemIdType]]] = None, n_threads: Optional[int] = None, ) -> List[List[Tuple[ItemIdType, float]]]: r"""Retrieve recommendation from score array. Args: score: 1d numpy ndarray for score. cutoff: Maximal number of recommendations allowed. allowed_item_ids: If not ``None``, defines "a list of recommendable item IDs". Ignored if `per_user_allowed_item_ids` is set. per_user_allowed_item_ids: If not ``None``, defines "a list of list of recommendable item IDs" and ``len(allowed_item_ids)`` must be equal to ``score.shape[0]``. Defaults to ``None``. allowed_item_ids: If not ``None``, defines "a list of list of recommendable item IDs" and ``len(allowed_item_ids)`` must be equal to ``len(item_ids)``. Defaults to ``None``. forbidden_item_ids: If not ``None``, defines "a list of list of forbidden item IDs" and ``len(allowed_item_ids)`` must be equal to ``len(item_ids)`` Defaults to ``None``. """ if forbidden_item_ids is not None: assert len(forbidden_item_ids) == score.shape[0] if per_user_allowed_item_ids is not None: assert len(per_user_allowed_item_ids) == score.shape[0] allowed_item_indices: List[List[int]] = [] if per_user_allowed_item_ids is not None: allowed_item_indices = [ self._item_id_list_to_index_list(_) for _ in per_user_allowed_item_ids ] elif allowed_item_ids is not None: allowed_item_indices = [self._item_id_list_to_index_list(allowed_item_ids)] if forbidden_item_ids is not None: for u, forbidden_ids_per_user in enumerate(forbidden_item_ids): score[ u, self._item_id_list_to_index_list(forbidden_ids_per_user) ] = -np.inf raw_result = retrieve_recommend_from_score( score, allowed_item_indices, cutoff, n_threads=get_n_threads(n_threads), ) return [ [ (self.item_ids[item_index], score) for item_index, score in user_wise_raw_result ] for user_wise_raw_result in raw_result ]