Esempio n. 1
0
    def __init__(
        self,
        URM_train,
        recommenders=None,
        mode="",
    ):

        if recommenders is None:
            raise AssertionError("Recommenders parameter cannot be None")

        self.URM_train = URM_train
        self.recommenders = {}

        # Initialize and fit the single recommenders
        for recommender in recommenders:
            init_rec = recommender(URM_train)
            init_rec.fit(**parameters[recommender.RECOMMENDER_NAME])
            self.recommenders[recommender.RECOMMENDER_NAME] = init_rec

        # Get the cold users list
        self.cold_users, _ = Helper().compute_cold_warm_user_ids(URM_train)

        # Initialize and fit the hybriod which will deal with cold users
        self.hybrid_cold = HybridUserCBFRegionalTopPop(URM_train)
        self.hybrid_cold.fit()
Esempio n. 2
0
    def __init__(self, URM_train, multithreaded=True, mode="",):
        self.URM_train = URM_train

        # Init single recommenders
        self.item_cbf = ItemCBF(URM_train)
        self.item_cf = ItemCollaborativeFilter(URM_train)
        self.hybrid_cold = HybridUserCBFRegionalTopPop(URM_train)
        if multithreaded:
            self.SSLIM = MultiThreadSSLIM_ElasticNet(URM_train)
        else:
            self.SSLIM = SSLIMElasticNetRecommender(URM_train)
        self.rp3 = RP3betaRecommender(URM_train)
        self.user_cf = UserCollaborativeFilter(URM_train)
        self.user_cbf = UserCBF(URM_train)

        # Get the cold users list
        self.cold_users, _ = Helper().compute_cold_warm_user_ids(URM_train)

        # Fit the single recommenders, this saves time in case of changing just the relative weights

        self.item_cbf.fit(**item_cbf_parameters)
        self.item_cf.fit(**item_cf_parameters)
        self.rp3.fit(**rp3_parameters)
        self.hybrid_cold.fit()
        self.SSLIM.fit(**SSLIM_parameters)
        self.user_cf.fit(**UCF_parameters)
        self.user_cbf.fit(**user_cbf_parameters)
        def __init__(self, URM_train, mode="validation"):
            self.URM_train = URM_train

            # Init single recommenders
            self.top_pop = HybridUserCBFRegionalTopPop(URM_train)
            self.SSLIM = MultiThreadSSLIM_ElasticNet(URM_train)
            self.UCF = UserCollaborativeFilter(URM_train)
            self.user_cbf = UserCBF(URM_train)
            # Get the cold users list
            self.cold_users, _ = Helper().compute_cold_warm_user_ids(URM_train)

            # Fit the single recommenders, this saves time in case of changing just the relative weights

            self.top_pop.fit()
            self.SSLIM.fit(**SSLIM_parameters)
            self.UCF.fit(**UCF_parameters)
            self.user_cbf.fit(**user_cbf_parameters)
    def __init__(self, URM_train, mode="dataset"):
        self.URM_train = URM_train

        # Init single recommenders
        self.item_cbf = ItemCBF(URM_train)
        self.item_cf = ItemCollaborativeFilter(URM_train)
        self.top_pop = HybridUserCBFRegionalTopPop(URM_train)
        self.SLIM = MultiThreadSLIM_ElasticNet(URM_train)
        self.rp3 = RP3betaRecommender(URM_train)

        # Get the cold users list
        self.cold_users, _ = Helper().compute_cold_warm_user_ids(URM_train)

        # Fit the single recommenders, this saves time in case of changing just the relative weights

        self.item_cbf.fit(**item_cbf_parameters)
        self.item_cf.fit(**item_cf_parameters)
        self.rp3.fit(**rp3_parameters)
        self.top_pop.fit()
        self.SLIM.fit(**SLIM_parameters)
