Creating a Review-Based Album Recommendation System
Leveraging textual features to provide content-based recommendation via NLP and machine learning.
Introduction
When looking for an album to listen to, we all recognize that emotional content is important for our choice. However, when we’re looking for albums, we can really only search for titles, artists, and genres, which doesn’t totally capture what I mean by emotional content. Instead, we have to read through album reviews if we want to understand what feelings that album may evoke.
I thought that there must be a way to connect these two methods of finding new music, and I wanted to apply some machine learning tools to this interesting dilemma. I realized that it would be relatively easy to get album reviews vectorized, and I wanted to see what tools I could create to allow users to get a faster look at the emotional content of an album than reading an album review would allow.
Getting the data
As in any data science project, getting and cleaning the data was the most time-intensive step. I used BeautifulSoup and the requests
library to scrape the first 10 pages of Pitchfork album reviews, totaling a few hundred albums for this proof-of-concept.
After getting the raw text of the album reviews, I wanted to perform some form of dimension reduction. I knew that I wanted to describe the emotional content of the albums, so I decided to use TextBlob’s handy parts-of-speech tagging abilities to only keep the adjectives from the album review text. By doing this, I was able to dramatically reduce the number of features that my model would later use, speeding up and simplifying my process.
Embedding
Once I had all of the adjectives and albums arranged in a Pandas DataFrame, I applied scikit-learn’s CountVectorizer to the data in order to perform embedding. Embedding is the process of turning textual features into something that is machine readable. CountVectorizer is a very simple method of doing this, where each word becomes its own column and each document has either a zero or a one depending on if the word is found within that document.
Recommendation
There are two general kinds of recommendation: collaborative filtering and content-based filtering. Collaborative filtering leverages user data to make recommendations (“You’re similar to Amy, and she liked X so we think you might like X.”). In this sort of system, the features for analysis come from the users, and not the content.
In content-based filtering, the opposite is true. We don’t have to know much about the users, other than the products that they liked in the past. Then, we use features derived from characteristics of the products to recommend new products.
Because this is a relatively small-scale project, I decided to stick with a simplistic, content-based method for recommendation. In the future, I would love to create a user-profile system where the user enters a few albums they like, and I deliver similarly-reviewed albums to them, but that’s a mission for another day. For this tool, I just decided to ask the user directly what they’re looking for in an album. With this information, I could use the CountVectorized album reviews to provide album recommendations.
This gave me a good starting point for my recommendation engine, but it only included exact matches. By incorporating the synonym list in PyDict, I was able to expand the range of adjectives that were searched when a user entered a specific term. For example, when a user searched for “energetic,” my tool would now search for albums described as “energetic,” “fast,” “upbeat,” and so on. This worked well, and decreased the number of times a user’s search would end in zero results.
Final tool
I decided to use Streamlit to create a polished tool that a theoretical user could search albums with.
For example, if we want to see albums that Pitchfork has described as “lyrical,” we can simply enter that term. We see that Pitchfork has described 24 albums as either “lyrical” or using a synonym of that term. The top five results are ranked by their album review score, with Bombay by A.R. Rahman topping the charts at a 9.0 rating. But we can get more specific than a single search term.
If we add another adjective, like “unrestrained,” we can see that the results have narrowed from 24 albums to only 6. The top scoring album that was described with both of these adjectives (or their synonyms) is Cavalcade by black midi. Of course, we can keep going!
If we want an album that was described by Pitchfork as “lyrical,” “unrestrained,” and even “modular,” we see that we ought to check out Butterfly 3000 by King Gizzard and the Lizard Wizard.
Take a listen for yourself, and see if you agree with Pitchfork’s opinion. And while you’re listening to that lyrical, unrestrained, and modular jam, why don’t you take a look at the GitHub repository for this project, and try the tool out for yourself!