はじめに
Spotify便利ですよね。私はサービスを使うまではCD派だったんですが、Spotify使い始めてからというものの、すっかりサブスクすげええええってなってます。音楽の海を探検するのは楽しいです。もちろんCDでも聴いてますよ
このSpotify、再生した曲の履歴が昔は50曲しか残らなくて、去年の春くらいに3か月分残るようにアプデがあったんですけど、それでも履歴の検索は出来ないので、気軽に見返したりができないわけです。
そこで、Spotify APIを用いて再生楽曲をデータベースに保存するプログラムを作りました。で、かれこれ1年経ったので、自分が聴いてきた楽曲を分析してみました。
このプログラム、ただ再生した楽曲を保存するのではなく、ちゃんと最初から最後まで再生した曲しか保存しないようになってます。何でかというと、間違えて再生した曲とか、ランダム再生でたまにスキップしたくなった時にその曲を除外するためです。イントロ飛ばしはゆるしまへんで!
データについて
この一年で保存された楽曲数は18621曲でした。まあちゃんと再生してない曲しかカウントしてないのでこんなものでしょう。このデータベースには4つのテーブルがあります
- 楽曲データ
- アーティスト情報
- 楽曲の特徴
- 楽曲の人気度
これらをCSVに落として、データを見ていきます。今回使うのは楽曲の特徴ファイルだけです。
楽曲の特徴の内容
Spotify APIで得られる楽曲特徴データは様々あります。以下の表はデータベースで保存している特徴です。
特徴 | 説明 |
---|---|
acousticness | アコースティック度(0.0~1.0) |
danceability | 踊りやすさ(0.0~1.0) |
energy | エネルギッシュさ(0.0~1.0) |
instrumentalness | インスト度(0.0~1.0) |
key | 曲のキー(0~11) |
liveness | ライブ感(0.0~1.0) |
loudness | 音量レベル(-60db~0db) |
mode | 調性(0,1) |
speechiness | しゃべりっぽさ(0.0~1.0) |
tempo | テンポ(BPM) |
valence | 曲の明るさ(0.0~1.0) |
このように、様々な特徴が取れます。
例えばenergy
はメタルとかハードロックだと高い数値が出るようです。speechiness
は0.6あたりだとラップ曲といった感じです。
他の特徴はリファレンスを参照してください
楽曲分析
APIを使う
では試しに1つの楽曲の特徴を見てみましょう。私の好きなフランツ・フェルディナンドのDo You Want To
を分析してみます。
以下のプログラムを書きます。IDとかは各自で入手して入力してください。
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
import pandas as pd
client_id = "xxx"
client_secret = "xxx"
client_credentials_manager = SpotifyClientCredentials(client_id, client_secret)
sp_body = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
track = sp_body.track("4ZdFTSdAmsoivF6pcM9Isz") #トラックID
print(track[9])
すると、以下の結果が得られる
{'danceability': 0.453,
'energy': 0.477,
'key': 2,
'loudness': -8.364,
'mode': 1,
'speechiness': 0.032,
'acousticness': 0.297,
'instrumentalness': 0,
'liveness': 0.193,
'valence': 0.151,
'tempo': 109.38,
'type': 'audio_features',
'id': '4ZdFTSdAmsoivF6pcM9Isz',
'uri': 'spotify:track:4ZdFTSdAmsoivF6pcM9Isz',
'track_href': 'https://api.spotify.com/v1/tracks/4ZdFTSdAmsoivF6pcM9Isz',
'analysis_url': 'https://api.spotify.com/v1/audio-analysis/4ZdFTSdAmsoivF6pcM9Isz',
'duration_ms': 237200,
'time_signature': 4}
ざっと見ると、energy
が高いですね。この曲はかなり陽気でノリノリな曲なので納得です。同様にvalence
も高く、この二つは似た属性なので相関がありそうです。
ただ、フランツ・フェルディナンドは踊れるロックということで定評があるのですが、danceability
は思ったよりも高くありませんでした。EDMとかディスコとなるともう少し高くなるでしょうか
もう1曲特徴を見てみましょう。次はインスト曲のこれです。
結果は以下のようになりました。
{'danceability': 0.51,
'energy': 0.919,
'key': 7,
'loudness': -8.244,
'mode': 1,
'speechiness': 0.0593,
'acousticness': 0.00205,
'instrumentalness': 0.809,
'liveness': 0.068,
'valence': 0.386,
'tempo': 141.053,
'type': 'audio_features',
'id': '3lpDrxUkr0tIe1kmJvdK7d',
'uri': 'spotify:track:3lpDrxUkr0tIe1kmJvdK7d',
'track_href': 'https://api.spotify.com/v1/tracks/3lpDrxUkr0tIe1kmJvdK7d',
'analysis_url': 'https://api.spotify.com/v1/audio-analysis/3lpDrxUkr0tIe1kmJvdK7d',
'duration_ms': 265840,
'time_signature': 4}
インスト曲なのでinstrumentalness
が0.809と高いですね。danceability
がさっきよりも高いのが意外でした。
履歴を分析
それではマイソングス達を見ていきましょう。データベースからダンプした楽曲特徴データを掲載したCSVファイルの「music_features.csv」を使用します。
├── csv/
│ └─ music_features.csv
├── main.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = pd.read_csv("csv/music_features.csv")
print(df)
実行するとこうなります。
record_id track_id acousticness danceability energy instrumentalness key liveness loudness mode speechiness tempo valence
0 1 7f7qDb9gtih3uuSIiOk9Lv 0.000273 0.134 0.9800 0.000000 4.0 0.2170 -1.248 1.0 0.0846 167.0 0.719
1 2 1JNnJME8FBXASVWjDatyH3 0.000480 0.371 0.9010 0.000000 0.0 0.2830 -1.655 1.0 0.0616 127.0 0.661
2 3 7N3PAbqfTjSEU1edb2tY8j 0.171000 0.572 0.8350 0.000377 0.0 0.0702 -6.219 1.0 0.0317 129.0 0.795
3 4 0OLSKxtucXAdTRknBf3KbN 0.238000 0.591 0.9040 0.143000 0.0 0.1250 -6.021 1.0 0.0349 120.0 0.647
4 5 3aYVWpgxbah3J9RJXCWBJE 0.001840 0.538 0.8380 0.002910 2.0 0.1920 -6.126 0.0 0.0331 112.0 0.622
... ... ... ... ... ... ... ... ... ... ... ... ... ...
18616 18628 5Vj4eHzcf4SJNtOx2SxWxw 0.972000 0.389 0.0773 0.920000 4.0 0.0772 -22.129 1.0 0.0392 100.0 0.109
18617 18629 1GoANJKOliZEQqvkk9Mdvh 0.990000 0.483 0.3520 0.913000 4.0 0.1160 -17.332 1.0 0.0385 90.0 0.645
18618 18630 3lq6i23fC6j1v1AR0GeNg8 0.074700 0.648 0.8750 0.000096 2.0 0.1960 -5.141 0.0 0.0340 102.0 0.857
18619 18631 4TigEFb9C8CfKmzdJtgJ5f 0.066200 0.421 0.9290 0.000171 0.0 0.5010 -3.264 1.0 0.0485 123.0 0.758
18620 18632 0OLSKxtucXAdTRknBf3KbN 0.238000 0.591 0.9040 0.143000 0.0 0.1250 -6.021 1.0 0.0349 120.0 0.647
何かいろんな値が出てきましたね。。とりあえずenergy
でヒストグラムを出してみます。
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
x = df["energy"]
ax.hist(x, bins="scott", range=(0, 1)) #スコットの選択
ax.set_title('energy histgram')
ax.set_xlabel('popularity')
ax.set_ylabel('frequency')
plt.xlim(0, 1)
plt.show()
HR/HMをよく聴くからでしょうか、エネルギッシュな曲が多いです。
他の特徴も見てみましょう。
曲の明るさ、アコースティック度、インスト度、踊りやすさ
4つのグラフを出力しました。インスト曲はもう少し聴いていたと思うのですがほとんどがボーカル曲であることが分かります。暗い曲から明るい曲まで幅広く聴いていますね。ロックに比重が傾くのでアコースティック度が低い曲に集中しているのは納得です。
全てまとめるとこんな感じになります。ヒップホップとかラップはあんまり聴いてないのがばれてしまいました。
相関を調べる
次に、各特徴の相関を調べる。まずこの特徴群から相関がありそうなのは曲の明るさvalence
と踊りやすさdanceability
と考えられるので、散布図をプロットする。
y = df["danceability"].values
print(np.corrcoef(x, y))
plt.xlabel("valence")
plt.ylabel("danceability")
plt.scatter(x, y, s=5)
plt.show()
このようにやや右肩上がりの散布図が出来上がりました。相関係数は0.6なのである程度の関係があるようですね。他のも見るためにヒートマップで相関係数をまとめてみました。
import seaborn as sns
df = df.drop(columns='record_id')
df = df.drop(columns='track_id')
df_mean = (df - df.min()) / (df.max() - df.min()) #正規化
df_mean = df_mean.corr().round(2)
sns.heatmap(df_mean, cmap='coolwarm', vmin=-1, vmax=1, annot=True)
plt.show()
特に相関係数が高いのがenergy
とloudness
の0.87ですね。確かにエネルギッシュな曲は音量レベルを大きめに設定していることが多いので、納得できます。次に高いのが先述のvalence
とdanceability
で、三番目がacosuticness
とinstrumentalness
でした。
acosuticness
とinstrumentalness
はおそらく私がジャズをよく聞いてるため、このような結果が出たと思いますが、例えばフュージョンとかサントラをよく聞いている人はこの限りでないでしょう。
逆に、相関係数が低いのがacosuticness
とenergy
,loudness
、instrumentalness
とloudness
あたりです。acosuticness
は明るい曲と逆になるのは納得できます。インスト曲はうるさい曲もありますが、私は基本ジャズを聴いているので負の相関となっています。メタルインストばっかり聴いてる人なら正の相関になるんじゃないでしょうか
まとめ
こうやって分析していくと、その人がどんな音楽を聴いているのかが見えてきて面白いですね。そもそも私がデータベースに履歴を保存しようとしたのは、「普段どんな音楽聴いてるの?」という質問にデータを使って答えたかったからなんです。こういったデータは自己紹介とかのプレゼンで使用すれば面白そうだなと思うので、これからも色々と解析していきたいと思います。
ちなみに自分が聴いてる曲以外も解析したりしてますが、例えばヒットチャートの解析とかはもう既に何人かQiitaにも記事を上げてやってたりするので、私は音楽好きとしてちょっと趣向を凝らしたアプローチをしていきたいと思います。