Spotify Together

April 2022

This project initially started off as a school project for my machine learning class in college. The professor told us we could do anything we wanted as long as it involved machine learning, so I teamed up with a classmate to create an application that would learn a Spotify users' music taste and be able to make recommendations based on that. The end goal being to create a playlist for multiple people that they equally enjoy. Spotify has an experimental feature that can do this for two people already, but it feels more like every other song is for one person and the rest are for the other instead of trying to find a common ground. So I figured we could try and do it better ourselves.

Spotify has and API that allows you (with a users' permission) to get information about what kind of songs said user listens to. They break down each song with several data points like how acoustic it is from 0 to 1, how "fun" it sounds from 0 to 1, and so on. I assumed you could use this information to train a machine learning algorithm a user's music taste, and after looking at some data it was clear that there are distinct patterns between users.

Here is an example of my music taste, visualized with a pairwise scatter plot:

And here is my classmates music taste:

Unfortunately I didn't regulate the plot sizes so graphs are hard to compare but once I knew there were distinct differences we could begin working on a machine learning algorithm that could categorize music taste.

There were a lot of different way to approach this, but there was a significant issue. Most machine learning algorithms, at least the ones we knew about, need negative training samples in order to learn. Since we only had positive data (songs a user listens to often) that meant most machine learning algorithms wouldn't work out of the box.

Our initial idea was to generate fake negative data that was far enough away from the positive data that it doesn't screw up the classifier. This worked somewhat decently but added a lot of computational complexity and created a lot of false negatives. As the project deadline was approaching we stuck with this idea and completed a basic version of the application.

After the semester ended I decided to return to this project, hoping to improve it and flesh out the features. I had another look at the classifier we used and tried to think of a different solution. After a while I came up with the idea of using a clustering algorithm to try to define a general area which could be labeled as positive. So the way it works is by running k-means on the set of songs that a user likes and trying to find cluster points, and if a new song is close enough to the cluster point it labels it as positive. After some testing with the number of cluster points and dynamically setting the distance songs can be away from each cluster point I ended up with an algorithm I felt was pretty robust. The testing involved running the classifier on myself and generating random songs and listening to them and deciding if I like them or not and comparing that to what the classifier thinks, giving a score based off of how many true positives and true negatives there were against how many false negative and false positives there were.

This is what one of the tests looked like:

Once that was finished all I had to do was update the Django application we made for our project with the new algorithm and put it on my AWS server and have my friends test it. The UI is very simple and I hope to update it soon to something that's easier on the eyes.

Here is an example of how the program works:

Ideas for future features are being able to set seed recommendations, deciding playlist length, selecting multiple users, etc.