def vectorize(feat, recent_candidate_list): c = cal_ent(recent_candidate_list) entropy_dict = c.do_job() list3 = [v for k, v in entropy_dict.items()] #list4 = [v for k, v in sim_dict2.items()] list4 = [0] * len(cfg.tag_map) #list3.remove(list3[-1] assert len(list3) == len(cfg.FACET_POOL) assert len(list4) == len(cfg.FACET_POOL) MAX_TURN = 5 history_list = [1] * min(MAX_TURN - 1, len(feat)) list5 = history_list + [0] * (MAX_TURN - len(history_list)) assert len(list5) == 5 list6 = [0] * 8 if len(recent_candidate_list) <= 10: list6[0] = 1 if len(recent_candidate_list) > 10 and len(recent_candidate_list) <= 50: list6[1] = 1 if len(recent_candidate_list) > 50 and len(recent_candidate_list) <= 100: list6[2] = 1 if len(recent_candidate_list) > 100 and len(recent_candidate_list) <= 200: list6[3] = 1 if len(recent_candidate_list) > 200 and len(recent_candidate_list) <= 300: list6[4] = 1 if len(recent_candidate_list) > 300 and len(recent_candidate_list) <= 500: list6[5] = 1 if len(recent_candidate_list) > 500 and len(recent_candidate_list) <= 1000: list6[6] = 1 if len(recent_candidate_list) > 1000: list6[7] = 1 list_cat = list3 + list4 + list5 + list6 # list_cat = np.array(list_cat) #print(list_cat) #assert len(list_cat) == 89 return list_cat
def update_upon_feature_inform(self, input_message): assert input_message.message_type == cfg.INFORM_FACET #_______ update F_dict________ facet = input_message.data['facet'] self.asked_feature.append(str(facet)) value = input_message.data['value'] if value is not None: self.update_this_turn = True rcl = [] for k in self.recent_candidate_list: if set(value).issubset(set( cfg.item_dict[str(k)]['categories'])): rcl.append(k) # self.recent_candidate_list = [k for k in self.recent_candidate_list if set(value).issubset(set(cfg.item_dict[str(k)]['categories']))] self.recent_candidate_list = rcl self.recent_candidate_list = list( set(self.recent_candidate_list) - set([self.busi_id])) + [self.busi_id] self.known_feature.append(cfg.tag_map[str(value[0])]) self.known_feature = list(set(self.known_feature)) # following dict l = list(set(self.recent_candidate_list) - set([self.busi_id])) random.shuffle(l) if cfg.play_by == 'AOO': self.sample_dict[self.busi_id].append( (self.known_feature, l[:10])) if cfg.play_by == 'AOO_valid': self.sample_dict[self.busi_id].append( (self.known_feature, l[:300])) # end dictionary if cfg.play_by != 'AOO' and cfg.play_by != 'AOO_valid': self.sim_dict = feature_similarity(self.known_feature, self.user_id, self.TopKTaxo) self.sim_dict2 = self.sim_dict.copy() self.recent_candidate_list = list( set(self.recent_candidate_list) - set([self.busi_id])) + [self.busi_id] self.recent_candidate_list_ranked = rank_items( self.known_feature, self.user_id, self.busi_id, self.skip_big_feature, self.FM_model, self.recent_candidate_list, self.write_fp, 0) if value is not None and value[0] is not None: c = cal_ent(self.recent_candidate_list) d = c.do_job() self.entropy_dict = d c = cal_ent(self.recent_candidate_list[:10]) d = c.do_job() self.entropy_dict_10 = d c = cal_ent(self.recent_candidate_list[:50]) d = c.do_job() self.entropy_dict_50 = d for f in self.asked_feature: # self.entropy_dict[int(f)] = 0 self.entropy_dict[f] = 0 if cfg.play_by == 'AOO' or cfg.play_by == 'AOO_valid': return for f in self.asked_feature: if self.sim_dict is not None and str(f) in self.sim_dict: self.sim_dict[str(f)] = -1 for f in self.asked_feature: if self.sim_dict2 is not None and str(f) in self.sim_dict: self.sim_dict2[str(f)] = -1 residual_feature = cfg.item_dict[str(self.busi_id)]['categories'] # known_ = [int(cfg.tag_map_inverted[item]) for item in self.known_feature] known_ = [cfg.tag_map_inverted[item] for item in self.known_feature] residual_feature = list(set(residual_feature) - set(known_)) self.residual_feature_big = residual_feature
def response(self, input_message): ''' The agent moves a step forward, upon receiving a message from the user. ''' assert input_message.sender == cfg.USER assert input_message.receiver == cfg.AGENT # _______ update the agent self_______ if input_message.message_type == cfg.INFORM_FACET: if self.turn_count > 0: # means first doesn't# count if input_message.data['facet_lable'] == 0: self.history_list.append(0) else: self.history_list.append(1) self.mini_update(input_message) if input_message.message_type == cfg.REJECT_REC: self.rejected_item_list_ += input_message.data[ 'rejected_item_list'] self.rejected_time += 1 self.history_list.append(-1) # 表示推荐失败 if self.mini == 1: if self.alwaysupdate == 1: self.mini_update(input_message) self.mini_update_already = True # ------ update Ent ------ c = cal_ent(self.recent_candidate_list) d = c.do_job() self.entropy_dict = d for f in self.asked_feature: self.entropy_dict[f] = 0 self.recent_candidate_list = list( set(self.recent_candidate_list) - set(self.rejected_item_list_)) self.recent_candidate_list = list( set(self.recent_candidate_list) - set([self.busi_id])) + [self.busi_id] # _______ Adding into history _______ if input_message.message_type == cfg.ACCEPT_REC: self.mini_update(input_message) if len(self.history_list) != 0: if self.history_list[-1] == -2: self.mini_update(input_message) self.recent_candidate_list_ranked, self.previous_dict, self.max_item_score = \ rank_items(self.known_feature, self.user_id, self.busi_id, self.skip_big_feature, self.FM_model, self.recent_candidate_list, self.write_fp, 1, self.rejected_item_list_, self.previous_dict) self.update_upon_feature_inform(input_message) action = None SoftMax = nn.Softmax() if cfg.play_by == 'AOO': new_message = self.prepare_next_question() # if cfg.play_by == 'AO': # means AskOnly action = 0 new_message = self.prepare_next_question() if cfg.hardrec == 'two': x = len(self.recent_candidate_list) p = 10.0 / x a = random.uniform(0, 1) if a < p: new_message = self.prepare_rec_message() if cfg.play_by == 'Naive': # means AskOnly action = 0 new_message = self.prepare_next_question() a = random.uniform(0, 1) if a > 0.5: new_message = self.prepare_rec_message() if cfg.play_by == 'RO': # means RecOnly new_message = self.prepare_rec_message() if cfg.play_by == 'AR': # means Ask and Recommend action = random.randint(0, 1) if cfg.play_by == 'policy': a = random.uniform(0, 1) if a < 0.8 or cfg.eval == 1: # means choose the action with highest probability ranked_facet = sorted(self.sim_dict.items(), key=lambda item: item[1], reverse=True) if ranked_facet[0][1] > self.max_item_score: action_max = cfg.FACET_POOL.index(ranked_facet[0][0]) else: action_max = self.big_feature_length # The following line are sampled the action chosen. action = Variable(torch.IntTensor([action_max])) else: # means we choose a random action action = np.random.randint(0, self.big_feature_length + 1) # action = Variable(action.data, requires_grad=True) if action < len(cfg.FACET_POOL): data = dict() data['facet'] = cfg.FACET_POOL[action] new_message = message(cfg.AGENT, cfg.USER, cfg.ASK_FACET, data) self.bias = self.cal_bias_at(ranked_facet[0][0]) else: new_message, self.bias = self.prepare_rec_message() if cfg.play_by == 'policy': self.action_tracker.append(action.data.numpy().tolist()) self.candidate_length_tracker.append( len(self.recent_candidate_list)) new_message.data['itemID'] = self.busi_id return new_message
def update_upon_feature_inform(self, input_message): # assert input_message.message_type == cfg.INFORM_FACET # _______ update F_dict________ if input_message.message_type == cfg.INFORM_FACET: facet = input_message.data['facet'] self.asked_feature.append(facet) value = input_message.data['value'] facet_lable = input_message.data['facet_lable'] if self.history_list[-1] == 1: self.recent_candidate_list = [ k for k in self.recent_candidate_list if set(value).issubset( set(cfg.item_dict[str(k)]['categories'])) ] self.recent_candidate_list = list( set(self.recent_candidate_list) - set([self.busi_id])) + [self.busi_id] self.known_facet.append(facet) fresh = True self.known_feature = list(set(self.known_feature)) if fresh is True: # dictionary l = list( set(self.recent_candidate_list) - set([self.busi_id])) random.shuffle(l) if cfg.play_by == 'AOO': self.sample_dict[self.busi_id].append( (self.known_feature, l[:10])) # end dictionary # end if if cfg.play_by != 'AOO': self.sim_dict = feature_similarity(self.known_feature, self.user_id, self.TopKTaxo) self.sim_dict2 = self.sim_dict.copy() start = time.time() if (facet_lable != 0) or self.turn_count == 1: c = cal_ent(self.recent_candidate_list[:10]) d = c.do_job() self.entropy_dict_10 = d c = cal_ent(self.recent_candidate_list[:50]) d = c.do_job() self.entropy_dict_50 = d c = cal_ent(self.recent_candidate_list) d = c.do_job() self.entropy_dict = d self.sim_dict = feature_similarity(self.known_feature, self.user_id, self.TopKTaxo) self.sim_dict2 = self.sim_dict.copy() for f in self.asked_feature: if self.entropy_dict != None: self.entropy_dict[f] = 0 for f in self.asked_feature: if self.sim_dict is not None and f in self.sim_dict: self.sim_dict[f] = -10 if self.entropy_dict != None: if self.entropy_dict[f] == 0: self.sim_dict[f] = -10 for f in self.asked_feature: if self.sim_dict2 is not None and f in self.sim_dict: self.sim_dict2[f] = -10 if self.entropy_dict != None: if self.entropy_dict[f] == 0: self.sim_dict[f] = -10
def update_upon_feature_inform(self, input_message): assert input_message.message_type == cfg.INFORM_FACET #_______ update F_dict________ facet = input_message.data['facet'] if facet is None: print('?') self.asked_feature.append(facet) value = input_message.data['value'] if facet in ['stars', 'RestaurantsPriceRange2', 'city']: ''' value is a list for stars: [3.0] for Prices: [3.0] for city: as we integerized, [31] be cautious for city, they must be integer ''' if value is not None and value[0] is not None: self.recent_candidate_list = [ k for k in self.recent_candidate_list if cfg.item_dict[str(k)][facet] in value ] self.recent_candidate_list = list( set(self.recent_candidate_list) - set([self.busi_id])) + [self.busi_id] self.known_facet.append(facet) fresh = True if facet == 'city': if int(value[0]) not in self.known_feature: self.known_feature.append(int(value[0])) else: fresh = False if facet == 'stars': if int(value[0] + cfg.city_count) not in self.known_feature: self.known_feature.append( int(value[0] + cfg.city_count - 1)) else: fresh = False if facet == 'RestaurantsPriceRange2': if int(value[0] + cfg.star_count + cfg.city_count) not in self.known_feature: self.known_feature.append( int(value[0] + cfg.star_count + cfg.city_count - 1)) else: fresh = False self.known_feature = list(set(self.known_feature)) if fresh is True: # dictionary l = list( set(self.recent_candidate_list) - set([self.busi_id])) random.shuffle(l) if cfg.play_by == 'AOO': self.sample_dict[self.busi_id].append( (self.known_feature, l[:10])) if cfg.play_by == 'AOO_valid': self.sample_dict[self.busi_id].append( (self.known_feature, l[:300])) # end dictionary #end if if cfg.play_by != 'AOO' and cfg.play_by != 'AOO_valid': self.sim_dict = feature_similarity(self.known_feature, self.user_id, self.TopKTaxo) self.sim_dict2 = self.sim_dict.copy() #print('Similarity ranking dict: {}'.format(self.sim_dict)) self.recent_candidate_list_ranked, self.previous_dict = rank_items( self.known_feature, self.user_id, self.busi_id, self.skip_big_feature, self.FM_model, self.recent_candidate_list, self.write_fp, 0, self.rejected_item_list_, self.previous_dict) # end if else: # means the feature is in the small tags if value is not None: self.recent_candidate_list = [ k for k in self.recent_candidate_list if set(value).issubset( set(cfg.item_dict[str(k)]['categories'])) ] self.recent_candidate_list = list( set(self.recent_candidate_list) - set([self.busi_id])) + [self.busi_id] base = cfg.star_count + cfg.price_count + cfg.city_count self.known_feature += [int(i + base) for i in value] self.known_feature = list(set(self.known_feature)) self.known_facet.append(facet) # dictionary l = list(set(self.recent_candidate_list) - set([self.busi_id])) random.shuffle(l) if cfg.play_by == 'AOO': self.sample_dict[self.busi_id].append( (self.known_feature, l[:10])) if cfg.play_by == 'AOO_valid': self.sample_dict[self.busi_id].append( (self.known_feature, l[:300])) # end dictionary if cfg.play_by != 'AOO' and cfg.play_by != 'AOO_valid': self.sim_dict = feature_similarity(self.known_feature, self.user_id, self.TopKTaxo) self.sim_dict2 = self.sim_dict.copy() self.recent_candidate_list_ranked, self.previous_dict = rank_items( self.known_feature, self.user_id, self.busi_id, self.skip_big_feature, self.FM_model, self.recent_candidate_list, self.write_fp, 0, self.rejected_item_list_, self.previous_dict) # end else start = time.time() if value is not None and value[0] is not None: c = cal_ent(self.recent_candidate_list[:10]) d = c.do_job() self.entropy_dict_10 = d c = cal_ent(self.recent_candidate_list[:50]) d = c.do_job() self.entropy_dict_50 = d c = cal_ent(self.recent_candidate_list) d = c.do_job() self.entropy_dict = d # _______ set those asked feature's entropy to 0 _______ for f in self.asked_feature: self.entropy_dict[f] = 0 for f in self.asked_feature: if self.sim_dict is not None and f in self.sim_dict: self.sim_dict[f] = -1 if self.entropy_dict[f] == 0: self.sim_dict[f] = -1 for f in self.asked_feature: if self.sim_dict2 is not None and f in self.sim_dict: self.sim_dict2[f] = -1 if self.entropy_dict[f] == 0: self.sim_dict[f] = -1 self.residual_feature_big = list( set(self.choose_pool) - set(self.known_facet)) ent_position, sim_position = None, None if self.entropy_dict is not None: ent_value = sorted([v for k, v in self.entropy_dict.items()], reverse=True) ent_position = [ ent_value.index(self.entropy_dict[big_f]) for big_f in self.residual_feature_big ] if self.sim_dict is not None: sim_value = sorted([v for k, v in self.sim_dict.items()], reverse=True) sim_position = [ sim_value.index(self.sim_dict[str(big_f)]) for big_f in self.residual_feature_big ] if len(self.residual_feature_big) > 0: with open(self.write_fp, 'a') as f: f.write( 'Turn Count: {} residual feature: {}***ent position: {}*** sim position: {}***\n' .format(self.turn_count, self.residual_feature_big, ent_position, sim_position))
def update_upon_feature_inform(self, input_message): # assert input_message.message_type == cfg.INFORM_FACET # _______ update F_dict________ if input_message.message_type == cfg.INFORM_FACET: facet = input_message.data['facet'] self.asked_feature += facet value = input_message.data['value'] facet_lable = input_message.data['facet_lable'] if self.history_list[-1] == 1: self.recent_candidate_list = [ k for k in self.recent_candidate_list if set(value).issubset( set(cfg.item_dict[str(k)]['feature_index'])) ] self.recent_candidate_list = list( set(self.recent_candidate_list) - set([self.busi_id])) + [self.busi_id] self.known_facet += facet fresh = True self.known_feature = list(set(self.known_feature)) if fresh is True: # dictionary l = list( set(self.recent_candidate_list) - set([self.busi_id])) random.shuffle(l) if cfg.play_by == 'AOO': self.sample_dict[self.busi_id].append( (self.known_feature, l[:10])) if cfg.play_by != 'AOO': self.sim_dict = feature_similarity(self.known_feature, self.user_id, self.TopKTaxo) self.sim_dict2 = self.sim_dict.copy() start = time.time() if (facet_lable != 0) or self.turn_count == 1: c = cal_ent(self.recent_candidate_list[:10]) d = c.do_job() self.entropy_dict_10 = d c = cal_ent(self.recent_candidate_list[:50]) d = c.do_job() self.entropy_dict_50 = d c = cal_ent(self.recent_candidate_list) d = c.do_job() self.entropy_dict = d # _______ update candidate db____________ # ---------- Need to check the correctness here!------------- # _______ here we only generated the query sentence, will do the query after the if judgment start = time.time() self.sim_dict = feature_similarity(self.known_feature, self.user_id, self.TopKTaxo) self.sim_dict2 = self.sim_dict.copy() for f in self.asked_feature: if self.entropy_dict != None: self.entropy_dict[f] = 0 for f in self.asked_feature: if self.sim_dict is not None and f in self.sim_dict: self.sim_dict[f] = -10 if self.entropy_dict != None: if self.entropy_dict[f] == 0: self.sim_dict[f] = -10 for f in self.asked_feature: if self.sim_dict2 is not None and f in self.sim_dict: self.sim_dict2[f] = -10 if self.entropy_dict != None: if self.entropy_dict[f] == 0: self.sim_dict[f] = -10
def update_upon_feature_inform(self, input_message): assert input_message.message_type == cfg.INFORM_FACET facet = input_message.data['facet'] if facet is None: print('?') self.asked_feature.append(facet) value = input_message.data['value'] if facet in ['clusters', 'POI_Type']: if value is not None and value[0] is not None: # value is in list. self.recent_candidate_list = [ k for k in self.recent_candidate_list if cfg.item_dict[str(k)][facet] in value ] self.recent_candidate_list = list( set(self.recent_candidate_list) - set([self.busi_id])) + [self.busi_id] self.known_facet.append(facet) fresh = True if facet == 'clusters': if int(value[0]) not in self.known_feature_cluster: self.known_feature_cluster.append(int(value[0])) else: fresh = False if facet == 'POI_Type': if int(value[0]) not in self.known_feature_type: self.known_feature_type.append(int(value[0])) else: fresh = False self.known_feature = list(set( self.known_feature)) # feature = values if cfg.play_by != 'AOO' and cfg.play_by != 'AOO_valid': self.known_feature_total.clear() self.known_feature_total.append(self.known_feature_cluster) self.known_feature_total.append(self.known_feature_type) self.known_feature_total.append( self.known_feature_category) self.distance_dict = feature_distance( self.known_feature_total, self.user_id, self.TopKTaxo, self.features) self.distance_dict2 = self.distance_dict.copy() self.recent_candidate_list_ranked = rank_items( self.known_feature_total, self.items, self.features, self.transE_model, self.recent_candidate_list, self.rejected_item_list_) else: if value is not None: self.recent_candidate_list = [ k for k in self.recent_candidate_list if set(value).issubset( set(cfg.item_dict[str(k)]['L2_Category_name'])) ] self.recent_candidate_list = list( set(self.recent_candidate_list) - set([self.busi_id])) + [self.busi_id] self.known_feature_category += [int(i) for i in value] self.known_feature_category = list( set(self.known_feature_category)) self.known_facet.append(facet) l = list(set(self.recent_candidate_list) - set([self.busi_id])) random.shuffle(l) if cfg.play_by != 'AOO' and cfg.play_by != 'AOO_valid': self.known_feature_total.clear() self.known_feature_total.append(self.known_feature_cluster) self.known_feature_total.append(self.known_feature_type) self.known_feature_total.append( self.known_feature_category) self.distance_dict = feature_distance( self.known_feature_total, self.user_id, self.TopKTaxo, self.features) self.distance_dict2 = self.distance_dict.copy() self.recent_candidate_list_ranked = rank_items( self.known_feature_total, self.items, self.features, self.transE_model, self.recent_candidate_list, self.rejected_item_list_) start = time.time() if value is not None and value[0] is not None: c = cal_ent(self.recent_candidate_list) d = c.do_job() self.entropy_dict = d for f in self.asked_feature: self.entropy_dict[f] = 0 for f in self.asked_feature: if self.distance_dict is not None and f in self.distance_dict: self.distance_dict[f] = 10000 if self.entropy_dict[f] == 0: self.distance_dict[f] = 10000 for f in self.asked_feature: if self.distance_dict2 is not None and f in self.distance_dict: self.distance_dict2[f] = 10000 if self.entropy_dict[f] == 0: self.distance_dict[f] = 10000 self.residual_feature_big = list( set(self.choose_pool) - set(self.known_facet)) ent_position, sim_position = None, None if self.entropy_dict is not None: ent_value = sorted([v for k, v in self.entropy_dict.items()], reverse=True) ent_position = [ ent_value.index(self.entropy_dict[big_f]) for big_f in self.residual_feature_big ] if self.distance_dict is not None: sim_value = sorted([v for k, v in self.distance_dict.items()], reverse=True) sim_position = [ sim_value.index(self.distance_dict[str(big_f)]) for big_f in self.residual_feature_big ] if len(self.residual_feature_big) > 0: with open(self.write_fp, 'a') as f: f.write( 'Turn Count: {} residual feature: {}***ent position: {}*** sim position: {}***\n' .format(self.turn_count, self.residual_feature_big, ent_position, sim_position))