Esempio n. 5
0
class HybridSSLIMICFUCFRP3Beta(object):

    RECOMMENDER_NAME = "HybridElasticNetCFRP3Beta"

    def __init__(self, URM_train, multithreaded=True, mode="",):
        self.URM_train = URM_train

        # Init single recommenders
        self.item_cbf = ItemCBF(URM_train)
        self.item_cf = ItemCollaborativeFilter(URM_train)
        self.hybrid_cold = HybridUserCBFRegionalTopPop(URM_train)
        if multithreaded:
            self.SSLIM = MultiThreadSSLIM_ElasticNet(URM_train)
        else:
            self.SSLIM = SSLIMElasticNetRecommender(URM_train)
        self.rp3 = RP3betaRecommender(URM_train)
        self.user_cf = UserCollaborativeFilter(URM_train)
        self.user_cbf = UserCBF(URM_train)

        # Get the cold users list
        self.cold_users, _ = Helper().compute_cold_warm_user_ids(URM_train)

        # Fit the single recommenders, this saves time in case of changing just the relative weights

        self.item_cbf.fit(**item_cbf_parameters)
        self.item_cf.fit(**item_cf_parameters)
        self.rp3.fit(**rp3_parameters)
        self.hybrid_cold.fit()
        self.SSLIM.fit(**SSLIM_parameters)
        self.user_cf.fit(**UCF_parameters)
        self.user_cbf.fit(**user_cbf_parameters)

    def fit(self, SSLIM_weight=0.8950096358670148, item_cbf_weight=0.034234727663263104, item_cf_weight=0.011497379340447589, rp3_weight = 0.8894480634395567, user_cf_weight=0, user_cbf_weight=0):

        # Normalize the weights, just in case
        weight_sum = item_cf_weight + SSLIM_weight + item_cbf_weight + rp3_weight + user_cbf_weight + user_cf_weight

        self.weights = {"item_cf": item_cf_weight/weight_sum,
                        "SSLIM": SSLIM_weight / weight_sum,
                        "item_cbf": item_cbf_weight/weight_sum,
                        "rp3": rp3_weight/weight_sum,
                        "user_cf": user_cf_weight,
                        "user_cbf": user_cbf_weight}

    def compute_scores(self, user_id):
        scores_item_cf = self.item_cf.compute_scores(user_id)
        scores_SSLIM = self.SSLIM._compute_item_score(user_id).squeeze()
        scores_item_cbf = self.item_cbf.compute_scores(user_id)
        scores_rp3 = self.rp3._compute_item_score(user_id).squeeze()
        scores_user_cf = self.user_cf.compute_scores(user_id)
        scores_user_cbf = self.user_cbf.compute_scores(user_id)
        scores = (self.weights["item_cf"] * scores_item_cf) + \
                 (self.weights["SSLIM"] * scores_SSLIM) + \
                 (self.weights["item_cbf"] * scores_item_cbf) +\
                 (self.weights["rp3"] * scores_rp3) + \
                 (self.weights["user_cf"] * scores_user_cf) + \
                 (self.weights["user_cbf"] * scores_user_cbf)

        return scores

    def recommend(self, user_id, at=10, exclude_seen=True, enable_toppop=True):
        if user_id in self.cold_users and enable_toppop:
            # If the user has no interactions a TopPopular recommendation is still better than random
            recommended_items = self.hybrid_cold.recommend(user_id)
        else:
            # Otherwise compute regular recommendations
            scores = self.compute_scores(user_id)
            if exclude_seen:
                self.filter_seen(user_id, scores)
            recommended_items = np.argsort(scores)
            recommended_items = np.flip(recommended_items, axis=0)
        return recommended_items[0: at]

    def filter_seen(self, user_id, scores):
        """Remove items that are in the user profile from recommendations

        :param user_id: array of user ids for which to compute recommendations
        :param scores: array containing the scores for each object"""

        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
