Spotify Artist Recommender | by Michael Whittle | Towards Data Science

Recommender systems within applications and services are no longer a “nice to have”. Users are now becoming accustomed to having this functionality as standard. Audio streaming, video streaming, advertising, search engines, blogs, etc. just to name a few.
When it comes to recommender systems there are a few common techniques. My favourite technique is “cosine similarity”. It’s easy to understand and very fast. Even without a data science background, the concept shouldn’t be too difficult to grasp.
The basic concept is as follows.
Plot a numeric representation of the items you wish to compare (A and B above) and then calculate the cosine distance between the points. The theory behind it is the smaller the distance, the more similar they are.
Create a recommender system to find similar artists on Spotify.
I downloaded the dataset, “Spotify Dataset 1922–2021, ~600k Tracks” on Kaggle. The file I will be working with is called “data_by_artist_o.csv”.
import pandas as pdimport numpy as npfrom sklearn.metrics.pairwise import cosine_similarityfrom sklearn.preprocessing import StandardScalerdf_artists = pd.read_csv('./data_by_artist_o.csv', encoding='utf-8')df_artists.shape
This dataset has 28680 songs with 11 features/columns.
The data is actually in a pretty good state already and there aren’t any null values.
df_artists.isnull().sum()
df_artists.info()
df_artists.describe()
There are a few features that are non-numeric or don’t really add much value so we will remove those.
df_artists.drop(columns={'genres', 'key', 'mode', 'count'}, inplace=True)df_artists.head()
The issue we have now is that all those descriptive features are all in different scales. We need to scale the data so they are all comparable.
ss = StandardScaler()df_artists_scaled = ss.fit_transform(df_artists)df_artists_scaled = pd.DataFrame(data=df_artists_scaled, index=df_artists.index, columns=df_artists.columns)df_artists_scaled.head()
As you can see now the features are all within the range of -1 to 1.
Let’s see how this works with “Ed Sheeran” as the artist.
artist_array = np.array(df_artists_scaled.T['Ed Sheeran']).reshape(1,-1)artist_dataset_array = df_artists_scaled.drop(index='Ed Sheeran').valuescosine_similarity(artist_array, artist_dataset_array)
df_Ed_Sheeran = df_artists.drop(index='Ed Sheeran').copy()df_Ed_Sheeran['cosim_score'] = cosine_similarity(artist_array, artist_dataset_array).reshape(-1,1)df_Ed_Sheeran
Take a look at the newly created “cosim_score” at the end. That shows us show similar the artist is with the other artists using “cosine similarity”.
We now have the building blocks to create ourselves a handy function.
def get_cosim_artist_df(artist_name, df, n):    ss = StandardScaler()    df_scaled = ss.fit_transform(df)    df = pd.DataFrame(data=df_scaled, index=df.index)        artist_array = np.array(df.T[artist_name]).reshape(1,-1)    dataset_array = df.drop(index=artist_name).values        cosim_scores = cosine_similarity(artist_array, dataset_array).flatten()artist_names_array = df.drop(index=artist_name).index.values        df_result = pd.DataFrame(        data = {            'artist'               : artist_names_array,            'cosim_' + artist_name : cosim_scores,        }    )        df_result = df_result.sort_values(by='cosim_' + artist_name, ascending=False).head(n)        return df_result.reset_index(drop=True)
And let’s see it in action...
get_cosim_artist_df('Ed Sheeran', df_artists, 20)
According to our newly created function, the top 20 artists that are similar to “Ed Sheeran”...
I have to admit I don’t recognise most of those artists in the list. I opened up Spotify and listened to the top 3 which are over 93% cosine similar and I think it did a pretty good job. It would be interesting to know what you think in the comments.
This technique is not limited to audio and video streaming, which is probably the first use case that comes to mind. As long as you can structure your data into a pivot table this will work. I’ll give you one more example as food for thought. Let’s say you have a web site and you want to recommend either pages or documents to your users. You could create a pivot table with the page name or document title as the index (rows) and you could maybe create a list of “tags” as the columns. If the tag describes the page or document you would either mark it as a 0 or 1, or maybe even a weight if some tags are more important than others. Then you run it through exactly the same process as above as it will work like charm.
If you liked this article I’ve written some other articles I think you may find interesting. I’m working through explaining various machine learning concepts by example.
levelup.gitconnected.com
levelup.gitconnected.com
levelup.gitconnected.com
If you enjoyed this, please follow me on Medium
Interested in collaborating? Let’s connect on LinkedIn