All projects
โ— Complete

Music Recommender

Where I learned that the shape of the input decides which model you can use.

Sole developer ยท Jul 2023 (Inspirit AI)

This was the first project where I picked the model instead of being handed one. The part that stuck was the jump from treating a song as a flat feature vector to treating its timbre as a 120-step sequence, because that reframing is the only reason an LSTM was worth trying at all. Everything before it is standard scikit-learn, and I would not pretend otherwise.

4
Notebook sections, from logistic regression to an LSTM

What the notebooks do

The first notebook predicts whether a track is a hit from Spotify audio features (danceability, energy, speechiness, acousticness, instrumentalness, liveness, valence, tempo) using logistic regression, then reads the coefficients to see which features carried the decision. The second builds a song vector out of text fields (artist, genre, lyrics) run through CountVectorizer, concatenated with normalized numeric features, and ranks the K nearest songs by cosine similarity. The third switches to 12-dimensional timbre timecourses pulled from Spotify's audio analysis, flattens them, and trains KNN, SVM, naive Bayes, logistic regression and an MLP on the same input to compare them. The fourth stops flattening. It reshapes the timbre data as 120 timesteps by 12 components and trains an LSTM with dense layers on top, plus PCA for spectrogram dimensionality reduction and librosa for audio visualization.

How the demo differs from the notebooks

The demo here does not run a trained model. It scores about thirty hand-entered songs with a weighted sum over genre match, tempo distance, energy, valence and danceability, and shows the per-feature breakdown behind each score. I built it that way on purpose. Shipping a real model to the browser would mean either a Python backend or a conversion pipeline, and neither is worth it for a project this old. What the demo is good for is making the idea legible: pick a target, score every candidate against it, sort, take the top K. That loop is the same one the content-based notebook runs, just with cosine similarity over real vectors instead of five weights I chose by hand.

Built with

Pythonscikit-learnTensorFlowKeraslibrosaPandasNumPyJupyter