Created
June 19, 2021 10:28
-
-
Save Auax/a80e19cf3e57c0bbf4177ac3b8fd4502 to your computer and use it in GitHub Desktop.
Predict a Spotify song genre
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "import pandas as pd\n", | |
| "import numpy as np" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Requesting Access Token from Spotify Web API**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/plain": [ | |
| "'{\"access_token\":\"BQCREIj2YaT4AUwMJWDs9-kwTY_EFHqXpghZp4TX-Tamglzl-ICc72mnQ0kKi-ZL5K_Ms3Gn-d9lWwP8DXU\",\"token_type\":\"Bearer\",\"expires_in\":3600,\"scope\":\"\"}'" | |
| ] | |
| }, | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "import requests\n", | |
| "import json\n", | |
| "client_id = your_client_id\n", | |
| "client_secret = your_client_secret\n", | |
| "\n", | |
| "grant_type = 'client_credentials'\n", | |
| "\n", | |
| "#Request body parameter: grant_type Value: Required. Set it to client_credentials\n", | |
| "body_params = {'grant_type' : grant_type}\n", | |
| "\n", | |
| "url='https://accounts.spotify.com/api/token'\n", | |
| "\n", | |
| "response=requests.post(url, data=body_params, auth = (client_id, client_secret)) \n", | |
| "response.text" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "import ast \n", | |
| "response_dict = ast.literal_eval(response.text)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 220, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "access_token = response_dict['access_token']\n", | |
| "headers = {'Authorization': 'Bearer '+ access_token}" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Get Playlist Tracks IDs**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "def get_id(songs):\n", | |
| " out = []\n", | |
| " for song in songs['items']:\n", | |
| " out.append(song['track']['id'])\n", | |
| " return out" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Getting Hip-Hop Playlist Track IDs**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "r = requests.get(\"https://api.spotify.com/v1/playlists/37i9dQZF1DX2RxBh64BHjQ/tracks\", headers=headers)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 30, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "hip_hop_songs = r.json()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "hip_hop_ids = get_id(hip_hop_songs)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Getting Classical Playlist Track IDs**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "r = requests.get(\"https://api.spotify.com/v1/playlists/37i9dQZF1DWWEJlAGA9gs0/tracks\", headers=headers)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "classical_songs = r.json()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "classical_ids = get_id(classical_songs)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Getting Techno Playlist Track IDs**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "r = requests.get(\"https://api.spotify.com/v1/playlists/37i9dQZF1DX6J5NfMJS675/tracks\", headers=headers)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 52, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "techno_songs = r.json()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "techno_ids = get_id(techno_songs)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Requesting Track Features and inserting into Pandas DataFrame**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "***Hip-Hop***" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "hip_hop_ids_test = \",\".join(hip_hop_ids)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "r = requests.get(f\"https://api.spotify.com/v1/audio-features/?ids={hip_hop_ids_test}\", headers=headers)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 100, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "hip_hop_features = r.json()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "# Delete None values (avoid errors with the DataFrame)\n", | |
| "def remove_none(features):\n", | |
| " for element in features['audio_features']:\n", | |
| " if element == None:\n", | |
| " index_pos = features['audio_features'].index(element)\n", | |
| " features['audio_features'].pop(index_pos)\n", | |
| " return features" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "# Remove None values from the list\n", | |
| "hip_hop_features = remove_none(hip_hop_features)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 104, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "# Create a DataFrame\n", | |
| "df_hip_hop = pd.DataFrame(hip_hop_features['audio_features'])" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 105, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "# Create a new column\n", | |
| "df_hip_hop['target'] = 'Hip-Hop'" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>danceability</th>\n", | |
| " <th>energy</th>\n", | |
| " <th>key</th>\n", | |
| " <th>loudness</th>\n", | |
| " <th>mode</th>\n", | |
| " <th>speechiness</th>\n", | |
| " <th>acousticness</th>\n", | |
| " <th>instrumentalness</th>\n", | |
| " <th>liveness</th>\n", | |
| " <th>valence</th>\n", | |
| " <th>tempo</th>\n", | |
| " <th>type</th>\n", | |
| " <th>id</th>\n", | |
| " <th>uri</th>\n", | |
| " <th>track_href</th>\n", | |
| " <th>analysis_url</th>\n", | |
| " <th>duration_ms</th>\n", | |
| " <th>time_signature</th>\n", | |
| " <th>target</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>0.794</td>\n", | |
| " <td>0.756</td>\n", | |
| " <td>5</td>\n", | |
| " <td>-7.160</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.136</td>\n", | |
| " <td>0.11000</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>0.247</td>\n", | |
| " <td>0.775</td>\n", | |
| " <td>123.066</td>\n", | |
| " <td>audio_features</td>\n", | |
| " <td>4DuUwzP4ALMqpquHU0ltAB</td>\n", | |
| " <td>spotify:track:4DuUwzP4ALMqpquHU0ltAB</td>\n", | |
| " <td>https://api.spotify.com/v1/tracks/4DuUwzP4ALMq...</td>\n", | |
| " <td>https://api.spotify.com/v1/audio-analysis/4DuU...</td>\n", | |
| " <td>156498</td>\n", | |
| " <td>4</td>\n", | |
| " <td>Hip-Hop</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1</th>\n", | |
| " <td>0.836</td>\n", | |
| " <td>0.611</td>\n", | |
| " <td>4</td>\n", | |
| " <td>-6.737</td>\n", | |
| " <td>1</td>\n", | |
| " <td>0.247</td>\n", | |
| " <td>0.00406</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>0.101</td>\n", | |
| " <td>0.787</td>\n", | |
| " <td>160.000</td>\n", | |
| " <td>audio_features</td>\n", | |
| " <td>2No8W4sLebINx3pdRUeMnl</td>\n", | |
| " <td>spotify:track:2No8W4sLebINx3pdRUeMnl</td>\n", | |
| " <td>https://api.spotify.com/v1/tracks/2No8W4sLebIN...</td>\n", | |
| " <td>https://api.spotify.com/v1/audio-analysis/2No8...</td>\n", | |
| " <td>145125</td>\n", | |
| " <td>4</td>\n", | |
| " <td>Hip-Hop</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " danceability energy key loudness mode speechiness acousticness \\\n", | |
| "0 0.794 0.756 5 -7.160 0 0.136 0.11000 \n", | |
| "1 0.836 0.611 4 -6.737 1 0.247 0.00406 \n", | |
| "\n", | |
| " instrumentalness liveness valence tempo type \\\n", | |
| "0 0.0 0.247 0.775 123.066 audio_features \n", | |
| "1 0.0 0.101 0.787 160.000 audio_features \n", | |
| "\n", | |
| " id uri \\\n", | |
| "0 4DuUwzP4ALMqpquHU0ltAB spotify:track:4DuUwzP4ALMqpquHU0ltAB \n", | |
| "1 2No8W4sLebINx3pdRUeMnl spotify:track:2No8W4sLebINx3pdRUeMnl \n", | |
| "\n", | |
| " track_href \\\n", | |
| "0 https://api.spotify.com/v1/tracks/4DuUwzP4ALMq... \n", | |
| "1 https://api.spotify.com/v1/tracks/2No8W4sLebIN... \n", | |
| "\n", | |
| " analysis_url duration_ms \\\n", | |
| "0 https://api.spotify.com/v1/audio-analysis/4DuU... 156498 \n", | |
| "1 https://api.spotify.com/v1/audio-analysis/2No8... 145125 \n", | |
| "\n", | |
| " time_signature target \n", | |
| "0 4 Hip-Hop \n", | |
| "1 4 Hip-Hop " | |
| ] | |
| }, | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "df_hip_hop.head(2)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "***Classical***" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "classical_ids = \",\".join(classical_ids)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 109, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "r = requests.get(f\"https://api.spotify.com/v1/audio-features/?ids={classical_ids}\", headers=headers)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "classical_features = r.json()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "df_classical = pd.DataFrame(classical_features['audio_features'])" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "df_classical['target'] = \"Classical\"" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>danceability</th>\n", | |
| " <th>energy</th>\n", | |
| " <th>key</th>\n", | |
| " <th>loudness</th>\n", | |
| " <th>mode</th>\n", | |
| " <th>speechiness</th>\n", | |
| " <th>acousticness</th>\n", | |
| " <th>instrumentalness</th>\n", | |
| " <th>liveness</th>\n", | |
| " <th>valence</th>\n", | |
| " <th>tempo</th>\n", | |
| " <th>type</th>\n", | |
| " <th>id</th>\n", | |
| " <th>uri</th>\n", | |
| " <th>track_href</th>\n", | |
| " <th>analysis_url</th>\n", | |
| " <th>duration_ms</th>\n", | |
| " <th>time_signature</th>\n", | |
| " <th>target</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>0.2210</td>\n", | |
| " <td>0.1260</td>\n", | |
| " <td>0</td>\n", | |
| " <td>-25.427</td>\n", | |
| " <td>1</td>\n", | |
| " <td>0.0447</td>\n", | |
| " <td>0.989</td>\n", | |
| " <td>0.897</td>\n", | |
| " <td>0.1020</td>\n", | |
| " <td>0.2160</td>\n", | |
| " <td>133.630</td>\n", | |
| " <td>audio_features</td>\n", | |
| " <td>4SFBV7SRNG2e2kyL1F6kjU</td>\n", | |
| " <td>spotify:track:4SFBV7SRNG2e2kyL1F6kjU</td>\n", | |
| " <td>https://api.spotify.com/v1/tracks/4SFBV7SRNG2e...</td>\n", | |
| " <td>https://api.spotify.com/v1/audio-analysis/4SFB...</td>\n", | |
| " <td>139307</td>\n", | |
| " <td>4</td>\n", | |
| " <td>Classical</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1</th>\n", | |
| " <td>0.0811</td>\n", | |
| " <td>0.0122</td>\n", | |
| " <td>4</td>\n", | |
| " <td>-32.654</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.0511</td>\n", | |
| " <td>0.902</td>\n", | |
| " <td>0.308</td>\n", | |
| " <td>0.0648</td>\n", | |
| " <td>0.0384</td>\n", | |
| " <td>74.554</td>\n", | |
| " <td>audio_features</td>\n", | |
| " <td>2kAgCRZPG3YQR2VMqRvLmb</td>\n", | |
| " <td>spotify:track:2kAgCRZPG3YQR2VMqRvLmb</td>\n", | |
| " <td>https://api.spotify.com/v1/tracks/2kAgCRZPG3YQ...</td>\n", | |
| " <td>https://api.spotify.com/v1/audio-analysis/2kAg...</td>\n", | |
| " <td>935360</td>\n", | |
| " <td>4</td>\n", | |
| " <td>Classical</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " danceability energy key loudness mode speechiness acousticness \\\n", | |
| "0 0.2210 0.1260 0 -25.427 1 0.0447 0.989 \n", | |
| "1 0.0811 0.0122 4 -32.654 0 0.0511 0.902 \n", | |
| "\n", | |
| " instrumentalness liveness valence tempo type \\\n", | |
| "0 0.897 0.1020 0.2160 133.630 audio_features \n", | |
| "1 0.308 0.0648 0.0384 74.554 audio_features \n", | |
| "\n", | |
| " id uri \\\n", | |
| "0 4SFBV7SRNG2e2kyL1F6kjU spotify:track:4SFBV7SRNG2e2kyL1F6kjU \n", | |
| "1 2kAgCRZPG3YQR2VMqRvLmb spotify:track:2kAgCRZPG3YQR2VMqRvLmb \n", | |
| "\n", | |
| " track_href \\\n", | |
| "0 https://api.spotify.com/v1/tracks/4SFBV7SRNG2e... \n", | |
| "1 https://api.spotify.com/v1/tracks/2kAgCRZPG3YQ... \n", | |
| "\n", | |
| " analysis_url duration_ms \\\n", | |
| "0 https://api.spotify.com/v1/audio-analysis/4SFB... 139307 \n", | |
| "1 https://api.spotify.com/v1/audio-analysis/2kAg... 935360 \n", | |
| "\n", | |
| " time_signature target \n", | |
| "0 4 Classical \n", | |
| "1 4 Classical " | |
| ] | |
| }, | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "df_classical.head(2)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "***Techno***" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "techno_ids = \",\".join(techno_ids)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 117, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "r = requests.get(f\"https://api.spotify.com/v1/audio-features/?ids={techno_ids}\", headers=headers)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "techno_features = r.json()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 119, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "df_techno = pd.DataFrame(techno_features['audio_features'])" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "df_techno['target'] = 'Techno'" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>danceability</th>\n", | |
| " <th>energy</th>\n", | |
| " <th>key</th>\n", | |
| " <th>loudness</th>\n", | |
| " <th>mode</th>\n", | |
| " <th>speechiness</th>\n", | |
| " <th>acousticness</th>\n", | |
| " <th>instrumentalness</th>\n", | |
| " <th>liveness</th>\n", | |
| " <th>valence</th>\n", | |
| " <th>tempo</th>\n", | |
| " <th>type</th>\n", | |
| " <th>id</th>\n", | |
| " <th>uri</th>\n", | |
| " <th>track_href</th>\n", | |
| " <th>analysis_url</th>\n", | |
| " <th>duration_ms</th>\n", | |
| " <th>time_signature</th>\n", | |
| " <th>target</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>0.652</td>\n", | |
| " <td>0.859</td>\n", | |
| " <td>11</td>\n", | |
| " <td>-7.757</td>\n", | |
| " <td>1</td>\n", | |
| " <td>0.0519</td>\n", | |
| " <td>0.000315</td>\n", | |
| " <td>0.908</td>\n", | |
| " <td>0.0752</td>\n", | |
| " <td>0.0348</td>\n", | |
| " <td>129.984</td>\n", | |
| " <td>audio_features</td>\n", | |
| " <td>0M07XMvl0ylY9VVt69LsJu</td>\n", | |
| " <td>spotify:track:0M07XMvl0ylY9VVt69LsJu</td>\n", | |
| " <td>https://api.spotify.com/v1/tracks/0M07XMvl0ylY...</td>\n", | |
| " <td>https://api.spotify.com/v1/audio-analysis/0M07...</td>\n", | |
| " <td>391385</td>\n", | |
| " <td>3</td>\n", | |
| " <td>Techno</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1</th>\n", | |
| " <td>0.798</td>\n", | |
| " <td>0.870</td>\n", | |
| " <td>7</td>\n", | |
| " <td>-6.337</td>\n", | |
| " <td>1</td>\n", | |
| " <td>0.0818</td>\n", | |
| " <td>0.001160</td>\n", | |
| " <td>0.830</td>\n", | |
| " <td>0.0582</td>\n", | |
| " <td>0.2760</td>\n", | |
| " <td>129.999</td>\n", | |
| " <td>audio_features</td>\n", | |
| " <td>5weOq4YmiAgStu1cmSZQuB</td>\n", | |
| " <td>spotify:track:5weOq4YmiAgStu1cmSZQuB</td>\n", | |
| " <td>https://api.spotify.com/v1/tracks/5weOq4YmiAgS...</td>\n", | |
| " <td>https://api.spotify.com/v1/audio-analysis/5weO...</td>\n", | |
| " <td>451044</td>\n", | |
| " <td>4</td>\n", | |
| " <td>Techno</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " danceability energy key loudness mode speechiness acousticness \\\n", | |
| "0 0.652 0.859 11 -7.757 1 0.0519 0.000315 \n", | |
| "1 0.798 0.870 7 -6.337 1 0.0818 0.001160 \n", | |
| "\n", | |
| " instrumentalness liveness valence tempo type \\\n", | |
| "0 0.908 0.0752 0.0348 129.984 audio_features \n", | |
| "1 0.830 0.0582 0.2760 129.999 audio_features \n", | |
| "\n", | |
| " id uri \\\n", | |
| "0 0M07XMvl0ylY9VVt69LsJu spotify:track:0M07XMvl0ylY9VVt69LsJu \n", | |
| "1 5weOq4YmiAgStu1cmSZQuB spotify:track:5weOq4YmiAgStu1cmSZQuB \n", | |
| "\n", | |
| " track_href \\\n", | |
| "0 https://api.spotify.com/v1/tracks/0M07XMvl0ylY... \n", | |
| "1 https://api.spotify.com/v1/tracks/5weOq4YmiAgS... \n", | |
| "\n", | |
| " analysis_url duration_ms \\\n", | |
| "0 https://api.spotify.com/v1/audio-analysis/0M07... 391385 \n", | |
| "1 https://api.spotify.com/v1/audio-analysis/5weO... 451044 \n", | |
| "\n", | |
| " time_signature target \n", | |
| "0 3 Techno \n", | |
| "1 4 Techno " | |
| ] | |
| }, | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "df_techno.head(2)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Combining DataFrames**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "main_df = pd.concat([df_hip_hop,df_classical,df_techno])" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>danceability</th>\n", | |
| " <th>energy</th>\n", | |
| " <th>key</th>\n", | |
| " <th>loudness</th>\n", | |
| " <th>mode</th>\n", | |
| " <th>speechiness</th>\n", | |
| " <th>acousticness</th>\n", | |
| " <th>instrumentalness</th>\n", | |
| " <th>liveness</th>\n", | |
| " <th>valence</th>\n", | |
| " <th>tempo</th>\n", | |
| " <th>type</th>\n", | |
| " <th>id</th>\n", | |
| " <th>uri</th>\n", | |
| " <th>track_href</th>\n", | |
| " <th>analysis_url</th>\n", | |
| " <th>duration_ms</th>\n", | |
| " <th>time_signature</th>\n", | |
| " <th>target</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>0.794</td>\n", | |
| " <td>0.756</td>\n", | |
| " <td>5</td>\n", | |
| " <td>-7.160</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.136</td>\n", | |
| " <td>0.11000</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>0.247</td>\n", | |
| " <td>0.775</td>\n", | |
| " <td>123.066</td>\n", | |
| " <td>audio_features</td>\n", | |
| " <td>4DuUwzP4ALMqpquHU0ltAB</td>\n", | |
| " <td>spotify:track:4DuUwzP4ALMqpquHU0ltAB</td>\n", | |
| " <td>https://api.spotify.com/v1/tracks/4DuUwzP4ALMq...</td>\n", | |
| " <td>https://api.spotify.com/v1/audio-analysis/4DuU...</td>\n", | |
| " <td>156498</td>\n", | |
| " <td>4</td>\n", | |
| " <td>Hip-Hop</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1</th>\n", | |
| " <td>0.836</td>\n", | |
| " <td>0.611</td>\n", | |
| " <td>4</td>\n", | |
| " <td>-6.737</td>\n", | |
| " <td>1</td>\n", | |
| " <td>0.247</td>\n", | |
| " <td>0.00406</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>0.101</td>\n", | |
| " <td>0.787</td>\n", | |
| " <td>160.000</td>\n", | |
| " <td>audio_features</td>\n", | |
| " <td>2No8W4sLebINx3pdRUeMnl</td>\n", | |
| " <td>spotify:track:2No8W4sLebINx3pdRUeMnl</td>\n", | |
| " <td>https://api.spotify.com/v1/tracks/2No8W4sLebIN...</td>\n", | |
| " <td>https://api.spotify.com/v1/audio-analysis/2No8...</td>\n", | |
| " <td>145125</td>\n", | |
| " <td>4</td>\n", | |
| " <td>Hip-Hop</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " danceability energy key loudness mode speechiness acousticness \\\n", | |
| "0 0.794 0.756 5 -7.160 0 0.136 0.11000 \n", | |
| "1 0.836 0.611 4 -6.737 1 0.247 0.00406 \n", | |
| "\n", | |
| " instrumentalness liveness valence tempo type \\\n", | |
| "0 0.0 0.247 0.775 123.066 audio_features \n", | |
| "1 0.0 0.101 0.787 160.000 audio_features \n", | |
| "\n", | |
| " id uri \\\n", | |
| "0 4DuUwzP4ALMqpquHU0ltAB spotify:track:4DuUwzP4ALMqpquHU0ltAB \n", | |
| "1 2No8W4sLebINx3pdRUeMnl spotify:track:2No8W4sLebINx3pdRUeMnl \n", | |
| "\n", | |
| " track_href \\\n", | |
| "0 https://api.spotify.com/v1/tracks/4DuUwzP4ALMq... \n", | |
| "1 https://api.spotify.com/v1/tracks/2No8W4sLebIN... \n", | |
| "\n", | |
| " analysis_url duration_ms \\\n", | |
| "0 https://api.spotify.com/v1/audio-analysis/4DuU... 156498 \n", | |
| "1 https://api.spotify.com/v1/audio-analysis/2No8... 145125 \n", | |
| "\n", | |
| " time_signature target \n", | |
| "0 4 Hip-Hop \n", | |
| "1 4 Hip-Hop " | |
| ] | |
| }, | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "main_df.head(2)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Selecting features for algorithm**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "X = main_df[['danceability', 'energy', 'key', 'loudness', 'speechiness', \n", | |
| " 'acousticness', 'instrumentalness', 'liveness', 'valence', \n", | |
| " 'tempo', 'time_signature']]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "y = main_df.target" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Stored 'X' (DataFrame)\n", | |
| "Stored 'y' (Series)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Save variables in JupyterNotebook\n", | |
| "%store X\n", | |
| "%store y" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Scaling Features**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>danceability</th>\n", | |
| " <th>energy</th>\n", | |
| " <th>key</th>\n", | |
| " <th>loudness</th>\n", | |
| " <th>speechiness</th>\n", | |
| " <th>acousticness</th>\n", | |
| " <th>instrumentalness</th>\n", | |
| " <th>liveness</th>\n", | |
| " <th>valence</th>\n", | |
| " <th>tempo</th>\n", | |
| " <th>time_signature</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>0.794</td>\n", | |
| " <td>0.756</td>\n", | |
| " <td>5</td>\n", | |
| " <td>-7.160</td>\n", | |
| " <td>0.1360</td>\n", | |
| " <td>0.11000</td>\n", | |
| " <td>0.000000</td>\n", | |
| " <td>0.2470</td>\n", | |
| " <td>0.775</td>\n", | |
| " <td>123.066</td>\n", | |
| " <td>4</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1</th>\n", | |
| " <td>0.836</td>\n", | |
| " <td>0.611</td>\n", | |
| " <td>4</td>\n", | |
| " <td>-6.737</td>\n", | |
| " <td>0.2470</td>\n", | |
| " <td>0.00406</td>\n", | |
| " <td>0.000000</td>\n", | |
| " <td>0.1010</td>\n", | |
| " <td>0.787</td>\n", | |
| " <td>160.000</td>\n", | |
| " <td>4</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2</th>\n", | |
| " <td>0.902</td>\n", | |
| " <td>0.462</td>\n", | |
| " <td>7</td>\n", | |
| " <td>-7.945</td>\n", | |
| " <td>0.0979</td>\n", | |
| " <td>0.19000</td>\n", | |
| " <td>0.000002</td>\n", | |
| " <td>0.0940</td>\n", | |
| " <td>0.646</td>\n", | |
| " <td>103.984</td>\n", | |
| " <td>4</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>3</th>\n", | |
| " <td>0.900</td>\n", | |
| " <td>0.521</td>\n", | |
| " <td>4</td>\n", | |
| " <td>-7.286</td>\n", | |
| " <td>0.1470</td>\n", | |
| " <td>0.01350</td>\n", | |
| " <td>0.000000</td>\n", | |
| " <td>0.0951</td>\n", | |
| " <td>0.213</td>\n", | |
| " <td>132.007</td>\n", | |
| " <td>4</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>4</th>\n", | |
| " <td>0.868</td>\n", | |
| " <td>0.474</td>\n", | |
| " <td>2</td>\n", | |
| " <td>-8.252</td>\n", | |
| " <td>0.3390</td>\n", | |
| " <td>0.02580</td>\n", | |
| " <td>0.000000</td>\n", | |
| " <td>0.1010</td>\n", | |
| " <td>0.189</td>\n", | |
| " <td>130.000</td>\n", | |
| " <td>4</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " danceability energy key loudness speechiness acousticness \\\n", | |
| "0 0.794 0.756 5 -7.160 0.1360 0.11000 \n", | |
| "1 0.836 0.611 4 -6.737 0.2470 0.00406 \n", | |
| "2 0.902 0.462 7 -7.945 0.0979 0.19000 \n", | |
| "3 0.900 0.521 4 -7.286 0.1470 0.01350 \n", | |
| "4 0.868 0.474 2 -8.252 0.3390 0.02580 \n", | |
| "\n", | |
| " instrumentalness liveness valence tempo time_signature \n", | |
| "0 0.000000 0.2470 0.775 123.066 4 \n", | |
| "1 0.000000 0.1010 0.787 160.000 4 \n", | |
| "2 0.000002 0.0940 0.646 103.984 4 \n", | |
| "3 0.000000 0.0951 0.213 132.007 4 \n", | |
| "4 0.000000 0.1010 0.189 130.000 4 " | |
| ] | |
| }, | |
| "execution_count": 135, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "from sklearn.preprocessing import StandardScaler\n", | |
| "\n", | |
| "scaler = StandardScaler()\n", | |
| "scaled_data = scaler.fit_transform(X)\n", | |
| "\n", | |
| "scaled_df = pd.DataFrame(X, columns=X.columns)\n", | |
| "scaled_df.head()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Training**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from sklearn.model_selection import train_test_split\n", | |
| "\n", | |
| "X_train, X_test, y_train, y_test = train_test_split(scaled_df, y, test_size=0.2, random_state=3)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Attempting multiple K values for K Nearest Neighbors**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from sklearn.neighbors import KNeighborsClassifier" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from sklearn.metrics import precision_score, recall_score, accuracy_score, f1_score" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "# Find best K value\n", | |
| "def find_best_k(X_train, y_train, X_test, y_test, min_k=1, max_k=25):\n", | |
| " best_k = 0\n", | |
| " best_score = 0.0\n", | |
| " \n", | |
| " for k in range(min_k, max_k+1, 2):\n", | |
| " knn = KNeighborsClassifier(n_neighbors=k)\n", | |
| " knn.fit(X_train, y_train)\n", | |
| " preds = knn.predict(X_test)\n", | |
| " f1 = f1_score(y_test, preds, average='micro')\n", | |
| " if f1 > best_score:\n", | |
| " best_k = k\n", | |
| " best_score = f1\n", | |
| " \n", | |
| " print(\"Best Value for k: {}\".format(best_k))\n", | |
| " print(\"F1-Score: {}\".format(best_score))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Best Value for k: 3\n", | |
| "F1-Score: 0.9423076923076923\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "find_best_k(X_train, y_train, X_test, y_test)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "***The best K value is 3***" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "knn = KNeighborsClassifier(n_neighbors=3) # n_neighbors = best K value\n", | |
| "knn.fit(X_train, y_train)\n", | |
| "preds = knn.predict(X_test)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Classification Scores on Test Set**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from sklearn.metrics import classification_report" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "def print_metrics(labels, preds):\n", | |
| " print(\"Precision Score: {}\".format(precision_score(labels, preds, average='micro')))\n", | |
| " print(\"Recall Score: {}\".format(recall_score(labels, preds, average='micro')))\n", | |
| " print(\"Accuracy Score: {}\".format(accuracy_score(labels, preds)))\n", | |
| " print(\"F1 Score: {}\".format(f1_score(labels, preds, average='micro')))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Precision Score: 0.9423076923076923\n", | |
| "Recall Score: 0.9423076923076923\n", | |
| "Accuracy Score: 0.9423076923076923\n", | |
| "F1 Score: 0.9423076923076923\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "print_metrics(y_test, preds)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### **Predicting a Song**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "**Our model is completed. We can now predict the type of music**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "def song_by_id(id):\n", | |
| " r = requests.get(f\"https://api.spotify.com/v1/audio-features/?ids={id}\", headers=headers)\n", | |
| " song_features = r.json()\n", | |
| " \n", | |
| " song_df = pd.DataFrame(song_features['audio_features'])\n", | |
| "\n", | |
| " return song_df[['danceability', 'energy', 'key', 'loudness', 'speechiness', \n", | |
| " 'acousticness', 'instrumentalness', 'liveness', 'valence', \n", | |
| " 'tempo', 'time_signature']]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": { | |
| "scrolled": false | |
| }, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Hip-Hop\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "id = '1mea3bSkSGXuIRvnydlB5b'\n", | |
| "preds = knn.predict(song_by_id(id))\n", | |
| "print(preds[0])" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": "Python 3", | |
| "language": "python", | |
| "name": "python3" | |
| }, | |
| "language_info": { | |
| "codemirror_mode": { | |
| "name": "ipython", | |
| "version": 3 | |
| }, | |
| "file_extension": ".py", | |
| "mimetype": "text/x-python", | |
| "name": "python", | |
| "nbconvert_exporter": "python", | |
| "pygments_lexer": "ipython3", | |
| "version": "3.8.5" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 4 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment