Data Science, anche nella musica.
Testando l'API di Spotify ho scoperto molte funzionalità nascoste dietro le canzoni che ascoltiamo ogni giorno.
Ecco il progetto, ma preferisco mostrarvelo in questo articolo.https://github.com/ivanurquiza/Spotify-Analysis
Ho avuto l'idea di analizzare le canzoni più ascoltate al momento.
Due domande principali a cui rispondere:
1. Qual è la caratteristica della musica di tendenza?
2. In cosa differisce dalla musica vecchio stile?
# FILL IN THESE VALUES WITH YOUR OWN KEYS
client_id = ...
client_secret = ...
# Make sure to add this on "Edit Settings" in your Dashboard
redirect_uri = "http://localhost:9000"
import spotipy
from spotipy.oauth2 import SpotifyOAuth
# Connect with API Keys created earlier
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri))
Ho dovuto fare una scelta. Per questo caso ho utilizzato una playlist molto famosa in Argentina creata da Spotify, che contiene la Top 50 delle canzoni più ascoltate al momento:
#Playlist ID
TOP50_playlist = sp.playlist('37i9dQZEVXbMMy2roB9myp')
for track_data in TOP50_playlist['tracks']['items']:
#Getting just the ID (last part of the url)
track_id = track_data['track']['uri'].split(':')[-1]
track_name = track_data['track']['name']
track_popularity = track_data['track']['popularity']
list_tracksids.append((track_name,track_id,track_popularity))
df_features = pd.DataFrame()
for idx, dict_trackfeatures in enumerate(sp.audio_features(tracks=[url[1] for url in list_tracksids])):
dict_trackfeatures['track_name'] = list_tracksids[idx][0]
dict_trackfeatures['popularity'] = list_tracksids[idx][2]
df_features = pd.concat([df_features,pd.Series(dict_trackfeatures)], axis=1)
#Selects only useful features
df_features=df_features.transpose()[['track_name','popularity','danceability','energy','loudness','speechiness','acousticness','instrumentalness','liveness','tempo']]
#Display Top 5 songs
df_features.head()
Siamo pronti. Analizziamo i dati!
Tracciamo alcuni grafici per ottenere i primi schemi sulla musica più popolare.
Dal grafico a sinistra, possiamo vedere che la musica che compone la nostra playlist TOP 50 si trova principalmente nella seconda metà (oltre 0,5 su 1), il che a quanto pare significa che è molto ballabile. Come possiamo sapere se questo sospetto è vero?
Confrontiamo la ballabilità media di queste canzoni con la musica classica. Ciao Mozart!
import seaborn as sns
import matplotlib.pyplot as plt
# Let's plot some charts for getting the first patterns about the most popular music
sns.set_theme(context='notebook',style="ticks")
fig, axes = plt.subplots(1, 2, figsize=(10,5))
# Left - Danceability's histogram with kde
sns.distplot(ax=axes[0], x=df_features["danceability"], bins=6, kde=True, color="#5B3BA0")
axes[0].set(xlabel='Danceability', ylabel='Frequency')
axes[0].set_title('TOP 50 Danceability freq.')
# Right - Comparation between the playlist avarage and Mozart's most popular song
# Requiem, K. 626: Lacrimosa
mozart_danceability = sp.audio_features(tracks=['3oHSL6pt9LpNrQZuQGu9wL'])[0]['danceability']
avg_top50_danceability = df_features['danceability'].mean()
sns.barplot(ax= axes[1],
x = 'who',
y = 'Danceability',
data = {'who':['TOP 50','MOZART'],
'Danceability':[avg_top50_danceability, mozart_danceability]},
palette=['#5B3BA0','#A378FF']
)
axes[1].set(ylabel='Danceability')
axes[1].set_title('Mozart vs TOP 50')
plt.show()
Come possiamo immaginare, Mozart non è nella Top 50 delle canzoni più suonate. Sulla base della nostra breve analisi, Mozart potrebbe non avere abbastanza ballabilità per far parte della playlist.
- Ballabilità di Mozart: 0.162
- Media ballabilità TOP 50: 0,739
#Adding Mozart's song variables to our dataframe
mozart = pd.DataFrame({'track_name':['Mozart'], 'popularity':[0.0]})
for k,v in sp.audio_features(tracks=['3oHSL6pt9LpNrQZuQGu9wL'])[0].items():
if k in df_features.keys():
mozart[k]=v
df_features = pd.concat([df_features,mozart], axis=0)
df_features['playlist'] = ['TOP 50' if x != 'Mozart' else 'Mozart' for x in df_features['track_name']]
df_features.tail(1)
#Scatter plot
plt.figure(dpi=80)
sns.scatterplot(
data=df_features, x='acousticness',y='loudness', hue="playlist",
sizes=(20, 200), legend="full", palette=['#5B3BA0','#D00000']
)
plt.show()
Questo grafico aiuta in parte a capire perché Mozart non è di moda. I brani nella Top 50 hanno valori simili delle variabili “loudness” e “acusticness” e sono molto concentrati nella parte in alto a sinistra del grafico. La tendenza è chiara: alto volume e bassi livelli di acustica. Mozart, invece, va controcorrente!
Stessi passi, altra playlist
E se invece di Mozart e delle canzoni di tendenza prendessimo una playlist con le migliori canzoni degli anni '80?
Facciamo lo stesso, ma leggermente diverso.
AllOut80s = sp.playlist('37i9dQZF1DX4UtSsGT1Sbe')
list_tracksids = list()
for track_data in AllOut80s['tracks']['items']:
#Gets just the ID (last part of the url)
track_id = track_data['track']['uri'].split(':')[-1]
track_name = track_data['track']['name']
track_popularity = track_data['track']['popularity']
list_tracksids.append((track_name,track_id,track_popularity))
AllOut80s_features = pd.DataFrame()
for idx, dict_trackfeatures in enumerate(sp.audio_features(tracks=[url[1] for url in list_tracksids])):
dict_trackfeatures['track_name'] = list_tracksids[idx][0]
dict_trackfeatures['popularity'] = list_tracksids[idx][2]
AllOut80s_features = pd.concat([AllOut80s_features,pd.Series(dict_trackfeatures)], axis=1)
#Selects only useful features
AllOut80s_features=AllOut80s_features.transpose()[['track_name','popularity','danceability','energy','loudness','speechiness','acousticness','instrumentalness','liveness','tempo']]
AllOut80s_features['playlist'] = 'AllOut80s'
#Handles data types
AllOut80s_features[['danceability','energy','loudness','speechiness','acousticness','instrumentalness','liveness','tempo']]=AllOut80s_features[['danceability','energy','loudness','speechiness','acousticness','instrumentalness','liveness','tempo']].astype(float)
Guarda i risultati:
# Setting up concatenated df
df_allsongs = pd.concat([df_features, AllOut80s_features[:50]]).reset_index()
df_allsongs= df_allsongs.drop(df_allsongs.index[df_allsongs['playlist'] == 'Mozart'])
plt.figure(dpi=80)
sns.lmplot(
data=df_allsongs, x='acousticness',y='loudness', hue="playlist",
legend="full", palette=['#5B3BA0','#D00000']
)
plt.show()
Osservando le distribuzioni e le linee di regressione per ciascuna playlist, notiamo che le tendenze sono piuttosto diverse. Sebbene la relazione tra le variabili (pendenza delle curve) rimanga abbastanza simile, le canzoni sembrano essere posizionate secondo uno schema, con la playlist Top 50 che ha un livello più alto di “loudness”.
Solo controllando queste due caratteristiche, possiamo vedere che la musica degli anni '80 è più simile alle tendenze attuali di Mozart.
Facciamo un ulteriore passo avanti nel progetto!
Possiamo prevedere, considerando tutte le possibili variabili, a quale playlist appartiene una canzone? Non ne sono sicuro, ma la risposta è probabilmente KNeighbors .
Ho cercato su Google la canzone più rappresentativa degli anni '80 per usarla come input della nostra previsione di modellazione:
Features used for modeling
featlist=['danceability','energy','loudness','speechiness','acousticness','instrumentalness','liveness','tempo']
prince = {}
for k,v in sp.audio_features(tracks=['54X78diSLoUDI3joC2bjMz'])[0].items():
if k in featlist:
prince[k]=v
prince = pd.DataFrame(prince.items()).transpose()
prince.columns = prince.iloc[0]
prince=prince[1:]
prince[featlist] = prince[featlist].astype(float)
prince
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=3)
X = df_allsongs[featlist]
y = df_allsongs['playlist']
knn.fit(X,y)
# Prediction
prediction = knn.predict(prince)
print('The song could be included in the playlist: ', prediction[0])
Grazie per aver letto!
Contatto : www.linkedin.com/in/ivanroblesurquiza
Cinguettio :https://twitter.com/urqivo

![Che cos'è un elenco collegato, comunque? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































