def merge_users(db_conn_conf, group_user_id, ratings, merge_fun): """Merge users using given strategy (merge function) """ individual_ratings = merge(ratings, merge_fun) db_conn = RSDBConnection(db_conn_conf) db_conn.insert_user_ratings(group_user_id, individual_ratings) db_conn.finalize()
def get_users_ratings_dict(db_conn_conf, user_ids): """Create dict with ratings for given users """ db_conn = RSDBConnection(db_conn_conf) raw_ratings = {user_id: db_conn.get_user_ratings(user_id) for user_id in user_ids} db_conn.finalize() return format_data(raw_ratings), len(user_ids)
def check_numplayers(db_conn_conf, num_players, game_id): """Check if given number of players is relevant to given game """ db_conn = RSDBConnection(db_conn_conf) min_players, max_players = db_conn.get_numplayers(game_id) db_conn.finalize() return min_players <= num_players and num_players <= max_players
def get_users_recommendations_dict(db_conn_conf, user_ids): """Create dict with recommendations for given users """ db_conn = RSDBConnection(db_conn_conf) raw_recommendations = { user_id: read_recommendation_from_file(db_conn_conf, db_conn.get_user_name(user_id)) for user_id in user_ids } db_conn.finalize() return format_data(raw_recommendations), len(user_ids)
def check_numplayers(numplayers, game_id): rsdbc = RSDBConnection() minplayers, maxplayers = rsdbc.get_numplayers(game_id) print 'gameid ', game_id print 'numplayers ', numplayers print 'minplayers ', minplayers print 'maxplayers ', maxplayers rsdbc.finalize() return minplayers <= numplayers and numplayers <= maxplayers
def recommend_fun(db_conn_conf, user_ids, group_name): ratings, num_players = get_users_ratings_dict(db_conn_conf, user_ids) db_conn = RSDBConnection(db_conn_conf) full_group_name = "group_" + merge_fun.__name__ + "_" + group_name group_user_id = db_conn.add_user(full_group_name) db_conn.finalize() merge_users(db_conn_conf, group_user_id, ratings, merge_fun) return gen_and_print_recommendation(db_conn_conf, full_group_name, num_players)
def merge_user_max(user_id, ratings): """For each game get maximum from users' from group rating """ rsdbc = RSDBConnection() individual_ratings = {} for game_id, game_ratings in ratings.iteritems(): user_id_max_rating = max(game_ratings.iteritems(), key=operator.itemgetter(1))[0] max_rating = game_ratings[user_id_max_rating] individual_ratings[game_id] = max_rating print individual_ratings rsdbc.insert_user_ratings(user_id, individual_ratings) rsdbc.finalize()
def merge_user_avg(user_id, ratings): """For each game get average from users' from group rating """ rsdbc = RSDBConnection() individual_ratings = {} for game_id, game_ratings in ratings.iteritems(): ratings = [game_ratings[i] for i in game_ratings] avg_rating = sum(ratings)/len(ratings) individual_ratings[game_id] = avg_rating print individual_ratings rsdbc.insert_user_ratings(user_id, individual_ratings) rsdbc.finalize()
def gen_and_print_recommendation(db_conn_conf, group_name, numplayers): """Function for generating and printing recommendation """ recommendation = read_recommendation_from_file(db_conn_conf, group_name) with open("recommendations/" + group_name + "_result", "w") as save_file: for game_id, prob in recommendation: if check_numplayers(db_conn_conf, numplayers, game_id): rsdbc = RSDBConnection() game = rsdbc.get_game_name(game_id) rsdbc.finalize() save_file.write("{};{}\n".format(prob, game)) return recommendation
def generate_and_print_recommendation(group_name, numplayers): """Function for generating and printing recommendation """ print "\nI'M RECOMMENDING\n" recommendation = read_recommendation_from_file(group_name) print 'mam rekomendacje\n\n' with open('recommendations/'+group_name + '_result', 'w') as save_file: for game_id, prob in recommendation: print 'jestem w forze\n numplayers ' print numplayers if check_numplayers(numplayers, game_id): print 'sprawdzam numplayers \n' rsdbc = RSDBConnection() game = rsdbc.get_game_name(game_id) rsdbc.finalize() print '{:.3f}\t{}'.format(prob, game) save_file.write('{} ;{}\n'.format(prob, game))
def generate_individual_recommendation(user_name): """Generate recommendation for single user """ rec_file = open('recommendations/'+user_name, 'w+') rsdbc = RSDBConnection() user_id = rsdbc.get_user_id(user_name) data = download_data(rsdbc) recommender = build_recommender(data) print "Recommending items..." recommendation = recommender.recommend(user_id) #print "Recommendations:\nprob\tgame" for game_id, prob in recommendation: #game = rsdbc.get_game_name(game_id) #print '{:.3f}\t{}'.format(prob, game) rec_file.write('{};{}\n'.format(game_id, prob)) rsdbc.finalize() rec_file.close() return recommendation
def merge_rec_avg(ratings): """For each game get average from users' from group rating """ individual_ratings = {} group_name = '' for game_id, game_ratings in ratings.iteritems(): ratings = [game_ratings[i] for i in game_ratings] group_name = "_".join(game_ratings.keys()) avg_rating = sum(ratings)/len(ratings) individual_ratings[game_id] = avg_rating sorted_recommendations = sorted(individual_ratings.items(), key=operator.itemgetter(1), reverse=True) print sorted_recommendations with open('recommendations/'+group_name+'_avg', 'w') as save_file: rsdbc = RSDBConnection() for game_id, recommendation in sorted_recommendations: game_name = rsdbc.get_game_name(game_id) save_file.write('{};{}\n'.format(recommendation, game_name)) rsdbc.finalize()
def merge_rec_max(ratings): """For each game get maximum from users' from group rating """ individual_ratings = {} group_name = '' for game_id, game_ratings in ratings.iteritems(): user_id_max_rating = max(game_ratings.iteritems(), key=operator.itemgetter(1))[0] group_name = "_".join(game_ratings.keys()) max_rating = game_ratings[user_id_max_rating] individual_ratings[game_id] = max_rating sorted_recommendations = sorted(individual_ratings.items(), key=operator.itemgetter(1), reverse=True) print sorted_recommendations with open('recommendations/'+group_name+'_max', 'w') as save_file: rsdbc = RSDBConnection() for game_id, recommendation in sorted_recommendations: game_name = rsdbc.get_game_name(game_id) save_file.write('{};{}\n'.format(recommendation, game_name)) rsdbc.finalize()
def main(number_of_groups, max_group_size=4): """Evaluate the system on a given number of random groups """ db_conn_conf = {"user": "******", "host": "localhost", "database": "bgg"} recommendation_functions = [ recommend_merge_users(avg), recommend_merge_users(max), recommend_merge_users(min), recommend_merge_recommendations(avg), recommend_merge_recommendations(max), recommend_merge_recommendations(min), ] user_groups = [] db_conn = RSDBConnection(db_conn_conf) for _ in range(number_of_groups): user_groups.append(db_conn.get_random_user_group(max_group_size)) db_conn.finalize() # user_groups = [[113, 145]] for user_group in user_groups: db_conn = RSDBConnection(db_conn_conf) user_names = [db_conn.get_user_name(user_id) for user_id in user_group] group_name = "_".join(user_names) db_conn.finalize() print "Evaluating user group: ", group_name user_rating_functions = [get_user_ratings(user_id) for user_id in user_group] evaluation_functions = user_rating_functions + recommendation_functions results_list = [dict(recommend(db_conn_conf, user_group, group_name)) for recommend in evaluation_functions] print results_list game_ids = set.union(*[set(reco.keys()) for reco in results_list]) print game_ids results_dict = {game_id: [] for game_id in game_ids} print results_dict # convert list of dicts into dict with list values results_dict = { game_id: [reco.get(game_id, None) for reco in results_list] for game_id in set.union(*[set(reco.keys()) for reco in results_list]) } print results_dict with open("eval/" + group_name + ".tsv", "wb") as eval_results_file: writer = csv.writer(eval_results_file, delimiter="\t") headings = ( ["game_id"] + user_names + ["merge_usr_avg", "merge_usr_max", "merge_usr_min", "merge_rec_avg", "merge_rec_max", "merge_rec_min"] ) writer.writerow(headings) for game_id, results in sorted(results_dict.items()): writer.writerow([game_id] + results)
def gen_individual_recommendation(db_conn_conf, user_name): """Generate recommendation for single user """ rec_file = open("recommendations/" + user_name, "w+") db_conn = RSDBConnection(db_conn_conf) user_id = db_conn.get_user_id(user_name) data = db_conn.get_data_for_rs() db_conn.finalize() recommender = build_recommender(data) print "Recommending items for user:"******"{};{}\n".format(game_id, prob)) rec_file.close() return recommendation
def get_user_ratings_for_game(): """Function for getting ratings of chosen game_name """ ratings = {} menu = {} menu['0'] = 'End.' menu['1'] = 'Add rating' user_name = raw_input("Give your username\n") rsdbc = RSDBConnection() user_id = rsdbc.get_user_id(user_name) rsdbc.finalize() while(True): options = menu.keys() options.sort() for entry in options: print entry, menu[entry] selection = raw_input("Please select: ") if selection == '0': return user_id, ratings elif selection == '1': game_name = raw_input("Please give the name of the game you want to rate: ") game_name = game_name.lower() game_name = '%' + game_name + '%' rsdbc = RSDBConnection() games = rsdbc.get_game_full_name(user_id, game_name) rsdbc.finalize() print("\nPlease rate the game you meant).\n" "If it's not the one you meant, just hit ENTER.\n" "If you want to quit, just write '-1' and ENTER\n") rating = 100 i = 0 while (rating != 0): if len(games) == 0: print 'Cannot find the game!\n' break rating = raw_input('"{}": '.format(games[i][1])) if rating: rating = float(rating) if rating< 1: rating = 1.0 elif rating > 10: rating= 10.0 ratings[games[i][0]] = rating if i +1 < len(games): i += 1 else: break else: print "Unknown option selected!\n"
def main(): """Do the stuff """ menu = {} menu['5'] = 'Add new user' menu['1'] = 'Add ratings for games' menu['2'] = 'Generate individual recommendation' menu['3'] = 'Generate group recommendation' menu['4'] = 'Show me my ratings' menu['0'] = 'Quit' while True: options = menu.keys() options.sort() for entry in options: print entry, menu[entry] selection = raw_input("Please select: ") if selection == '5': add_new_user() elif selection == '1': user_id, ratings = get_user_ratings_for_game() rsdbc = RSDBConnection() rsdbc.insert_user_ratings(user_id, ratings) rsdbc.finalize() elif selection == '2': user_name = raw_input("Give user name for counting recommendation: ") recommendation = read_recommendation_from_file(user_name) rsdbc = RSDBConnection() for game_id, prob in recommendation[:50]: game = rsdbc.get_game_name(game_id) print '{:.3f}\t{}'.format(prob, game) rsdbc.finalize() elif selection == '3': make_group_recommendation() elif selection == '4': show_user_ratings() elif selection == '0': print '\n\nBye!' break else: print "Unknown option selected!\n"
def add_new_user(): """ Add new user to database """ rsdbc = RSDBConnection() user = raw_input("What's your name? ") user_id = rsdbc.add_user(user) while not user_id: user = raw_input( "This name isn't available. Choose another one: ") user_id = rsdbc.add_user(user) ratings = collect_user_ratings(rsdbc, user_id) rsdbc.insert_user_ratings(user_id, ratings) rsdbc.finalize()
def create_dict_with_group_ratings(): """Function that creates a dict with user ratings from our group """ rsdbc = RSDBConnection() menu = {} menu['1'] = 'Add user to group' menu['0'] = 'End' user_ids = [] ratings = {} game_ratings = {} while(True): options = menu.keys() options.sort() for entry in options: print entry, menu[entry] selection = raw_input("Please select: ") if selection == '1': user_name = raw_input("Please give the user name of existing user: ") user_id = rsdbc.get_user_id(user_name) user_ids.append(user_id) elif selection == '0': break else: print 'Wrong option!\n' for user_id in user_ids: rating = rsdbc.get_user_ratings(user_id) ratings[user_id] = rating rsdbc.finalize() for user_id, game_dict in ratings.iteritems(): for game_id, rating in game_dict: if game_id in game_ratings: game_ratings[game_id] [user_id] = rating else: game_ratings[game_id] = {user_id:rating} return game_ratings, len(user_ids)
def show_user_ratings(): """Show ratings for a given user """ rsdbc = RSDBConnection() user_name = raw_input("Please enter your username\n") user_id = rsdbc.get_user_id(user_name) ratings = rsdbc.get_user_ratings(user_id) print '\n\nrating\t\t game' for elem in ratings: game_name = rsdbc.get_game_name(elem[0]) print '{1}\t\t {0}'.format(game_name, elem[1]) print "\n\n" rsdbc.finalize()
def resulting_fun(db_conn_conf, user_ids, group_name): db_conn = RSDBConnection(db_conn_conf) ratings = db_conn.get_user_ratings(user_id) recommendations = read_recommendation_from_file(db_conn_conf, db_conn.get_user_name(user_id)) db_conn.finalize() return ratings + recommendations
def make_group_recommendation(): """Display menu for choose of method of group recommendation. Call appropriate method of group recommendation. Merge multiple users to one user or merge individual recommendations into group one. """ menu_rec = {} menu_rec['2'] = 'Merge users approach ' menu_rec['1'] = 'Merge recommendations approach ' menu_rec['0'] = 'Back ' while(True): options = menu_rec.keys() options.sort() for entry in options: print entry, menu_rec[entry] selection = raw_input("Please select: ") if selection == '2': group_ratings, numplayers = create_dict_with_group_ratings() group_name = raw_input("Please provide a name for your group: ") rsdbc = RSDBConnection() user_id = rsdbc.add_user(group_name) # while not user_id: # group_name = raw_input( # "This name isn't available. Choose another one: ") # user_id = rsdbc.add_user(group_name) rsdbc.finalize() menu_user_approach = {} menu_user_approach['0'] = 'Back' menu_user_approach['1'] = 'User Minimum strategy ' menu_user_approach['2'] = 'User Maximum strategy ' menu_user_approach['3'] = 'User Avg strategy ' options2 = menu_user_approach.keys() options2.sort() for entry2 in options2: print entry2, menu_user_approach[entry2] selection2 = raw_input("Please select: ") if selection2 == '0': break elif selection2 == '1': merge_user_least_misery(user_id, group_ratings) generate_and_print_recommendation(group_name, numplayers) elif selection2 == '2': merge_user_max(user_id, group_ratings) generate_and_print_recommendation(group_name, numplayers) elif selection2 == '3': merge_user_avg(user_id, group_ratings) generate_and_print_recommendation(group_name, numplayers) else: print 'Wrong option!\n' elif selection == '0': break elif selection == '1': group_ratings, numplayers = create_dict_with_group_recommendations() menu_rec_approach = {} menu_rec_approach['0'] = 'Back' menu_rec_approach['1'] = 'Minimum strategy ' menu_rec_approach['2'] = 'Maximum strategy ' menu_rec_approach['3'] = 'Avg strategy ' options3 = menu_rec_approach.keys() options3.sort() for entry3 in options3: print entry3, menu_rec_approach[entry3] selection3 = raw_input("Please select: ") if selection3 == '0': break elif selection3 == '1': merge_rec_least_misery(group_ratings) elif selection3 == '2': merge_rec_max(group_ratings) elif selection3 == '3': merge_rec_avg(group_ratings) else: print 'Wrong option!\n' else: print 'Wrong option!\n'
#!/usr/bin/python # -*- coding: utf-8 -*- """Parse data from BoardGameGeek XMLs and insert them to MySQL database""" from rs_db_connection import RSDBConnection if __name__ == "__main__": rsdbc = RSDBConnection() rsdbc.create_tables() rsdbc.process_games("dane") # rsdbc.show_games() rsdbc.process_users("users") rsdbc.finalize() print "Done."