Data Science, até na música.
Testando a API do Spotify, descobri muitos recursos ocultos por trás das músicas que ouvimos todos os dias.
Aqui está o projeto, mas prefiro mostrá-lo neste artigo.https://github.com/ivanurquiza/Spotify-Analysis
Tive a ideia de analisar as músicas mais ouvidas no momento.
Duas perguntas principais a serem respondidas:
1. Qual é a característica da música popular?
2. Em que ela difere da música antiga?
# 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))
Eu tive que fazer uma escolha. Para este caso, usei uma playlist muito famosa na Argentina criada pelo Spotify, que contém as 50 músicas mais ouvidas no 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()
Estamos prontos. Vamos analisar os dados!
Vamos traçar alguns gráficos para obter os primeiros padrões sobre a música mais popular.
No gráfico à esquerda, podemos ver que a música que compõe nossa playlist TOP 50 está localizada principalmente na segunda metade (mais de 0,5 de 1), o que aparentemente significa que é muito dançante. Como podemos saber se essa suspeita é verdadeira?
Vamos comparar a dançabilidade média dessas músicas com a música clássica. Olá 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()
Como podemos imaginar, Mozart não está no Top 50 das músicas mais tocadas. Com base em nossa breve análise, Mozart pode não ter dançabilidade suficiente para fazer parte da lista de reprodução.
- Dançabilidade de Mozart: 0,162
- Média de dançabilidade 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()
Este gráfico ajuda em parte a entender por que Mozart não está na moda. As músicas do Top 50 possuem valores semelhantes das variáveis “loudness” e “acousticness” e estão altamente concentradas na parte superior esquerda do gráfico. A tendência é clara: alto volume e baixos níveis de acústica. Por outro lado, Mozart vai contra a tendência!
Mesmos passos, outra lista de reprodução
E se, em vez de Mozart e músicas da moda, pegássemos uma playlist com as melhores músicas dos anos 80?
Vamos fazer o mesmo, mas um pouco diferente.
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)
Veja os resultados:
# 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()
Observando as distribuições e linhas de regressão para cada lista de reprodução, notamos que as tendências são bastante diferentes. Embora a relação entre as variáveis (inclinação das curvas) permaneça bastante semelhante, as músicas parecem estar posicionadas em um padrão, sendo que a playlist Top 50 apresenta maior nível de “loudness”.
Apenas verificando essas duas características, podemos ver que a música dos anos 80 é mais parecida com as tendências atuais do que Mozart.
Vamos levar o projeto um passo adiante!
Podemos prever, considerando todas as variáveis possíveis, a qual playlist uma música pertence? Não tenho certeza, mas a resposta provavelmente é KNeighbours .
Pesquisei no Google a música mais representativa dos anos 80 para usá-la como entrada de nossa previsão de modelagem:
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])
Obrigado por ler!
Contato : www.linkedin.com/in/ivanroblesurquiza
Twitter :https://twitter.com/urqivo





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)