Esempio n. 6
0
class Hybrid(object):

    RECOMMENDER_NAME = "HybridElasticNetCFRP3Beta"

    def __init__(
        self,
        URM_train,
        recommenders=None,
        mode="",
    ):

        if recommenders is None:
            raise AssertionError("Recommenders parameter cannot be None")

        self.URM_train = URM_train
        self.recommenders = {}

        # Initialize and fit the single recommenders
        for recommender in recommenders:
            init_rec = recommender(URM_train)
            init_rec.fit(**parameters[recommender.RECOMMENDER_NAME])
            self.recommenders[recommender.RECOMMENDER_NAME] = init_rec

        # Get the cold users list
        self.cold_users, _ = Helper().compute_cold_warm_user_ids(URM_train)

        # Initialize and fit the hybriod which will deal with cold users
        self.hybrid_cold = HybridUserCBFRegionalTopPop(URM_train)
        self.hybrid_cold.fit()

        # Fit the single recommenders, this saves time in case of changing just the relative weights

    def fit(self, weights: dict):

        weight_sum = 0

        # Normalize the weights, just in case
        for weight in weights.values():
            weight_sum += weight

        for recommender in weights:
            weights[recommender] /= weight_sum

        self.weights = weights

    def compute_scores(self, user_id):
        scores = np.zeros(self.URM_train.shape[1])

        for recommender in self.recommenders:
            # Deal with some legacy implementations
            if recommender == "SLIMElasticNetRecommender" or recommender == "SSLIMElasticNetRecommender" or recommender == "RP3betaRecommender" or recommender == "SLIM_BPR_Recommender":
                score = self.recommenders[recommender]._compute_item_score(
                    user_id).squeeze()
            # Compute regular scores
            else:
                score = self.recommenders[recommender].compute_scores(user_id)

            # Weight the scores
            scores += score * self.weights[recommender]

        return scores

    def recommend(self, user_id, at=10, exclude_seen=True, enable_toppop=True):
        if user_id in self.cold_users and enable_toppop:
            # If the user has no interactions a TopPopular recommendation is still better than random
            recommended_items = self.hybrid_cold.recommend(user_id)
        else:
            # Otherwise compute regular recommendations
            scores = self.compute_scores(user_id)
            if exclude_seen:
                self.filter_seen(user_id, scores)
            recommended_items = np.argsort(scores)
            recommended_items = np.flip(recommended_items, axis=0)
        return recommended_items[0:at]

    def filter_seen(self, user_id, scores):
        """Remove items that are in the user profile from recommendations

        :param user_id: array of user ids for which to compute recommendations
        :param scores: array containing the scores for each object"""

        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 HybridSSLIMUCF(object):

        RECOMMENDER_NAME = "HybridElasticNetICF"

        def __init__(self, URM_train, mode="validation"):
            self.URM_train = URM_train

            # Init single recommenders
            self.top_pop = HybridUserCBFRegionalTopPop(URM_train)
            self.SSLIM = MultiThreadSSLIM_ElasticNet(URM_train)
            self.UCF = UserCollaborativeFilter(URM_train)
            self.user_cbf = UserCBF(URM_train)
            # Get the cold users list
            self.cold_users, _ = Helper().compute_cold_warm_user_ids(URM_train)

            # Fit the single recommenders, this saves time in case of changing just the relative weights

            self.top_pop.fit()
            self.SSLIM.fit(**SSLIM_parameters)
            self.UCF.fit(**UCF_parameters)
            self.user_cbf.fit(**user_cbf_parameters)

        def fit(self, SSLIM_weight=0.5):

            self.weights = {"SLIM": SSLIM_weight, "UCF": 1 - SSLIM_weight}

        def compute_scores(self, user_id):
            scores_SLIM = self.SSLIM._compute_item_score(user_id).squeeze()
            scores_UCF = self.UCF.compute_scores(user_id)

            scores = (self.weights["UCF"] * scores_UCF) + \
                     (self.weights["SLIM"] * scores_SLIM)
            return scores

        def recommend(self,
                      user_id,
                      at=10,
                      exclude_seen=True,
                      enable_toppop=True):
            if user_id in self.cold_users and enable_toppop:
                # If the user has no interactions a TopPopular recommendation is still better than random
                recommended_items = self.top_pop.recommend(user_id)
            else:
                # Otherwise compute regular recommendations
                scores = self.compute_scores(user_id)
                if exclude_seen:
                    self.filter_seen(user_id, scores)
                recommended_items = np.argsort(scores)
                recommended_items = np.flip(recommended_items, axis=0)
            return recommended_items[0:at]

        def filter_seen(self, user_id, scores):
            """Remove items that are in the user profile from recommendations

            :param user_id: array of user ids for which to compute recommendations
            :param scores: array containing the scores for each object"""

            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