Clustering Music to Create your Playlists on Spotify Using Python and R. | by Cristóbal Veas | Towards Data Science

Spotify is one of the most famous Music Platforms to discover new music. The company uses a lot of different algorithms to recommend the user new music based on their music preferences and most of these recommendations are located in Playlists. These Playlists are created for different users based on a wide diversity of music genres and even Spotify is capable to recommend new music based in moods.
Music has been in my daily routine during all my life, It’s a kind of drug that I need when I’m doing housework, working at the office, walking the dog, workouts and so on. I have a lot of music on Spotify that I always wanted to separate according to the similarities of the songs and save them into different playlists. Fortunately, with a little knowledge of Machine Learning Algorithms and Python, I could achieve that goal !!!.
So to do that, first I will list the tools required and some definitions of the Spotify Audio Features that I will use for built the Clustering model.
Pandas and Numpy for data analysis.
Sklearn to build the Machine Learning model.
Spotipy Python Library (click here for more info).
Spotify Credentials to access Api Database and Playlists Modify (click here for more info).
Spotify uses a series of different features to classify the tracks. I copy/paste the information from the Spotify Webpage.
Acousticness: A confidence measure from 0.0 to 1.0 of whether the track is acoustic. 1.0 represents high confidence the track is acoustic.
Danceability: Danceability describes how suitable a track is for dancing based on a combination of musical elements including tempo, rhythm stability, beat strength, and overall regularity. A value of 0.0 is least danceable and 1.0 is most danceable.
Energy: Energy is a measure from 0.0 to 1.0 and represents a perceptual measure of intensity and activity. Typically, energetic tracks feel fast, loud, and noisy. For example, death metal has high energy, while a Bach prelude scores low on the scale. Perceptual features contributing to this attribute include dynamic range, perceived loudness, timbre, onset rate, and general entropy.
Instrumentalness: Predicts whether a track contains no vocals. “Ooh” and “aah” sounds are treated as instrumental in this context. Rap or spoken word tracks are clearly “vocal”. The closer the instrumentalness value is to 1.0, the greater likelihood the track contains no vocal content. Values above 0.5 are intended to represent instrumental tracks, but confidence is higher as the value approaches 1.0.
Liveness: Detects the presence of an audience in the recording. Higher liveness values represent an increased probability that the track was performed live. A value above 0.8 provides a strong likelihood that the track is live.
Loudness: the overall loudness of a track in decibels (dB). Loudness values are averaged across the entire track and are useful for comparing the relative loudness of tracks. Loudness is the quality of a sound that is the primary psychological correlate of physical strength (amplitude). Values typically range between -60 and 0 db.
Speechiness: Speechiness detects the presence of spoken words in a track. The more exclusively speech-like the recording (e.g. talk show, audiobook, poetry), the closer to 1.0 the attribute value. Values above 0.66 describe tracks that are probably made entirely of spoken words. Values between 0.33 and 0.66 describe tracks that may contain both music and speech, either in sections or layered, including such cases as rap music. Values below 0.33 most likely represent music and other non-speech-like tracks.
Valence: A measure from 0.0 to 1.0 describing the musical positiveness conveyed by a track. Tracks with high valence sound more positive (e.g. happy, cheerful, euphoric), while tracks with low valence sound more negative (e.g. sad, depressed, angry).
Tempo: The overall estimated tempo of a track in beats per minute (BPM). In musical terminology, the tempo is the speed or pace of a given piece and derives directly from the average beat duration.
For information reduction purposes I decided to use the features of Loudness, Valence, Energy, and Danceability because they have more influence to differentiate between Energetic and Relaxed songs.
My favorite band is Radiohead, so I decided to obtain their discography and all the music created by the musicians in their solo music careers.
Using the Spotipy Library I created some functions to download all the songs of Radiohead, Thom Yorke, Atoms For Peace, Jonny Greenwood, Ed O’Brien, Colin Greenwood, and Phil Selway (Yes, I’m obsessed with their music hehe). You can access those functions on my Github Repository (click here).
I obtained the following data:
I always wondered why I like a lot the music of Radiohead and I realized that most of their songs tend towards melancholy. Describing the features above, the data showed me that Valence and Energy are less than 0.5 and Danceability tends to low values, so I like tracks with low energy and negative sound (there is still something of my 2000’s Emo Side watching MTV Videos).
I decided to use K-means Clustering for Unsupervised Machine Learning due to the shape of my data (423 tracks ) and considering I want to create 2 playlists separating Relaxed tracks from Energetic tracks (K=2).
Important: I’m not using train and test data because in this case I just want to group all the tracks into 2 different groups to create playlists with the entire data.
So let’s do it!. I first import the libraries:
from sklearn.cluster import KMeansfrom sklearn.preprocessing import MinMaxScaler
Then I need to define features and normalize the values of the model. I’ will use MinMaxScaler to preserve the shape of the original distribution and scale the features between a range from 0 to 1. Once I have the values in the correct format, I just simply create the K-Means model and then save the labels into the main Data Frame called “df”.
col_features = ['danceability', 'energy', 'valence', 'loudness']X = MinMaxScaler().fit_transform(df[col_features])kmeans = KMeans(init="kmeans++",                n_clusters=2,                random_state=15).fit(X)df['kmeans'] = kmeans.labels_
That’s All, I have the music clustered in 2 groups !!!
But now I need to study the features of these labels, so I plot the tracks in a 3D Scatter and then I analyze the respective mean of each feature grouping the data frame by the K-Means result labels.
As I noticed on the graph the values are quite well grouped, blue values are located in label 0 and red values in label 1. Looking at the table of means, the label 0 grouped tracks with less danceability, energy, valence, loudness, so this one corresponds to Relaxed songs, likewise, the label 1 has the Energetic songs.
I know that Clustering accuracy is a bit subjective trying to evaluate the best result of a Clustering Algorithm, but in the same way, I wanted to observe if my model is separating the tracks well. So with a little help from Rstudio, I used the Silhouette Analysis. to measure the accuracy of my model.
In Rstudio I used the library “cluster” and “factoextra” to visualize and calculate the Silhouette Analysis using the Euclidean distance. the complete code is on my Github Repository (click here):
#Calculate The euclidean distance of my dataframe values.dd <- dist(df,method="euclidean")#Silhouette Analysis using the K-means model(km) and distance(dd)sil.km <- silhouette(km$cluster,dd)fviz_silhouette(sil.km)
The result is:
The Silhouette Analysis is a way to measure how close each point in a cluster is to the points in its neighboring clusters. Silhouette values lies in the range of [-1, 1]. A value of +1 indicates that the sample is far away from its neighboring cluster and very close to the cluster its assigned. Similarly, a value of -1 indicates that the point is close to its neighboring cluster than to the cluster its assigned. So in my case values are between 0.25 and 0.60 inferring that most of the values are quite well grouped.
To create the playlists and add the clustered tracks I use the library Spotipy explained in the first part of this article. You just need to get a client id, client secret, and username code to use the Spotify’s Apis and manipulate your library music. I let you the link with the information (Click Here).
I had to separate the tracks grouped into 2 different variables and then having the ids of the tracks I just create 2 new playlists and pass them the ids of the tracks. The code is the following one:
#Separating the clusters into new variablescluster_0 = df[df['kmeans']==0]cluster_1  = df[df['kmeans']==1]#Obtaining the ids of the songs and conver the id dataframe column to a list.ids_0 = cluster_0['id'].tolist()ids_1 = cluster_1['id'].tolist()#Creating 2 new playlists on my Spotify Userpl_energy = sp.user_playlist_create(username=username,                                           name="Radiohead :)")pl_relaxed = sp.user_playlist_create(user=username,                                            name="Radiohead :(")#Adding the tracks into the playlists#For energetic Playlistsp.user_playlist_add_tracks(user=username,                            playlist_id = pl_energy['id'],                            tracks=ids_1)#For relaxed Playlistsp.user_playlist_add_tracks(user=username,                            playlist_id = pl_relaxed['id'],                            tracks=ids_0)
Finally, I have my 2 playlists of Radiohead’s songs using a K-means Clustering Algorithm to separate Energetic Songs from Relaxed Songs !!!!.
If you want to listen to both playlists you can access them below.
Machine Learning Algorithms are a lot of fun to implement ideas or projects related to things you like. In my case, I like music a lot, so I could use this knowledge to create cool ways helping me to automate a task that can take a long time to perform it. I also could learn more about this amazing world of Data Science and my tendencies to music tastes.
Una Forma Genial para Buscar y Analizar Arriendos de Departamentos en la Web
Predicting the Music Mood of a Song with Deep Learning
Una Forma Interactiva para Buscar y Analizar Ofertas de Trabajo en la Web.
Automating Playlists on Spotify From the Music Folders of your Computer