{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Playlist Classifier\n", "\n", "Given a list of playlists, can unknown tracks be correctly classified?" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "playlist_names = [\"RAP\", \"EDM\", \"ROCK\", \"METAL\", \"JAZZ\", \"POP\"] # super-genres\n", "playlist_names = [\"ALL RAP\", \"EDM\", \"ROCK\", \"METAL\", \"JAZZ\", \"POP\"] # super-genres\n", "# playlist_names = [\"RAP\", \"EDM\", \"ROCK\", \"METAL\", \"JAZZ\"] # super-genres without POP\n", "# playlist_names = [\"DNB\", \"HOUSE\", \"TECHNO\", \"GARAGE\", \"DUBSTEP\", \"BASS\"] # EDM playlists\n", "# playlist_names = [\"20s rap\", \"10s rap\", \"00s rap\", \"90s rap\", \"80s rap\"] # rap decades\n", "# playlist_names = [\"UK RAP\", \"US RAP\"] # UK/US split\n", "# playlist_names = [\"uk rap\", \"grime\", \"drill\", \"afro bash\"] # british rap playlists\n", "# playlist_names = [\"20s rap\", \"10s rap\", \"00s rap\", \"90s rap\", \"80s rap\", \"trap\", \"gangsta rap\", \"industrial rap\", \"weird rap\", \"jazz rap\", \"boom bap\", \"trap metal\"] # american rap playlists\n", "# playlist_names = [\"rock\", \"indie\", \"punk\", \"pop rock\", \"bluesy rock\", \"hard rock\", \"chilled rock\", \"emo\", \"pop punk\", \"stoner rock/metal\", \"post-hardcore\", \"melodic hardcore\", \"art rock\", \"post-rock\", \"classic pop punk\", \"90s rock & grunge\", \"90s indie & britpop\", \"psych\"] # rock playlists\n", "# playlist_names = [\"metal\", \"metalcore\", \"mathcore\", \"hardcore\", \"black metal\", \"death metal\", \"doom metal\", \"sludge metal\", \"classic metal\", \"industrial\", \"nu metal\", \"calm metal\", \"thrash metal\"] # metal playlists\n", "\n", "# headers = float_headers + [\"duration_ms\", \"mode\", \"loudness\", \"tempo\"]\n", "headers = float_headers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pull and process playlist information.\n", "\n", "1. Get live playlist track information from spotify\n", "2. Filter listening history for these tracks\n", "\n", "Filter out tracks without features and drop duplicates before taking only the descriptor parameters" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "playlists = [get_playlist(i, spotnet) for i in playlist_names] # 1)\n", "\n", "# filter playlists by join with playlist track/artist names\n", "filtered_playlists = [pd.merge(track_frame(i.tracks), scrobbles, on=['track', 'artist']) for i in playlists] # 2)\n", "\n", "filtered_playlists = [i[pd.notnull(i[\"uri\"])] for i in filtered_playlists]\n", "# distinct on uri\n", "filtered_playlists = [i.drop_duplicates(['uri']) for i in filtered_playlists]\n", "# select only descriptor float columns\n", "filtered_playlists = [i.loc[:, headers] for i in filtered_playlists]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Construct the dataset with associated labels before splitting into a train and test set." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "dataset = pd.concat(filtered_playlists)\n", "labels = [np.full(len(plst), idx) for idx, plst in enumerate(filtered_playlists)]\n", "labels = np.concatenate(labels)\n", "\n", "# stratify: maintains class proportions in test and train set\n", "data_train, data_test, labels_train, labels_test = train_test_split(dataset, labels, test_size=0.25, random_state=70, stratify=labels)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# SVM\n", "Support Vector Machine" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " | uw-rbf | \n", "w-rbf | \n", "linear | \n", "poly | \n", "sigmoid | \n", "
---|---|---|---|---|---|
accuracy % | \n", "75.03 | \n", "71.0 | \n", "68.98 | \n", "71.37 | \n", "34.3 | \n", "