import pandas as pd def get_limited_similarity(df, compressed_matrix, compressed_values_matrix, indices, spotify_id, top_n=10): # Get the index corresponding to artist spotify id index = indices[spotify_id] # find artist related data artist_attribute_spot = df['SPOTIFY_ARTIST_ID'].iloc[index] artist_attribute_genre = df['C_GENRES'].iloc[index] artist_attribute_name = df['C_ARTIST_NAME'].iloc[index] artist_attribute_country = df['C_FAN_COUNTRY_CODE'].iloc[index] print(f"Spotify id: {artist_attribute_spot}.\nartist name: {artist_attribute_name}.\ntop streaming countries: {artist_attribute_country}.\ngenres: {artist_attribute_genre[0:75]}") # first 75 characters print("------------") # print top indexes matches = compressed_matrix[index] recommendation_df = pd.DataFrame() counter = 0 for m in matches: # exclude comparison with itself if m !=index: _dict = { 'index': m, 'score': compressed_values_matrix[index][counter], 'name': df['C_ARTIST_NAME'].iloc[m], 'popularity': df['C_POPULARITY'].iloc[m], 'spotify_id': df['SPOTIFY_ARTIST_ID'].iloc[m], 'streaming_country': df['C_FAN_COUNTRY_CODE'].iloc[m], 'spotify_genre': df['C_GENRES'].iloc[m], #'spotify_description': df['C_DESCRIPTION'].iloc[m], } _x = pd.DataFrame([_dict]) recommendation_df = pd.concat([recommendation_df, _x]) #top_10_artist_indices.append(i[ 0]) counter +=1 recommendation_df = recommendation_df.sort_values(by=['score', 'popularity'], ascending=[False,False]) return recommendation_df def get_similarity(df, similarity_matrix, indices, spotify_id, top_n=10): """ Find most similar artists :param df: Dataframe containing all the data used for calculating similarities. :param similarity_matrix: Matrix containing all artists' similarity scores with other artists. :param indices: Index containing spotify_id's and indexes for better retreival of data from df. :param spotify_id: The spotify id of artist we want to use for similarity. :param top_n: Number of similar artists to return. Default 10. :return: Dataframe containing top_n most similar artists ordered by score descending. """ # Get the index corresponding to artist spotify id index = indices[spotify_id] # find artist related data artist_attribute_genre = df['C_GENRES'].iloc[index] artist_attribute_name = df['C_ARTIST_NAME'].iloc[index] artist_attribute_country = df['C_FAN_COUNTRY_CODE'].iloc[index] artist_attribute_tag = df['C_TAG_NAME'].iloc[index] print(f"artist index: {index}.\nartist name: {artist_attribute_name}.\nplaylist tag: {artist_attribute_tag}.\ntop streaming countries: {artist_attribute_country}.\ngenres: {artist_attribute_genre[0:75]}") # first 75 characters # Get the cosine similarity scores similarity_scores = list(enumerate(similarity_matrix[index])) # Sort the similarity scores in descending order sorted_similarity_scores = sorted(similarity_scores, key=lambda x: x[1], reverse=True) # Top-n most similar spotify artists top_10_artist_scores = sorted_similarity_scores[1:top_n+1] # Build recommendations dataframe recommendation_df = pd.DataFrame() top_10_artist_indices=[] for i in top_10_artist_scores: # don't include 0 rating or comparison with itself if i[1] > 0.0 and index != i[0]: _dict = {'index': i[0], 'score': i[1], 'name': df['C_ARTIST_NAME'].iloc[i[0]], 'popularity': df['C_POPULARITY'].iloc[i[0]], 'spotify_id': df['SPOTIFY_ARTIST_ID'].iloc[i[0]], 'streaming_country': df['C_FAN_COUNTRY_CODE'].iloc[i[0]], 'spotify_genre': df['C_GENRES'].iloc[i[0]], 'playlist_tags': df['C_TAG_NAME'].iloc[i[0]], 'spotify_description': df['C_DESCRIPTION'].iloc[i[0]], } _x = pd.DataFrame([_dict]) recommendation_df = pd.concat([recommendation_df, _x]) top_10_artist_indices.append(i[0]) recommendation_df = recommendation_df.sort_values(by=['score', 'popularity'], ascending=[False,False]) return recommendation_df def compare_similarity_approaches(df1, df2, genre_matrix, genre_location_matrix, genre_index, genre_location_index, spotify_id, top_n=5): """ Compare similarity scores from 2 different approaches :param df1: First Dataframe containing all the data used for calculating similarities. :param df2: Second Dataframe containing all the data used for calculating similarities. :param genre_matrix: Matrix containing all artists' genre similarity scores with other artists. :param genre_location_matrix: Matrix containing all artists' genre and location similarity scores with other artists. :param genre_index: Index containing spotify_id's and indexes for better retreival of data from df1. :param genre_location_index: Index containing spotify_id's and indexes for better retreival of data from df2. :param spotify_id: The spotify id of artist we want to use for similarity. :param top_n: Number of similar artists to return. Default 10. :return: Dataframe containing top_n most similar artists ordered by score descending combined from df1 and df2. """ index_g = genre_index[spotify_id] index_g_l = genre_location_index[spotify_id] artist_attribute_1_g = df1['C_GENRES'].iloc[index_g] artist_attribute_1_n = df1['C_ARTIST_NAME'].iloc[index_g] artist_attribute_1_cc = df1['C_FAN_COUNTRY_CODE'].iloc[index_g] print(f"artist index: {index_g}.\nartist name: {artist_attribute_1_n}.\ntop streaming ountries: {artist_attribute_1_cc}.\ngenres: {artist_attribute_1_g[0:75]}") # first 75 characters artist_attribute_2_g = df2['C_GENRES'].iloc[index_g_l] artist_attribute_2_n = df2['C_ARTIST_NAME'].iloc[index_g_l] # Get the sorted cosine similarity scores for first matrix similarity_scores_genre = list(enumerate(genre_matrix[index_g])) sorted_similarity_scores_genre = sorted(similarity_scores_genre, key=lambda x: x[1], reverse=True) # Get the sorted cosine similarity scores for second matrix similarity_scores_genre_loc = list(enumerate(genre_location_matrix[index_g_l])) sorted_similarity_scores_genre_loc = sorted(similarity_scores_genre_loc, key=lambda x: x[1], reverse=True) # Top-n most similar spotify artists from first matrix top_10_artist_scores_genre = sorted_similarity_scores_genre[1:top_n+1] # Top-n most similar spotify artists from second matrix top_10_artist_scores_genre_loc = sorted_similarity_scores_genre_loc[1:top_n+1] # Get spotify artist id indices for first approach recommendation_df_1 = pd.DataFrame() _dict2_1 = {} top_10_artist_indices_1=[] for i in top_10_artist_scores_genre: # don't include 0 rating or comparison with itself if i[1] > 0.0 and index_g != i[0]: _dict_1 = {'index': i[0], 'score': i[1], 'name': df1['C_ARTIST_NAME'].iloc[i[0]], 'popularity': df1['C_POPULARITY'].iloc[i[0]], 'spotify_id': df1['SPOTIFY_ARTIST_ID'].iloc[i[0]], 'spotify_genre': df1['C_GENRES'].iloc[i[0]], 'spotify_description': df1['C_DESCRIPTION'].iloc[i[0]], 'streaming_countries': df1['C_FAN_COUNTRY_CODE'].iloc[i[0]], } _x_1 = pd.DataFrame([_dict_1]) recommendation_df_1 = pd.concat([recommendation_df_1, _x_1]) top_10_artist_indices_1.append(i[0]) recommendation_df_1 = recommendation_df_1.sort_values(by=['score', 'popularity'], ascending=[False,False]) # Get spotify artist id indices for second approach recommendation_df_2 = pd.DataFrame() _dict2_2 = {} top_10_artist_indices_2=[] for ii in top_10_artist_scores_genre_loc: # don't include 0 rating or comparison with itself if ii[1] > 0.0 and index_g_l != i[0]: _dict_2 = {'index': ii[0], 'score': ii[1], 'name': df2['C_ARTIST_NAME'].iloc[ii[0]], 'popularity': df2['C_POPULARITY'].iloc[ii[0]], 'spotify_id': df2['SPOTIFY_ARTIST_ID'].iloc[ii[0]], 'spotify_genre': df2['C_GENRES'].iloc[ii[0]], 'spotify_description': df2['C_DESCRIPTION'].iloc[ii[0]], 'streaming_countries': df2['C_FAN_COUNTRY_CODE'].iloc[ii[0]], } _x_2 = pd.DataFrame([_dict_2]) recommendation_df_2 = pd.concat([recommendation_df_2, _x_2]) top_10_artist_indices_2.append(i[0]) recommendation_df_2 = recommendation_df_2.sort_values(by=['score', 'popularity'], ascending=[False,False]) concatenated_df = pd.concat([recommendation_df_1[['score','name','popularity', 'spotify_genre']], recommendation_df_2[['score','name','popularity', 'spotify_genre', 'streaming_countries']]], axis="columns") concatenated_df.columns = ['first_score', 'artist_name', 'artist_popularity', 'artist_genre','second_score', 'artist_name', 'artist_popularity', 'artist_genre', 'streaming_countries'] return concatenated_df def find_knn_similarities(df,tf_knn, nn, spotify_id): """ Find most similar artists using KNN algorithm :param df: Dataframe containing all the data used for calculating similarities. :param tf_knn: Matrix containing all artists and genres. :param nn: NearestNeighbors model. :param spotify_id: The spotify id of artist we want to use for similarity. :return: Dataframe containing top_n most similar artists ordered by score descending. """ artist_index_value = df.index[df['SPOTIFY_ARTIST_ID']==spotify_id].tolist()[0] search_artist = df[df['SPOTIFY_ARTIST_ID']==spotify_id]['COMBINED'].astype(str) artist_attribute_genre = df['C_GENRES'].iloc[artist_index_value] artist_attribute_name = df['C_ARTIST_NAME'].iloc[artist_index_value] artist_attribute_country = df['C_FAN_COUNTRY_CODE'].iloc[artist_index_value] print(f"artist index: {artist_index_value}.\nartist name: {artist_attribute_name}.\ntop streaming countries: {artist_attribute_country}.\ngenres: {artist_attribute_genre[0:75]}") # first 75 characters new = tf_knn.transform(search_artist) results = nn.kneighbors(new.todense()) knn_df = pd.DataFrame() for e, knn_i in enumerate(results[1][0]): score = [results[0][0][e]][0] index_ = [results[1][0][e]][0] if spotify_id != df['SPOTIFY_ARTIST_ID'].iloc[index_]: # exclude comparison with itself _dict_knn = {'index': index_, 'score': score, 'name': df['C_ARTIST_NAME'].iloc[index_], 'popularity': df['C_POPULARITY'].iloc[index_], 'spotify_id': df['SPOTIFY_ARTIST_ID'].iloc[index_], 'spotify_genre': df['C_GENRES'].iloc[index_], 'spotify_description': df['C_DESCRIPTION'].iloc[index_], 'streaming_countries': df['C_FAN_COUNTRY_CODE'].iloc[index_], } _x_knn = pd.DataFrame([_dict_knn]) knn_df = pd.concat([knn_df, _x_knn]) return knn_df def get_similarity_orchard(df, similarity_matrix, indices, spotify_id, top_n=10): """ Find most similar artists :param df: Dataframe containing all the data used for calculating similarities. :param similarity_matrix: Matrix containing all artists' similarity scores with other artists. :param indices: Index containing spotify_id's and indexes for better retreival of data from df. :param spotify_id: The spotify id of artist we want to use for similarity. :param top_n: Number of similar artists to return. Default 10. :return: Dataframe containing top_n most similar artists ordered by score descending. """ # Get the index corresponding to artist spotify id index = indices[spotify_id] # find artist related data artist_attribute_genre = df['O_SUBGENRE'].iloc[index] #artist_attribute_name = df['C_ARTIST_NAME'].iloc[index] artist_attribute_country = df['O_COUNTRY_CODE'].iloc[index] print(f"artist index: {index}.\nartist country: {artist_attribute_country}.\ngenres: {artist_attribute_genre[0:75]}") # first 75 characters # Get the cosine similarity scores similarity_scores = list(enumerate(similarity_matrix[index])) # Sort the similarity scores in descending order sorted_similarity_scores = sorted(similarity_scores, key=lambda x: x[1], reverse=True) # Top-n most similar spotify artists top_10_artist_scores = sorted_similarity_scores[1:top_n+1] # Build recommendations dataframe recommendation_df = pd.DataFrame() top_10_artist_indices=[] for i in top_10_artist_scores: # don't include 0 rating or comparison with itself if i[1] > 0.0 and index != i[0]: _dict = {'index': i[0], 'score': i[1], # 'name': df['C_ARTIST_NAME'].iloc[i[0]], # 'popularity': df['C_POPULARITY'].iloc[i[0]], 'spotify_id': df['SPOTIFY_ARTIST_ID'].iloc[i[0]], 'spotify_genre': df['O_SUBGENRE'].iloc[i[0]], # 'spotify_description': df['C_DESCRIPTION'].iloc[i[0]], } _x = pd.DataFrame([_dict]) recommendation_df = pd.concat([recommendation_df, _x]) top_10_artist_indices.append(i[0]) #recommendation_df = recommendation_df.sort_values(by=['score', 'popularity'], ascending=[False,False]) return recommendation_df