# -*- coding: utf-8 -*- """HS_Recomm_Metacritic_Gradio.ipynb Automatically generated by Colaboratory. Original file is located at https://colab.research.google.com/drive/1cIAUS8Z2U2DXPEVmRdou9mqI0vwNT0_0 """ import pandas as pd import numpy as np import scipy as sp from scipy import sparse from sklearn.metrics.pairwise import cosine_similarity from fuzzywuzzy import fuzz import gradio as gr meta_df = pd.read_csv("Metacritic_Scores_File.csv", error_bad_lines=False, encoding='utf-8') meta_df = meta_df[['game', 'reviewer_ID', 'score']] df_game_names = pd.read_csv("Game_Titles_IDs.csv", error_bad_lines=False, encoding='utf-8') #We will create a pivot table of users as rows and games as columns. #The pivot table will help us make the calcuations of similarity between the reviewers. pivot = meta_df.pivot_table(index=['reviewer_ID'], columns=['game'], values='score') #Applying lambda function to multiple rows using Dataframe.apply() #(x-np.mean(x))/(np.max(x)-np.min(x)) = Formula pivot_n = pivot.apply(lambda x: (x-np.mean(x))/(np.max(x)-np.min(x)), axis=1) # step 2 - Fill NaNs with Zeros pivot_n.fillna(0, inplace=True) # step 3 - Transpose the pivot table pivot_n = pivot_n.T # step 4 - Locate the columns that are not zero (unrated) pivot_n = pivot_n.loc[:, (pivot_n != 0).any(axis=0)] # step 5 - Create a sparse matrix based on our pivot table piv_sparse = sp.sparse.csr_matrix(pivot_n.values) #Compute cosine similarity between samples in X and Y. game_similarity = cosine_similarity(piv_sparse) #Turn our similarity kernel matrix into a dataframe game_sim_df = pd.DataFrame(game_similarity, index = pivot_n.index, columns = pivot_n.index) # create a function to find the closest title def matching_score(a,b): #fuzz.ratio(a,b) calculates the Levenshtein Distance between a and b, and returns the score for the distance return fuzz.ratio(a,b) # exactly the same, the score becomes 100 # a function to convert index to title def get_title_from_index(index): return df_game_names.iloc[index]['game'] # a function to return the most similar title to the words a user type def find_closest_title(title): #matching_score(a,b) > a is the current row, b is the title we're trying to match leven_scores = list(enumerate(df_game_names['game'].apply(matching_score, b=title))) sorted_leven_scores = sorted(leven_scores, key=lambda x: x[1], reverse=True) closest_title = get_title_from_index(sorted_leven_scores[0][0]) distance_score = sorted_leven_scores[0][1] return closest_title, distance_score # Bejeweled Twist, 100 def game_recommendation(game): #Insert closest title here game, distance_score = find_closest_title(game) #Counter for Ranking number = 1 print('Recommended because you played {}:\n'.format(game)) for n in game_sim_df.sort_values(by = game, ascending = False).index[1:6]: print("#" + str(number) + ": " + n + ", " + str(round(game_sim_df[game][n]*100,2)) + "% " + "match") number +=1 recommender_interface = gr.Interface(game_recommendation, ["text"], ["text"], title="Top 5 Game Recommendations", description="This is a Recommendation Engine based on how Metacritic professional reviewers have scored games up to 2019 (apologies for the out of date data). Simply input a game you have enjoyed playing and it should return 5 games that have been rated similarily") recommender_interface.launch(debug=True)