こんにちは、Michaelです!

雨が降ってきました。今年も梅雨が到来しましたね。

私は去年の7月2日に日本に帰国したのですが、梅雨真っ只中でした。
8年ぶりの梅雨、帰国した直後から面接に向かい、蒸し暑い中スーツで走り回っていたのを覚えています。

もうあれから一年経ったのか。。月日が経つのは早いですね。

さて、今日は前回のブログに引き続き、Spotify APIで取得した宇多田ヒカルの楽曲データーを分析していきましょう。

まず、前回の続きからでモデリングに少し手を加えます。

1.データ加工

データの表示変更・カラムの追加

前回取得したデータに不備があり、全楽曲を含んでいないことが確認できたため、今回新たに以下のように楽曲データを取得し直しました。

①アルバム収録曲のみを集めたもの=90曲
②シングルを集めたもの=50曲

各①、②のCSVファイルからカスタムテーブルを作ります。

まず最初に、元データを確認したところ、いくつかの項目に対して見やすくするために以下の処理を行いました。

・テンポに少数点が含まれていたためROUND処理
・lengthがミリセカンズ単位だったので1000で割って秒単位に変更
・modeが1の時は「メジャー」、0の時は「マイナー」と表記の変更

次に分析を容易化するために、各テーブルに対して、以下のカラムを追加しました。

  • ・アルバムの順番
  • ・アルバムの順番が先頭についたアルバム名(可視化時点で見やすくするため)※シングル曲のテーブルにはシングルの順番を先頭に付けた番号になっています
  • ・danceability, energy, acosticness, valenceに対して、0.1区切りのtierをそれぞれ4つ(ヒートマップ作成のため)
  • ・リリースされた季節
  • ・リリース時の宇多田ヒカルの年齢(リリース日から彼女の誕生日である1983年1月19日の引き算)
  • ・リリース時の彼女のキャリアステージ(1_新人時代、2_スター期、3_充電期間、4_出産後)

アルバム収録曲の中にリミックス曲が含まれていたので、WHERE句で除外しました。
分析対象はあくまでもオリジナル曲に限るためです。

SQLは以下のようになりました。シングル曲に関しても同様の処理済みです。
(SisenseのモデリングはSQLベース+Sisense独自の関数です)

