🎵
世界のSpotify「週間トップ50」をPythonで分析
Spotify Web APIについて
「Spotipy」は、Spotify Web APIのための軽量なPythonライブラリです。
今回はSpotipyを用いて、世界のSpotify「週間トップ50」をPythonで分析します。
Spotifyで得られる各楽曲の特徴量(Audio Features)
AudioFeatures | 概要 |
---|---|
acousticness | アコースティック感 |
danceability | 踊りやすさ |
duration_ms | 曲の長さ |
energy | エネルギッシュさ |
instrumentalness | ボーカルが含まれていないことの確信度 |
liveness | ライブ感 |
loudness | 音の大きさ |
speechiness | スピーチ感 |
tempo | テンポ |
valence | ポジティブさ |
Spotipyの準備
①APIの登録を行う
※これらのトークンは流出させないよう注意してくだいさい。
②Python環境にspotipyパッケージをpip Installする
pip install spotipy
各国の週間トップ50曲を収集し、国ごとの特徴を分析
ソースコード一覧(Jupyter Notebook)は⇓で公開しています。
前準備
import yaml
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
import yaml
from pprint import pprint
from tqdm.notebook import tqdm
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
with open('./secret.yaml') as f:
secret = yaml.safe_load(f)
sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials(
client_id=secret['SPOTIFY_API_CLIENT_ID'],
client_secret=secret['SPOTIFY_API_CLIENT_SECRET']),
language='ja')
週間トップ50曲を取得
weekly_top_playlist_ids_dict = dict(
Global='37i9dQZEVXbNG2KDcFcKOF', # グローバル
Japan='37i9dQZEVXbKqiTGXuCOsB', # 日本
Korea='37i9dQZEVXbJZGli0rRP3r', # 韓国
America='37i9dQZEVXbLp5XoPON0wI', # アメリカ
Italy='37i9dQZEVXbJUPkgaWZcWG', # イタリア
India='37i9dQZEVXbMWDif5SCBJq', # インド
Brazil='37i9dQZEVXbKzoK95AbRy9', # ブラジル
)
def get_playlist_tracks(playlist_ids:dict, playlist_len:int):
tracks_df = pd.DataFrame(np.zeros((playlist_len*len(playlist_ids.keys()), 5)), \
columns=['country', 'weekly_rank', 'artist', 'title', 'uri'])
for i, country in enumerate(tqdm(playlist_ids.keys())):
playlist = sp.playlist(playlist_id=playlist_ids[country], market='JP')
print(playlist['description'])
tracks = playlist['tracks']['items']
for j, track in enumerate(tracks):
idx = (i*50) + j
track_info = track['track']
tracks_df.loc[idx, 'country'] = country
tracks_df.loc[idx, 'weekly_rank'] = int(j+1)
tracks_df.loc[idx, 'artist'] = track_info['artists'][0]['name']
tracks_df.loc[idx, 'title'] = track_info['name']
tracks_df.loc[idx, 'uri'] = track_info['uri']
return tracks_df
tracks_df = get_playlist_tracks(playlist_ids=weekly_top_playlist_ids_dict, playlist_len=50)
各曲の特徴量を取得
def get_playlist_features(tracks_df, use_features_list:list, chunk_n=100):
tracks_df_idx_list = tracks_df.index.tolist()
tracks_df_idx_chunk_list = [tracks_df_idx_list[i:i+chunk_n] for i in range(0, len(tracks_df_idx_list), chunk_n)]
print(f"All:{len(tracks_df_idx_list)} -> ChunkSize:{chunk_n} | ChunkLength:{len(tracks_df_idx_chunk_list)}")
for idx_chunk in tqdm(tracks_df_idx_chunk_list):
tmp_df = tracks_df.loc[idx_chunk]
uri_list = tmp_df.uri.tolist()
sp_features_list = sp.audio_features(tracks=uri_list)
for idx, sp_features in zip(idx_chunk, sp_features_list):
for feature_name in use_features_list:
tracks_df.loc[idx, feature_name] = sp_features[feature_name]
return tracks_df
use_features_list = ['danceability', 'energy', 'speechiness', 'acousticness',
'valence', 'tempo', 'liveness', 'duration_ms']
tracks_df = get_playlist_features(tracks_df=tracks_df, use_features_list=use_features_list, chunk_n=100)
プロットするための前準備
# 標準化
tracks_s_df = tracks_df.copy()
tracks_s_df[use_features_list] = tracks_df[use_features_list].apply(lambda x: (x-x.mean())/x.std(), axis=0)
tracks_s_df.head()
# Featuresを縦に結合(SeabornでBoxPlotを描写するため)
features_s_concat_df = pd.DataFrame()
for column_n in use_features_list:
pick_col_list = [*tracks_s_df.columns.tolist()[0:5], column_n]
col_df = tracks_s_df.loc[:, pick_col_list]
col_df.rename(columns={column_n: 'value'}, inplace=True)
col_df['feature_name'] = column_n
features_s_concat_df = pd.concat([features_s_concat_df, col_df], axis=0)
各国のトップ50曲の特徴をプロット
fig = plt.figure(figsize=(3*len(weekly_top_playlist_ids_dict), 10))
ax = fig.add_subplot(111)
ax.grid()
ax.set_title('Comparison of the top 50 Spotify weekly rankings in each country.')
ax = sns.boxplot(x='country', y="value", hue='feature_name', data=features_s_concat_df, palette="Set2", whis=np.inf, linewidth=2)
fig.savefig('./top_50_comparison.pdf')
fig.savefig('./top_50_comparison.jpg')
各国のトップ50曲の特徴について考察
Japan(日本)
他国と比べると、エネルギッシュさ「energy」が高く、楽曲の長さ「duration_ms」が比較的長いことが読み取れる。
Korea(韓国)
上記のグラフだと平均値0の周辺に各特徴量が固まっており、バランスがよい。
America(アメリカ)
各特徴量に大きなばらつきがあり、多種多様な楽曲がランクインしていると推測できる。
Italy(イタリア)
「danceability」、「valence」が高く、「acousticness」が低くなっている。ポップで明るく、陽気な曲が多いことが読み取れる。
India(インド)
曲によってかなりばらつきが見られるが、リズミカルだが比較的落ち着いた曲が多いのではないか。
Brazil(ブラジル)
「energy」「acousticness」の相反する特徴量が高くなっており、特徴量同士の関係を詳細に見ないと曲の特徴をつかめないと痛感した。
Discussion