16
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Spotifyで自分が聞いた曲を分析してみた

Last updated at Posted at 2022-05-23

はじめに

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
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()

energy.png

HR/HMをよく聴くからでしょうか、エネルギッシュな曲が多いです。
他の特徴も見てみましょう。

Figure_1.png

曲の明るさ、アコースティック度、インスト度、踊りやすさ
4つのグラフを出力しました。インスト曲はもう少し聴いていたと思うのですがほとんどがボーカル曲であることが分かります。暗い曲から明るい曲まで幅広く聴いていますね。ロックに比重が傾くのでアコースティック度が低い曲に集中しているのは納得です。

Figure_1.png
全てまとめるとこんな感じになります。ヒップホップとかラップはあんまり聴いてないのがばれてしまいました。

相関を調べる

次に、各特徴の相関を調べる。まずこの特徴群から相関がありそうなのは曲の明るさ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()

output.png

このようにやや右肩上がりの散布図が出来上がりました。相関係数は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()

heat_map.png

特に相関係数が高いのがenergyloudnessの0.87ですね。確かにエネルギッシュな曲は音量レベルを大きめに設定していることが多いので、納得できます。次に高いのが先述のvalencedanceabilityで、三番目がacosuticnessinstrumentalnessでした。

acosuticnessinstrumentalnessはおそらく私がジャズをよく聞いてるため、このような結果が出たと思いますが、例えばフュージョンとかサントラをよく聞いている人はこの限りでないでしょう。

逆に、相関係数が低いのがacosuticnessenergy,loudnessinstrumentalnessloudnessあたりです。acosuticnessは明るい曲と逆になるのは納得できます。インスト曲はうるさい曲もありますが、私は基本ジャズを聴いているので負の相関となっています。メタルインストばっかり聴いてる人なら正の相関になるんじゃないでしょうか

まとめ

こうやって分析していくと、その人がどんな音楽を聴いているのかが見えてきて面白いですね。そもそも私がデータベースに履歴を保存しようとしたのは、「普段どんな音楽聴いてるの?」という質問にデータを使って答えたかったからなんです。こういったデータは自己紹介とかのプレゼンで使用すれば面白そうだなと思うので、これからも色々と解析していきたいと思います。

ちなみに自分が聴いてる曲以外も解析したりしてますが、例えばヒットチャートの解析とかはもう既に何人かQiitaにも記事を上げてやってたりするので、私は音楽好きとしてちょっと趣向を凝らしたアプローチをしていきたいと思います。

16
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?