How to make a playlist for someone

Hands-on Tutorials

Create a Spotify Playlist for Yourself and Your Partner or Friend

Using the spotify library to create a version of Spotifys Duo Mix

Merlin Schäfer

Feb 10·7 min read

Photo by Heidi Fin on Unsplash

Spotify offers a Duo Subscription which comes with a unique playlist called Duo Mix. This playlist is supposed to be for both users and combine their music tastes.

My girlfriend and I were eager to see what this playlist was all about. We started listening to it, but it somehow felt a little off. The artists were correct but the songs were not, the playlist hardly featured the songs we both actually listened to. It also jumped between styles pretty hard, going from a chilled jazzy song into techno, rap, or metalcore [okay, that might be a little on me as well]. We were not satisfied and didnt really listen to the weekly updates within the playlist anymore. However, I liked the idea and thought that there must be a way to create the playlist we both wished for.

So I decided to create a playlist myself, but not manually as I wanted weekly updates. I first thought to use machine learning and other more elaborate methods, but then I reminded myself that I had a problem that required a working solution. The objective was not to try out new machine learning algorithms if the problem didnt require it.

My goal was to:

  • include some of our all-time favorites as well as songs we both enjoyed recently
  • include new songs based on these favorites
  • limit the number of songs by one artist
  • create an overall listening experience based on mutually liked music, not just providing a wild mixture of individual tastes

I ended up with a solution that works and does not use machine learning yet, it really is just a bit of data-wrangling, some refinement of Spotifys recommendations through similarity metrics, and a sprinkle of randomness. But it works, we are happy with the playlist so far and will continue to improve it, maybe through machine learning. If there is data on songs we liked and didnt like, a well-trained model could improve everything.

Preparing the playlist creation

Getting the data

I started off by using the Spotify App I had created already and by authenticating our accounts with the app. If you are unsure how to do these things, check out my previous article which walks you through this process.

I started by querying the following data for both of us:

  • top artists long, medium, and short term
  • top tracks long, medium, and short term
  • and some saved user tracks [the last 50]

I used the following function, which really just combines a bunch of queries and produces three DataFrames.

Please note that I am calling functions here that I wrote to convert the Spotify API query results to a usable DataFrame. I wont go through the details of all of them here. Some are in my other article about Spotify [see above]. And you can find the full code on Github [see the spotifuncs.py to view all functions].

The first important piece of data is all the top tracks of the user, which I combined into a complete list of top tracks that cover everything from short to long term favorites. Notice that I am sampling only 15 songs from the long term top tracks and doing so without setting a random seed to not get the same results every time the code is run. Always using the full list of long term favorites in the process would lead to too much repetition over the course of multiple weeks and thus playlists.

The second important piece is the top artists data, which like the tracks are retrieved for all time frames. The artists are important for the filtering process later on.

Lastly, I am also retrieving the latest 50 tracks a user saved. 50 is the upper limit here, which is unfortunate as this really limits the use of the data.

Last weeks playlist

To avoid encountering the same songs two weeks in a row, which is very likely as short and medium-term top tracks wont have changed much, last week's playlist is read from Playlist.csv. This file was just an empty .csv file the first time I ran the code. But at the end of the playlist creation process, the newly created playlist is saved in that .csv file, so it contains last week's playlist. I used the data in that .csv file to filter songs for the new playlist in various stages of the process.

Building the Playlist

The playlist creation requires a couple of steps to assemble all building blocks that make it up. These are:

  1. Common top tracks, that were not in last weeks playlists
  2. A sample of each users top tracks that are most similar to the other user's top tracks
  3. A sample of each users top tracks from an artist both users like [one of their top artists]
  4. A sample of the songs saved by users
  5. A recommended track [through the Spotify API and additional filtering] for every track that was added to the playlist in step 1.-4.

Common top tracks

The playlist is initiated by common top tracks, that did not appear in last week's playlist already. As these songs are both users favorites they should theoretically enjoy them.

I created a DataFrame to find common top tracks by finding tracks that occur in both users top tracks DataFrame. This could be done in multiple ways, I used the following function for all DataFrame comparisons:

Common top tracks are only added to the playlist if they did not appear in last week's playlist.

Users top tracks that are similar to each other

The next building block consists of songs from both users top tracks that are most similar to one another on the level of audio features.

For this task, the top tracks unique to each user are extracted and a similarity matrix is computed. The similarity is based on the audio features [excluding key and mode] and computed via cosine similarity [see create_similarity_score[] in spotifuncs.py]. From this matrix, the 30 highest similarity scores and corresponding indices are extracted. The songs corresponding to these indices are put into a DataFrame, any duplicates are dropped and a sample of 10 songs is drawn for the new playlist.

Common top artists

The next step filters the top tracks based on common artists. I tried to find common artists [among the 2 users] to later filter their top songs by these artists. The logic behind this is the following:
A track might be only among one user's top tracks, it may, however, be by an artist both users enjoy. In that case, the track is a good candidate for the Duos Playlist as both users will probably enjoy it, yet it might be a new discovery for one of them. If both already know and like it: still a good fit for the playlist!

Potential issues

This filtering approach for me often leads to lists of songs that only contain very few artists but a couple of songs by that artist [its also due to Spotify really noticing when you cant stop listening to an album..]. In order to not have too many songs by the same artist in the new playlist, I sampled from the DataFrames. For that, I assigned weights to the rows depending on how often an artist occurs and then sampled from both DataFrames.
This approach worked reasonably well, however, still has some flaws [which might be partially driven by my listening behavior].

Sampling from saved tracks

When creating the playlist I aimed for around 25 known tracks [and 25 new ones through recommendations]. To achieve this and to somehow account for the somewhat random nature of the previous steps I am filling the playlist with sampled saved tracks in the last step. For this step, I also make sure that none of the sampled songs occurred in last week's playlist already.

Adding new tracks from Spotify recommendations

In this last step, I add new tracks to fill up the other half of the playlist.

I dont want to simply add songs Spotify recommends based on the songs, which are already in the playlist. Therefore getting Spotify recommendations is only the first step. I am retrieving multiple songs recommendations per song, which are then filtered again based on similarity scoring.

Unfortunately, the Spotify API does not accept 25 seed tracks for a recommendation query, I, therefore, ended up splitting the process into packages of 5 seed tracks, retrieving 25 tracks per package. The 125 recommendations are further filtered by their similarity to the known tracks in the playlist.

The playlist is finished!

Now the only thing left to do is to add the tracks to the playlist [Adding a nice picture and thanking your partner for her/his patience in the playlist description are not optional].

I hope you take this as an inspiration to build a playlist for you and others. I also hope you get creative and find other solutions to this problem. Let me know what you build!

P.S. I intentionally skipped over some code to keep the article at a reasonable length, if you want to see it, its all on Github.

-Merlin

Video liên quan

Chủ Đề