Exemplo n.º 1
0
    def getNegative(self, user_id: int, nega_num: int,
                    supp_nega_cluster_items):
        try:
            nega_items_list = self.nega_ui_dic[user_id].copy()
        except KeyError:
            nega_items_list = []

        if len(nega_items_list) > 0:
            if len(nega_items_list) >= nega_num:
                negative_list = constant_sample(nega_items_list, nega_num)
            else:
                negative_list = nega_items_list
                if nega_num - len(negative_list) >= len(
                        supp_nega_cluster_items):
                    negative_list += list(supp_nega_cluster_items)
                else:
                    negative_list = constant_sample(
                        supp_nega_cluster_items, nega_num - len(negative_list))
        else:
            if nega_num >= len(supp_nega_cluster_items):
                negative_list = list(supp_nega_cluster_items)
            else:
                negative_list = constant_sample(supp_nega_cluster_items,
                                                nega_num)
        return negative_list
Exemplo n.º 2
0
 def init_random_env(self, h_test_items):
     state_emd = np.zeros((1, self.state_num * self.state_dim))
     t_count = 0
     test_num = int(len(h_test_items)/2)
     if test_num >= self.state_num:
         test_num = self.state_num
         in_test = constant_sample(h_test_items, test_num)
         in_state = in_test
     else:
         in_test = constant_sample(h_test_items, test_num)
         in_state = in_test + constant_sample(range(0, self.data_shape[1]), self.state_num - test_num)
     for i_item in in_state:
         state_emd[0][t_count * self.state_dim:(t_count + 1) * self.state_dim] = self.item_vector[i_item]
         t_count += 1
     return in_state, state_emd, in_test
Exemplo n.º 3
0
    def init_env(self, user_id: int):
        state_emd = np.zeros((1, self.state_num * self.state_dim))
        t_count = 0
        h_train_items = self.train_user_items_dict[user_id].copy()
        if len(h_train_items) >= self.state_num:
            # 随机选择
            t = []

            in_state = constant_sample(h_train_items, self.state_num)
            for i_item in in_state:
                state_emd[0][t_count * self.state_dim:(t_count + 1) * self.state_dim] = self.item_vector[i_item]
                t_count += 1
        else:
            in_state = h_train_items
            while len(in_state) < self.state_num:
                in_state.append(-1)
            for i_item in in_state:
                if i_item == -1:
                    state_emd[0][t_count * self.state_dim:(t_count + 1) * self.state_dim] = np.zeros(self.item_vector[0].shape)
                else:
                    state_emd[0][t_count * self.state_dim:(t_count + 1) * self.state_dim] = self.item_vector[i_item]
                t_count += 1
        return in_state, state_emd
Exemplo n.º 4
0
 def step(self, user_id, in_state, in_a_w, select_size: int,
          train_percent: float):
     in_state_ = in_state.copy()
     in_emb_s_ = np.zeros((1, self.state_num * self.state_dim))
     # Select the most suitable item from the candidate set and calculate according to action
     train_num = int(train_percent * select_size)
     if train_num > len(self.train_user_items_dict[user_id]):
         train_num = len(self.train_user_items_dict[user_id])
     train_list = constant_sample(self.train_user_items_dict[user_id],
                                  train_num)
     try:
         nega_items_list = self.nega_ui_dic[user_id]
     except KeyError:
         nega_items_list = []
     nega_num = int((select_size - train_num) / 2)
     nega_list = self.getNegative(
         user_id=user_id,
         nega_num=nega_num,
         supp_nega_cluster_items=self.supp_nega_cluster_items[int(
             self.user_label_list[user_id])])
     random_c_list = train_list + nega_list
     num_random = select_size - train_num - len(nega_list)
     random_list = self.getRandom(random_c_list, num_random)
     random_c_list += random_list
     random.shuffle(random_c_list)
     # print(random_c_list)
     # Select top k items from the candidate set according to weight in a
     c_score_list = list()
     for c_item in random_c_list:
         c_item = int(c_item)
         score = np.sum(np.multiply(in_a_w, self.item_vector[c_item]))
         c_score_list.append([c_item, score])
     # Select a_num as action
     a_t = []
     for ii in range(self.action_num):
         r_item = -1
         max_score = -1
         for c_score in c_score_list:
             c_item = c_score[0]
             score = c_score[1]
             if score > max_score and c_item not in a_t:
                 max_score = score
                 r_item = c_item
         a_t.append(r_item)
     # print('a_t:', a_t)
     reward = 0
     ii = 0
     for item_a_t in a_t:
         # Distinguish the positions that appear, and the ahead is significant
         # position_weight = (len(in_state) - ii)/len(in_state)
         position_weight = 1 / math.log(ii + 2)
         # Every hit, reward + position_weight
         if item_a_t in train_list:
             reward += (self.train_user_items_rating_dict[user_id][item_a_t] - self.boundry_rating)\
                       * position_weight
         elif item_a_t in nega_items_list:
             reward += (self.nega_user_items_rating_dict[user_id][item_a_t]
                        - self.boundry_rating - 1) * position_weight
         elif item_a_t in nega_list:
             reward += -0.5 * position_weight
         # The sliding window is replaced from the front to the back and is not repeated
         if item_a_t not in in_state_:
             in_state_.pop()
             in_state_.insert(0, item_a_t)
         ii += 1
     # Update emb
     ii = 0
     for s_item_ in in_state_:
         in_emb_s_[0][ii * self.state_dim:(ii + 1) *
                      self.state_dim] = self.item_vector[s_item_]
         ii += 1
     # print('state_:', in_state_)
     return in_state_, in_emb_s_, reward