SELECT
    name
  , album
  , artist
  , release_date
  , YearDiff(release_date, CREATEDATE(1983,1,19)) AS age
  , RankDenseAsc(release_date) AS album_order
  , ToString(RankDenseAsc(release_date)) + '_' + album AS album_order_name
  , length / 1000 as length_seconds
  
  , CASE
      WHEN mode = 1 THEN 'major'
      WHEN mode = 0 THEN 'minor'
    END AS mode
  , popularity
  
  , danceability
  
  , CASE
      WHEN danceability BETWEEN 0 AND 0.099 THEN '0.0-0.1'
      WHEN danceability BETWEEN 0.1 AND 0.199 THEN '0.1-0.2' 
      WHEN danceability BETWEEN 0.2 AND 0.299 THEN '0.2-0.3' 
      WHEN danceability BETWEEN 0.3 AND 0.399 THEN '0.3-0.4' 
      WHEN danceability BETWEEN 0.4 AND 0.499 THEN '0.4-0.5' 
      WHEN danceability BETWEEN 0.5 AND 0.599 THEN '0.5-0.6' 
      WHEN danceability BETWEEN 0.6 AND 0.699 THEN '0.6-0.7' 
      WHEN danceability BETWEEN 0.7 AND 0.799 THEN '0.7-0.8' 
      WHEN danceability BETWEEN 0.8 AND 0.899 THEN '0.8-0.9'
      WHEN danceability BETWEEN 0.9 AND 1 THEN '0.9-1.0'
    END AS danceability_tier
  
    , acousticness
    
    , CASE
      WHEN acousticness BETWEEN 0 AND 0.099 THEN '0.0-0.1'
      WHEN acousticness BETWEEN 0.1 AND 0.199 THEN '0.1-0.2' 
      WHEN acousticness BETWEEN 0.2 AND 0.299 THEN '0.2-0.3' 
      WHEN acousticness BETWEEN 0.3 AND 0.399 THEN '0.3-0.4' 
      WHEN acousticness BETWEEN 0.4 AND 0.499 THEN '0.4-0.5' 
      WHEN acousticness BETWEEN 0.5 AND 0.599 THEN '0.5-0.6' 
      WHEN acousticness BETWEEN 0.6 AND 0.699 THEN '0.6-0.7' 
      WHEN acousticness BETWEEN 0.7 AND 0.799 THEN '0.7-0.8' 
      WHEN acousticness BETWEEN 0.8 AND 0.899 THEN '0.8-0.9'
      WHEN acousticness BETWEEN 0.9 AND 1 THEN '0.9-1.0'
    END AS acousticness_tier
  , energy
  
  , CASE
      WHEN energy BETWEEN 0 AND 0.099 THEN '0.0-0.1'
      WHEN energy BETWEEN 0.1 AND 0.199 THEN '0.1-0.2' 
      WHEN energy BETWEEN 0.2 AND 0.299 THEN '0.2-0.3' 
      WHEN energy BETWEEN 0.3 AND 0.399 THEN '0.3-0.4' 
      WHEN energy BETWEEN 0.4 AND 0.499 THEN '0.4-0.5' 
      WHEN energy BETWEEN 0.5 AND 0.599 THEN '0.5-0.6' 
      WHEN energy BETWEEN 0.6 AND 0.699 THEN '0.6-0.7' 
      WHEN energy BETWEEN 0.7 AND 0.799 THEN '0.7-0.8' 
      WHEN energy BETWEEN 0.8 AND 0.899 THEN '0.8-0.9'
      WHEN energy BETWEEN 0.9 AND 1 THEN '0.9-1.0'
    END AS energy_tier
    
  , instrumentalness
  , liveness
  , loudness
  , speechiness
  , ROUND(tempo,0) AS tempo
  ,time_signature
  , valence
  
  , CASE
      WHEN valence BETWEEN 0 AND 0.099 THEN '0.0-0.1'
      WHEN valence BETWEEN 0.1 AND 0.199 THEN '0.1-0.2' 
      WHEN valence BETWEEN 0.2 AND 0.299 THEN '0.2-0.3' 
      WHEN valence BETWEEN 0.3 AND 0.399 THEN '0.3-0.4' 
      WHEN valence BETWEEN 0.4 AND 0.499 THEN '0.4-0.5' 
      WHEN valence BETWEEN 0.5 AND 0.599 THEN '0.5-0.6' 
      WHEN valence BETWEEN 0.6 AND 0.699 THEN '0.6-0.7' 
      WHEN valence BETWEEN 0.7 AND 0.799 THEN '0.7-0.8' 
      WHEN valence BETWEEN 0.8 AND 0.899 THEN '0.8-0.9'
      WHEN valence BETWEEN 0.9 AND 1 THEN '0.9-1.0'
    END AS positivity_tier
    
  , 'album' AS category
  , CASE
      WHEN getYear(release_date) BETWEEN 1998 AND 2003 THEN '1_新人時代'
      WHEN getYear(release_date) BETWEEN 2004 AND 2008 THEN '2_スター期'
      WHEN getYear(release_date) BETWEEN 2009 AND 2015 THEN '3_充電期間'
      WHEN getYear(release_date) BETWEEN 2016 AND 2020 THEN '4_出産後'
    END AS stage
  , CASE
      WHEN getMonth(release_date) BETWEEN 3 AND 5 THEN '春'
      WHEN getMonth(release_date) BETWEEN 6 AND 8 THEN '夏'
      WHEN getMonth(release_date) BETWEEN 9 AND 11 THEN '秋'
      ELSE '冬'
    END AS season
FROM
  [album_songs.csv]
WHERE
  name <> 'Automatic - Johnny Vicious Remix'
  AND name <> 'HAYATOCHI-REMIX'

アルバム曲とシングル曲を合わせたテーブルの作成

次に「全ての曲の必要データを含むテーブル」を作成しました。

「アルバム収録曲」と「シングル曲」からユニークなnameを洗い出し、そこに重複を含んだ曲をJOINし、必要なカラムのみを取得しました。

その中で気づいてしまったことがあります。

なんと、「シングルでアルバムに含まれている曲」は数値データでアルバム側とシングル側で数値に相違がある!

ということで二つ数値が異なる指標に関しては、足して平均を取ることとしました。

最終的なSQLは以下のようになります。使わなそうなカラムに関してはあえてSELECTしませんでした。

SELECT
    b.name
  , a.stage
  , AVG(a.length_seconds) AS length_seconds
  , ROUND(AVG(a.acousticness),5) AS acousticness
  , ROUND(AVG(a.energy),5) AS energy
  , ROUND(AVG(a.liveness),5) AS liveness
  , ROUND(AVG(a.loudness),5) AS loudness
  , ROUND(AVG(a.popularity),5) AS popularity
  , ROUND(AVG(a.danceability),5) AS danceability
  , ROUND(AVG(a.valence),5) AS valence
FROM (
  SELECT
    *
  FROM
    single_songs
  UNION ALL
  SELECT
    *
  FROM
    album_songs
) a RIGHT JOIN all_songs_list b
ON a.name = b.name
GROUP BY
    b.name
    , a.stage


今回は特にテーブル間をまたいでの分析がないので、リレーションの設定などは行う必要がありません。

さて、準備が整いました!  いよいよダッシュボードを作成して、データを可視化していきましょう!

2.可視化

アルバムごとの動向

まずはアルバムごとの主な指標の動向を見てみましょう。各指標において、アルバムごとの平均を取りました。

アコーステック度

いわゆる生楽器度を表す指標なのですが、キャリアを積むにあたって上昇しているのがわかります。

ダンス度

キャリアを積むにつれて踊れる曲がなくなってきているということですね。初期のアルバムには確かにアップテンポな曲が多くてこちら納得です。

