class Runner: ####################################################################################### # INSTANCE OF RUNNER # ####################################################################################### def __init__(self, recommender, name, evaluate=True): print("Evaluation: " + str(evaluate)) self.recommender = recommender self.evaluate = evaluate self.name = name self.functionality = BaseFunction() ####################################################################################### # WRITE RESULT # ####################################################################################### def write_csv(self, rows, name): fields = FIELDS timestr = time.strftime("%Y-%m-%d_%H.%M.%S") file_path = "Results/" + name + "-" + timestr + ".csv" with open(file_path, 'w') as csv_file: csv_write_head = csv.writer(csv_file, delimiter=',') csv_write_head.writerow(fields) csv_write_content = csv.writer(csv_file, delimiter=' ') csv_write_content.writerows(rows) ####################################################################################### # RUN FITTNG # ####################################################################################### def fit_recommender(self, requires_icm=False, requires_ucm=False, load_similarity=True): print("Fitting model...") ICM_all = self.functionality.ICM_all UCM_all = self.functionality.UCM_all if not self.evaluate: if requires_icm and requires_ucm: self.recommender.fit(self.functionality.URM_all, ICM_all, UCM_all) elif requires_icm: self.recommender.fit(self.functionality.URM_all, ICM_all) elif requires_ucm: self.recommender.fit(self.functionality.URM_all, UCM_all) else: self.recommender.fit(self.functionality.URM_all) else: self.functionality.split_80_20(0.8) if requires_icm and requires_ucm: self.recommender.fit(self.functionality.URM_train, ICM_all, UCM_all, tuning=True) elif requires_icm: self.recommender.fit(self.functionality.URM_train, ICM_all, tuning=True) elif requires_ucm: self.recommender.fit(self.functionality.URM_train, UCM_all, tuning=True) else: self.recommender.fit(self.functionality.URM_train, tuning=True) print("Model fitted") ####################################################################################### # RUN RECOMMENDATION # ####################################################################################### def run_recommendations(self): recommendations = [] saved_tuple = [] print("Computing recommendations...") for user in tqdm(self.functionality.userlist_unique): index = [str(user) + ","] recommendations.clear() for recommendation in self.recommender.recommend(user): recommendations.append(recommendation) saved_tuple.append(index + recommendations) print("Recommendations computed") if not self.evaluate: print("Printing csv...") self.write_csv(saved_tuple, self.name) print("Ended") return saved_tuple ####################################################################################### # RUN COMPUTATION # ####################################################################################### def run(self, requires_ucm=False, requires_icm=False): self.functionality.get_URM() if requires_icm: self.functionality.get_ICM() if requires_ucm: self.functionality.get_UCM() self.functionality.get_target_users() self.fit_recommender(requires_icm, requires_ucm) if not self.evaluate: # Recommendations on target users are necessary only during file printing self.run_recommendations() if self.evaluate: evaluation.evaluate_algorithm(self.functionality.URM_test, self.recommender, at=10)
class BayesianSearch: ####################################################################################### # INIT CLASS BAYESIAN SEARCH # ####################################################################################### def __init__(self, recommender, name): self.recommender = recommender self.name = name self.helper = BaseFunction() self.helper.get_URM() self.helper.split_80_20() self.helper.get_target_users() self.helper.get_UCM() self.helper.get_ICM() self.optimazer = None def instanziate_optimazer(self, bayesian_method_call, pbounds): optimizer = BayesianOptimization( f=bayesian_method_call, pbounds=pbounds, verbose= 2, # verbose = 1 prints only when a maximum is observed, verbose = 0 is silent ) optimizer.maximize(init_points=30, n_iter=1000, acq='ucb', kappa=0.1) ####################################################################################### # STEP TO MAXIMAXE # ####################################################################################### def step_hybrid_three(self, weight1=0, weight2=0, weight3=0): start_time = time.time() UCM_all = self.helper.UCM_all ICM_all = self.helper.ICM_all self.recommender.fit(self.helper.URM_train, ICM_all=ICM_all, UCM_all=UCM_all, weights=[weight1, weight2, weight3], tuning=True) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_hybrid_four(self, weight1=0, weight2=0, weight3=0, weight4=0): start_time = time.time() UCM_all = self.helper.UCM_all ICM_all = self.helper.ICM_all self.recommender.fit(self.helper.URM_train, ICM_all=ICM_all, UCM_all=UCM_all, weights=[weight1, weight2, weight3, weight4], tuning=True) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_hybrid_six(self, weight1=0, weight2=0, weight3=0, weight4=0, weight5=0, weight6=0): start_time = time.time() UCM_all = self.helper.UCM_all ICM_all = self.helper.ICM_all self.recommender.fit( self.helper.URM_train, ICM_all=ICM_all, UCM_all=UCM_all, weights=[weight1, weight2, weight3, weight4, weight5, weight6], tuning=True) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_hybrid_seven(self, weight1=0, weight2=0, weight3=0, weight4=0, weight5=0, weight6=0, weight7=0): start_time = time.time() UCM_all = self.helper.UCM_all ICM_all = self.helper.ICM_all self.recommender.fit(self.helper.URM_train, ICM_all=ICM_all, UCM_all=UCM_all, weights=[ weight1, weight2, weight3, weight4, weight5, weight6, weight7 ], tuning=True) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_fallBack_Hybrid(self, weight1=0, weight2=0): start_time = time.time() UCM_all = self.helper.UCM_all ICM_all = self.helper.ICM_all self.recommender.fit(self.helper.URM_train, ICM_all=ICM_all, UCM_all=UCM_all, weights_fallback=[int(weight1), int(weight2)], tuning=True) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_slim(self, weight1=0, weight2=0, weight3=0): start_time = time.time() self.recommender = SLIM_BPR_Cython(lambda_i=weight1, lambda_j=weight2, learning_rate=weight3) self.recommender.fit(self.helper.URM_train) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_elastic(self, weight1=0, weight2=0, weight3=0): start_time = time.time() self.recommender.fit(self.helper.URM_train, l1_ratio=weight1, alpha=weight2, topK=int(weight3)) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_ALS(self, weight1=0, weight2=0, weight3=0): start_time = time.time() self.recommender = AlternatingLeastSquare(n_factors=int(weight1), regularization=weight2, iterations=int(weight3)) self.recommender.fit(self.helper.URM_train) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_Item_CB(self, weight1=0, weight2=0): start_time = time.time() ICM_all = self.helper.ICM_all self.recommender.fit(self.helper.URM_train, ICM_all, knn=int(weight1), shrink=int(weight2), tuning=False) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_User_CB(self, weight1=0, weight2=0): start_time = time.time() UCM_all = self.helper.UCM_all self.recommender.fit(self.helper.URM_train, UCM_all, knn=int(weight1), shrink=int(weight2)) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_P3Alpha(self, weight1=0, weight2=0): start_time = time.time() self.recommender.fit(self.helper.URM_train, topK=int(weight1), alpha=weight2) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_RP3Beta(self, alpha=0, beta=0, min_rating=0, topK=0): start_time = time.time() self.recommender.fit(self.helper.URM_train, alpha=alpha, beta=beta, min_rating=min_rating, topK=int(topK)) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_PureSVD_randomSVD(self, n_components, n_iter): start_time = time.time() self.recommender.fit(self.helper.URM_train, n_components=int(n_components), n_iter=int(n_iter)) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_FunkSVD(self, epoch, num_factors, learning_rate, user_reg, item_reg): start_time = time.time() self.recommender = MatrixFactorization_FunkSVD_Cython( int(epoch), int(num_factors), learning_rate, user_reg, item_reg) self.recommender.fit(self.helper.URM_train) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_TEST(self, t1, t2, t3, t4, t5): start_time = time.time() UCM_all = self.helper.UCM_all ICM_all = self.helper.ICM_all self.recommender = Hybrid_User_Wise("Hybrid User Wise", UserCBFKNNRecommender()) self.recommender.fit(self.helper.URM_train, ICM_all=ICM_all, UCM_all=UCM_all, thre1=t1, thre2=t2, thre3=t3, thre4=t4, thre5=t5, tuning=True) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative def step_all(self, H0_ICF_sh=0, H0_ICF_tK=0, H1_UCF_sh=0, H1_UCF_tK=0, H2_ICB_sh=0, H2_ICB_tK=0, H3_UCB_sh=0, H3_UCB_tK=0, H4_El_tK=0, H5_RP3_a=0, H5_RP3_b=0, H5_RP3_tK=0, H6_SL_bs=0, H6_SL_ep=0, H6_SL_l_i=0, H6_SL_l_j=0, H6_SL_l_r=0, H6_SL_tK=0, H7_ALS_i=0, H7_ALS_nf=0, H7_ALS_re=0, weight1=0, weight2=0, weight3=0, weight4=0, weight5=0, weight6=0, weight7=0): start_time = time.time() UCM_all = self.helper.UCM_all ICM_all = self.helper.ICM_all ItemCF = ItemKNNCFRecommender() UserCF = UserKNNCFRecommender() ItemCB = ItemCBFKNNRecommender() UserCB = UserCBFKNNRecommender() ElasticNet = SLIMElasticNetRecommender() RP3Beta = RP3BetaRecommender() Slim = SLIM_BPR_Cython(batch_size=int(H6_SL_bs), epochs=int(H6_SL_ep), lambda_i=H6_SL_l_i, lambda_j=H6_SL_l_j, learning_rate=H6_SL_l_r, topK=int(H6_SL_tK)) ALS = AlternatingLeastSquare(iterations=int(H7_ALS_i), n_factors=int(H7_ALS_nf), regularization=H7_ALS_re) ItemCF.fit(self.helper.URM_train, knn=int(H0_ICF_tK), shrink=H0_ICF_sh) UserCF.fit(self.helper.URM_train, knn=int(H1_UCF_tK), shrink=H1_UCF_sh) ItemCB.fit(self.helper.URM_train, ICM_all, knn=int(H2_ICB_tK), shrink=H2_ICB_sh) UserCB.fit(self.helper.URM_train, UCM_all, knn=int(H3_UCB_tK), shrink=H3_UCB_sh) ElasticNet.fit(self.helper.URM_train, topK=int(H4_El_tK)) RP3Beta.fit(self.helper.URM_train, alpha=H5_RP3_a, beta=H5_RP3_b, topK=int(H5_RP3_tK)) Slim.fit(self.helper.URM_train) ALS.fit(self.helper.URM_train) self.recommender = Hybrid_Achille_Tuning("Hybrid_Achille_Tuning_All", UserCB) self.recommender.fit(self.helper.URM_train, ICM_all=ICM_all, UCM_all=UCM_all, weights=[ weight1, weight2, weight3, weight4, weight5, weight6, weight7 ], ItemCF=ItemCF, UserCF=UserCF, ItemCB=ItemCB, ElasticNet=ElasticNet, RP3=RP3Beta, Slim=Slim, ALS=ALS) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative
class ClassesRating: def __init__(self): self.helper = BaseFunction() self.URM = None self.URM_train = None self.URM_test = None self.URM = self.helper.get_URM() self.helper.split_80_20() self.URM_train, self.URM_test = self.helper.URM_train, self.helper.URM_test self.helper.get_ICM() self.helper.get_UCM() self.helper.get_target_users() self.ICM_all = self.helper.ICM_all self.UCM_all = self.helper.UCM_all self.initial_target_user = self.helper.userlist_unique MAP_ItemCF_per_group = [] MAP_UserCF_per_group = [] MAP_ItemCBF_per_group = [] MAP_UserCBF_per_group = [] MAP_ItemCBF_BM25_per_group = [] MAP_UserCBF_BM25_per_group = [] MAP_ItemCBF_TFIDF_per_group = [] MAP_UserCBF_TFIDF_per_group = [] MAP_Slim_per_group = [] MAP_Elastic_per_group = [] MAP_PureSVD_per_group = [] MAP_P3Alpha_per_group = [] MAP_RP3Beta_per_group = [] MAP_ALS_per_group = [] MAP_Hybrid2_per_group = [] MAP_Hybrid6_per_group = [] MAP_H6_bis_per_group = [] MAP_Hybrid7_per_group = [] MAP_Hybrid8_per_group = [] MAP_HybridCB_per_group = [] self.profile_length = np.ediff1d(self.URM_train.indptr) self.blocksize = int(len(self.profile_length) * 0.05) self.sortedusers = np.argsort(self.profile_length) self.ItemCF = ItemKNNCFRecommender() self.UserCF = UserKNNCFRecommender() self.ItemCBF = ItemCBFKNNRecommender() self.UserCBF = UserCBFKNNRecommender() self.Slim = SLIM_BPR_Cython() self.Elastic = SLIMElasticNetRecommender() self.PureSVD = PureSVDRecommender() self.P3Alpha = P3AlphaRecommender() self.RP3Beta = RP3BetaRecommender() self.ALS = AlternatingLeastSquare() self.H6_bis = Hybrid_Combo6_bis("Combo6_bis", UserCBFKNNRecommender()) self.ItemCBF.fit( self.URM_train, self.ICM_all, tuning=True, similarity_path="/SimilarityProduct/ItemCBF_similarity.npz") self.UserCBF.fit( self.URM_train, self.UCM_all, tuning=True, similarity_path="/SimilarityProduct/UserCBF_similarity.npz") self.ItemCF.fit( self.URM_train, tuning=True, similarity_path="/SimilarityProduct/ItemCF_similarity.npz") self.UserCF.fit( self.URM_train, tuning=True, similarity_path="/SimilarityProduct/UserCF_similarity.npz") self.Slim.fit(self.URM_train, tuning=True, similarity_path="/SimilarityProduct/Slim_similarity.npz") self.Elastic.fit( self.URM_train, tuning=True, similarity_path="/SimilarityProduct/Elastic_similarity.npz") self.PureSVD.fit(self.URM_train) self.P3Alpha.fit( self.URM_train, tuning=True, similarity_path="/SimilarityProduct/P3Aplha_similarity.npz") self.RP3Beta.fit( self.URM_train, tuning=True, similarity_path="/SimilarityProduct/RP3Beta_similarity.npz") self.ALS.fit(self.URM_train) self.H6_bis.fit(self.URM_train, self.ICM_all, self.UCM_all, tuning=True) for group_id in range(0, 20): start_pos = group_id * self.blocksize end_pos = min((group_id + 1) * self.blocksize, len(self.profile_length)) users_in_group = self.sortedusers[start_pos:end_pos] users_in_group_p_len = self.profile_length[users_in_group] print("Group {}, average p.len {:.2f}, min {}, max {}".format( group_id, users_in_group_p_len.mean(), users_in_group_p_len.min(), users_in_group_p_len.max())) users_not_in_group_flag = np.isin(self.sortedusers, users_in_group, invert=True) users_not_in_group = self.sortedusers[users_not_in_group_flag] users_in_group = list( set(self.initial_target_user) - set(list(users_not_in_group))) results = evaluate_algorithm_classes(self.URM_test, users_in_group, self.ItemCBF, at=10) MAP_ItemCBF_per_group.append(results) results = evaluate_algorithm_classes(self.URM_test, users_in_group, self.ItemCF, at=10) MAP_ItemCF_per_group.append(results) results = evaluate_algorithm_classes(self.URM_test, users_in_group, self.UserCF, at=10) MAP_UserCF_per_group.append(results) results = evaluate_algorithm_classes(self.URM_test, users_in_group, self.Slim, at=10) MAP_Slim_per_group.append(results) results = evaluate_algorithm_classes(self.URM_test, users_in_group, self.Elastic, at=10) MAP_Elastic_per_group.append(results) results = evaluate_algorithm_classes(self.URM_test, users_in_group, self.PureSVD, at=10) MAP_PureSVD_per_group.append(results) results = evaluate_algorithm_classes(self.URM_test, users_in_group, self.P3Alpha, at=10) MAP_P3Alpha_per_group.append(results) results = evaluate_algorithm_classes(self.URM_test, users_in_group, self.RP3Beta, at=10) MAP_RP3Beta_per_group.append(results) results = evaluate_algorithm_classes(self.URM_test, users_in_group, self.UserCBF, at=10) MAP_UserCBF_per_group.append(results) results = evaluate_algorithm_classes(self.URM_test, users_in_group, self.ALS, at=10) MAP_ALS_per_group.append(results) results = evaluate_algorithm_classes(self.URM_test, users_in_group, self.H6_bis, at=10) MAP_H6_bis_per_group.append(results) pyplot.plot(MAP_UserCBF_per_group, label="UserCBF") pyplot.plot(MAP_ItemCBF_per_group, label="ItemCBF") pyplot.plot(MAP_ItemCF_per_group, label="ItemCF") pyplot.plot(MAP_UserCF_per_group, label="UserCF") pyplot.plot(MAP_Slim_per_group, label="Slim") pyplot.plot(MAP_Elastic_per_group, label="Elastic") pyplot.plot(MAP_P3Alpha_per_group, label="P3Alpha") pyplot.plot(MAP_RP3Beta_per_group, label="RP3Beta") pyplot.plot(MAP_PureSVD_per_group, label="PureSVD") pyplot.plot(MAP_ALS_per_group, label="ALS") pyplot.plot(MAP_H6_bis_per_group, label="H6_bis") pyplot.xlabel('User Group') pyplot.ylabel('MAP') pyplot.xticks(np.arange(0, 20, 1)) pyplot.grid(b=True, axis='both', color='firebrick', linestyle='--', linewidth=0.5) pyplot.legend(loc='lower right') pyplot.show()
class Tuner_Singles(): ####################################################################################### # INIT CLASS # ####################################################################################### def __init__(self, recommender, name): self.recommender = recommender self.name = name self.helper = BaseFunction() self.helper.get_URM() self.helper.get_ICM() self.helper.get_UCM() self.helper.split_80_20() self.helper.get_target_users() ####################################################################################### # TEP FOR TUNING # ####################################################################################### def step_weight(self, w1, w2): start_time = time.time() print("----------------------------------------") print("HybridCombination: " + self.name) print([w1, w2]) print("----------------------------------------") list_UCM = [self.helper.UCM_age, self.helper.UCM_region] list_ICM = [ self.helper.ICM, self.helper.ICM_price, self.helper.ICM_asset ] self.recommender.fit(self.helper.URM_train, [w1, w2], list_ICM=list_ICM, list_UCM=list_UCM, tuning=False) cumulative = evaluation.evaluate_algorithm(self.helper.URM_test, self.recommender, at=10) elapsed_time = time.time() - start_time print("----------------" + str(elapsed_time) + "----------------") return cumulative ####################################################################################### # GENETIC ALGORITHM # ####################################################################################### def random_pop(self): weights = [] for i in range(self.pop_size): w1 = random.randint(250, 600) # epoch w2 = random.randint(100, 300) # knn line = [w1, w2] weights.append(np.array(line)) return weights def evaluate_pop(self): appo = [] for chromosome in self.pop: res = self.evaluate_chromosome(chromosome) appo.append(res) return appo def evaluate_chromosome(self, chromosome): return self.step_weight(w1=chromosome[0], w2=chromosome[1]) def my_index(self, l, item): for i in range(len(l)): if (item == l[i]).all(): return i return -1 def select_parents(self): sorted_pop_score = sorted(self.pop_scores, reverse=False) probs = [] taken_pop = [False] * self.pop_size taken_score = [False] * self.pop_size l = (self.pop_size * (self.pop_size + 1)) / 2 for i in self.pop: pos_of_i_in_pop = self.my_index(self.pop, i) while taken_pop[pos_of_i_in_pop]: pos_of_i_in_pop += self.my_index( self.pop[pos_of_i_in_pop + 1:], i) + 1 score_of_pos = self.pop_scores[pos_of_i_in_pop] ranking = self.my_index(sorted_pop_score, score_of_pos) while taken_score[ranking]: ranking += self.my_index(sorted_pop_score[ranking + 1:], score_of_pos) + 1 taken_score[ranking] = True taken_pop[pos_of_i_in_pop] = True prob = (ranking + 1) / l probs.append(prob) parents = [ self.pop[i] for i in np.random.choice(len(self.pop), 2, p=probs) ] return parents def generate_offspring(self, p1, p2): size = len(p1) offspring = np.empty((size), dtype='object') offspring[0] = p1[0] offspring[1] = p2[1] return offspring def crossover(self, parents): offspring1 = self.generate_offspring(parents[0], parents[1]) offspring2 = self.generate_offspring(parents[1], parents[0]) offspring1 = self.mutation(offspring1) offspring2 = self.mutation(offspring2) return offspring1, offspring2 def mutation(self, offspring): if np.random.choice([True, False], 1, p=[self.p_mutation, 1 - self.p_mutation]) == True: offspring += random.randint(0, 100) return offspring def elitism(self): els = self.pop[:] score_c = self.pop_scores[:] for _ in range(4): index = np.argmax(score_c) score_c.pop(index) self.new_pop.append(els.pop(index)) ####################################################################################### # RUN GENETIC ALGORITHM # ####################################################################################### def run(self, max=1000, pop_size=10, p_mutation=0.1): self.pop_size = pop_size self.p_mutation = p_mutation self.pop = self.random_pop() self.pop_scores = self.evaluate_pop() for i in range(max): self.new_pop = [] self.elitism() while len(self.new_pop) < len(self.pop): parents = self.select_parents() off1, off2 = self.crossover(parents) self.new_pop.append(off1) self.new_pop.append(off2) self.pop = self.new_pop self.pop_scores = self.evaluate_pop() print("-----------------ENDED------------------") print(self.pop) print(np.argmax(self.pop_scores)) print("----------------------------------------")