Exemplo n.º 5
0
def prepare_data(user_label_list, train_user_items_dict, test_user_ir_dict,
                 max_dis_dict, nega_user_ratings, num_item, save_root):
    user_label_num = len(set(user_label_list)) - 1
    nega_user_items_rating_dict = {}
    for u_id in nega_user_ratings.keys():
        nega_items_rating_dict = {}
        if nega_user_ratings[u_id] != '':
            for item in nega_user_ratings[u_id].split(','):
                items = item.split(':')
                nega_items_rating_dict[int(items[0])] = float(items[1])
        nega_user_items_rating_dict[u_id] = nega_items_rating_dict.copy()
    # print(nega_user_items_rating_dict[0].keys())
    with open(save_root + '/nega_user_items_rating_dict.txt',
              'w') as nega_uir_dict:
        nega_uir_dict.write(str(nega_user_items_rating_dict))

    cluster_items = []  # int, record of items for per cluster
    cluster_users = []  # int, record of users for per cluster
    for i in range(0, user_label_num + 1):  # Initialization
        cluster_users.append(list())
        cluster_items.append(set())
    for user in train_user_items_dict.keys():
        t_label = int(user_label_list[user])
        cluster_users[t_label].append(user)
        for item in train_user_items_dict[user]:
            cluster_items[t_label].add(item)
    with open(save_root + '/cluster_users.txt', 'w') as c_us:
        c_us.write(str({'cluster_users': cluster_users}))

    # Gets the list of classes that appear in the current class but not the farthest from the current class
    supp_nega_cluster_items = {}
    for user_cluster in range(user_label_num + 1):
        train_cluster_items_list = cluster_items[user_cluster].copy()
        max_dis_cluster = max_dis_dict[user_cluster]
        # print(len(cluster_items), len(cluster_items[int_cluster]))
        supp_nega_cluster_items[user_cluster] = cluster_items[
            max_dis_cluster].copy()
        for train_item in train_cluster_items_list:
            if train_item in cluster_items[max_dis_cluster]:
                supp_nega_cluster_items[user_cluster].remove(train_item)
    with open(save_root + '/supp_nega_cluster_items.txt', 'w') as nega_ci_file:
        nega_ci_file.write(str(supp_nega_cluster_items))

    # Get all test samples in advance for all methods
    test_dict = {}
    test_user_items_rating_dict = {}
    for user_id in test_user_ir_dict.keys():
        user_cluster = int(user_label_list[user_id])
        test_items = set()
        test_items_rating_dict = {}
        for (i_id, rating) in test_user_ir_dict[user_id]:
            test_items.add(i_id)
            test_items_rating_dict[i_id] = float(rating)
        test_user_items_rating_dict[user_id] = test_items_rating_dict.copy()
        test_dict[str(user_id) + '_p'] = list(test_items)

        num_nega = int(len(test_items) / test_percent)
        if num_nega < max_k * 2 - len(test_items):
            num_nega = max_k * 2 - len(test_items)
        # Avoid dead circulation
        if num_nega > num_item - len(train_user_items_dict[user_id]):
            num_nega = num_item - len(train_user_items_dict[user_id])

        if num_nega >= len(supp_nega_cluster_items[user_cluster]):
            negative_list = list(supp_nega_cluster_items[user_cluster].copy())
            while True:
                if len(negative_list) == num_nega:
                    break
                one_negative = np.random.randint(num_item)
                if one_negative not in negative_list:
                    negative_list.append(one_negative)
        else:
            negative_list = constant_sample(
                supp_nega_cluster_items[user_cluster], num_nega)

        test_dict[str(user_id) + '_n'] = negative_list
    with open(save_root + '/test_dict.txt', 'w') as test_f:
        test_f.write(str(test_dict))
    # print(test_user_items_rating_dict[0].keys())
    with open(save_root + '/test_user_items_rating_dict.txt',
              'w') as test_uir_dict:
        test_uir_dict.write(str(test_user_items_rating_dict))