エネルギー度

こちらも同じく、ダンス度と同じく、後のアルバムでは落ちていきますが、落ち方がダンス度よりゆるやかですね。

確かにHEART_STATIONまではアップテンポな曲が多く、「Fantome」からはかなり静かになりました。

曲の長さ(秒)

予想と外れました。キャリアが長くなるにつれて曲も長くなると思っていたのですが、そうでもなさそうです。Spotifyで確認すると、First Love、DEEP_RIVER、ULTRA_BLUE、HEART_STATIONには、1分ほどのInterludeが入っておりました。これを考慮すると、そこまで大差はなく、4分半前後の曲が多いのかもしれませんね。

人気度

なんだこれは!宇多田ヒカルってFirst Loveの時点から人気がすごかったですよね。この感じだと、あくまでも、ストリーミングサービス上の人気なのでしょうか。この指標の決定がどうなされているのかがわからないのですが、

宇多田ヒカルの人気は衰えることがない」という解釈にしておきましょう笑

ポジティブ度

これもまた意外でした。僕の予想では、「ポジティブ度はキャリアとともに上がっていく
」という予想だったのですが、どうやらそうでもないみたいです。確かにDEEP_RIVER, ULTRA_BLUEはメランコリーな曲調が多いですね。First Loveはぶっちぎりのポジティブ度です。

曲調

アルバムごとのメジャー調、マイナー調の曲の割合を表しています。First Loveはメジャーの曲が70%超えですね。この辺はvalence(ポジティブ度)と関連するのかなと思ったのですがどうやらそうでもなさそうです。

シングル曲の動向

次はシングル曲の代表的な指標の動向を見てみましょう。
左が古いシングルで右に行くにつれて新しい曲になり、時系列に並んでいます。

エネルギー度

バラードとアップテンポなチューンを織り交ぜて口語にリリースしていると言ったところでしょうか。この辺はマーケティングも関係しているのでしょうね。全体的にはやや緩やかに下がってきているように見えます。

ダンス度

意外でした。

ダンス度はキャリアと共に下がると思っていたのですが、シングルベースで見るとそうでもなさそうです。アップテンポなチューンをキャリアのどこでもリリースし続けているといったところでしょうか。

曲の長さ(秒)

アルバムと同じく、こちらも初期から最近までとくに大きく変化はなさそうです。キャリアが長くなると、エクスペリメンタルになり曲が長くなるという僕の予想は外れました。

ポジティブ度

ほんのわずかですが、ややゆるやかに下降しているように見えます。「SAKURAドロップス」から「Keep Tryin’」の辺りは落ち込んでますね。「Keep Trying’」っていうポジティブな曲なのに笑

2軸での分析

次にエネルギー度とダンス度を2軸にして散布図を作成しました。キャリアステージ毎に色分けしてあります。

エネルギー x ダンス キャリアステージ毎

新人時代はエネルギー度が高く、ダンス度も高い曲が多いです。スター期は若干両方で下がっています。充電期間にリリースした1曲は両指標とても低いですね。色々あったのでなかなか踊れる曲を作れる状態でもなかったのでしょう。出産後はスター期よりもさらに落ち着いた楽曲を作られているように観察できます。

アルバムの1曲単位の指標マッピング

最後に、アルバム一曲単位で代表的な指標を0.1単位で分割したtierものとヒートマップを作りました。色付けされている数字は曲数で色がこくなると曲数が多くなることを示しています。

ポジティブ度

これを見ると、「First_Love」。「Distance」にはポジティブな曲が多いですね。
その後のアルバムはポジティブ度も下がった曲が多いように見えます。

ダンス度

意外だったのは、「ULTRA BLUE」「HEART STATION」にもダンス度高い楽曲が多いことでした。初期の宇多田ヒカルってR&B色が強いのですが、この辺のアルバムは自分で打ち込みもされてよりエレクトリックな影響を受けている気がします・(僕はULTRA BlUEが一番好きなアルバムなのですが、このアルバムを聴くといつもテクノのUNDERWORLDの曲作りを思い出します)

エネルギー度

ダンス度と似た結果になりましたが、「DEEP RIVER」「ULTRA BLUE」の方がエネルギッシュな曲が初期のアルバム2枚より多いという結果になりました。

アコースティック度

全体的に低いですね。DISTANCEはほとんど0.1より低くなりました。

まぁ打ち込みメインなので妥当でしょう。

3.まとめ

ということで、宇多田ヒカルのSpotifyの音楽データを可視化・分析してみました。

結果的には、意外な発見もありましたが、おおむね予想していたものがプロットされたという印象です。

なお、季節の視点からも分析をしたのですが、特に「ダンス度やエネルギー度が高い楽曲が夏にリリースされる」といった因果関係は宇多田ヒカルさんの場合は見つけられませんでした。

今回は時間の都合上、ここまでしか分析できなかったのですが、また次回時間があるときにぜひより深く分析をしていこうと思います。

それでは!

Viva, Sisense!

この記事が気に入ったら
いいね ! しよう