user_2_anime_df = relavence_scores.groupby("user_id").agg({"anime_id":lambda x:list(set(x))}) user_2_anime_map = dict(zip(user_2_anime_df.index,user_2_anime_df['anime_id'])) #create candidate pool, this will be a all the animes in the database candidate_pool = anime_info_df_final['anime_id'].unique().tolist() #anime_id to it's name mapping anime_id_2_name = relavence_scores.drop_duplicates(subset=["anime_id","Name"])[['anime_id',"Name"]] anime_id_2_name_map = dict(zip(anime_id_2_name['anime_id'],anime_id_2_name['Name'])) def candidate_generation(user_id:int,candidate_pool:list,user_2_anime_map:dict,N:int): """ Note: this a totally random generation, only for demo purpose Generates a list of N anime candidates for a given user based on their previously liked animes. Parameters: user_id (int): The user's ID. candidate_pool (list): A list of all possible anime candidates. user_2_anime_map (dict): A dictionary that maps users to their liked animes. N (int): The number of anime candidates to generate. Returns: already_interacted (list): List of animes which user already liked candidates (list): A list of N anime candidates for the user. """ #get the already liked animes already_interacted = user_2_anime_map[user_id] #candidates will be rest of animes which are not exposed to user candidates = list(set(candidate_pool) - set(already_interacted)) return already_interacted,np.random.choice(candidates,size=N) def generate_predictions(user_id,user_2_anime_map,candidate_pool,feature_columns,anime_id_2_name_map,ranker,N=100): """ Generates predictions for anime recommendations for a given user. Parameters: user_id (int): The user's ID. user_2_anime_map (dict): A dictionary that maps users to their liked animes. candidate_pool (list): A list of all possible anime candidates. feature_columns (list): A list of feature columns to use for generating predictions. anime_id_2_name_map (dict): A dictionary that maps anime IDs to their names. ranker (object): A trained model object that is used to generate predictions. N (int): The number of anime predictions to generate. Returns: predictions (DataFrame): A dataframe containing the top N anime recommendations for the user. """ already_liked,candidates = candidate_generation(user_id,candidate_pool,user_2_anime_map,N=10000) #Create dataframe for candidates candidates_df = pd.DataFrame(data=pd.Series(candidates,name='anime_id')) # Merge with feature dataframe features = anime_info_df_final.merge(candidates_df) #Add user id as a feature features['user_id'] = user_id # Merge with user information features = features.merge(user_info) # If number of already liked animes is less than number of candidates # Extend the already liked list with -1 already_liked = list(already_liked) if len(already_liked) < len(candidates): append_list = np.full(fill_value=-1,shape=(len(candidates)-len(already_liked))) already_liked.extend(list(append_list)) #Create dataframe for predictions predictions = pd.DataFrame(index=candidates) #Add anime names predictions['name'] = np.array([anime_id_2_name_map.get(id_) for id_ in candidates]) #Generate predictions predictions['score'] = ranker.predict(features[feature_columns]) predictions = predictions.sort_values(by='score',ascending=False).head(N) predictions[f'already_liked - sample[{N}]'] = [anime_id_2_name_map.get(id_) for id_ in already_liked[0:len(predictions)]] return predictions #let's generate the predictions generate_predictions(123,user_2_anime_map,candidate_pool,feature_columns=features,anime_id_2_name_map=anime_id_2_name_map,ranker=model,N=10)