$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
「国と音楽」 ~spotifyrを用いて~ #muana
Search
bob3bob3
October 28, 2023
Science
2
490
「国と音楽」 ~spotifyrを用いて~ #muana
SpotifyのWebAPIから取得できるデータを使い、国ごとに流行っている曲の傾向やグループ分けを行ってみた。
#muana #R言語 #rstats
bob3bob3
October 28, 2023
Tweet
Share
More Decks by bob3bob3
See All by bob3bob3
RでPSM分析
bob3bob3
1
190
Rでコンジョイント分析 2024年版
bob3bob3
0
820
『改訂新版前処理大全』の話と Apache Parquet の話 #TokyoR
bob3bob3
0
700
R言語の環境構築と基礎 Tokyo.R 112
bob3bob3
0
470
『データ可視化学入門』をPythonからRに翻訳した話(増強版)
bob3bob3
0
420
『データ可視化学入門』を PythonからRに翻訳した話
bob3bob3
1
500
qeMLパッケージの紹介
bob3bob3
0
1.6k
パーマーステーションのペンギンたち#3 探索的データ分析(EDA)編
bob3bob3
1
600
Redditで遊ぼう #TokyoR 106
bob3bob3
0
660
Other Decks in Science
See All in Science
インフラだけではない MLOps の話 @事例でわかるMLOps 機械学習の成果をスケールさせる処方箋 発売記念
icoxfog417
2
600
All-in-One Bioinformatics Platform Realized with Snowflake ~ From In Silico Drug Discovery, Disease Variant Analysis, to Single-Cell RNA-seq
ktatsuya
0
240
ABEMAの効果検証事例〜効果の異質性を考える〜
s1ok69oo
4
2.1k
240510 COGNAC LabChat
kazh
0
140
DEIM2024 チュートリアル ~AWSで生成AIのRAGを使ったチャットボットを作ってみよう~
yamahiro
3
1.3k
機械学習による確率推定とカリブレーション/probabilistic-calibration-on-classification-model
ktgrstsh
2
260
ベイズ最適化をゼロから
brainpadpr
2
840
How were Quaternion discovered
kinakomoti321
2
1.1k
大規模画像テキストデータのフィルタリング手法の紹介
lyakaap
7
1.6k
理論計算機科学における 数学の応用: 擬似ランダムネス
nobushimi
1
350
ウェーブレットおきもち講座
aikiriao
1
790
Science of Scienceおよび科学計量学に関する研究論文の俯瞰可視化_LT版
hayataka88
0
940
Featured
See All Featured
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
Imperfection Machines: The Place of Print at Facebook
scottboms
266
13k
Happy Clients
brianwarren
98
6.7k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
365
24k
Navigating Team Friction
lara
183
15k
The Language of Interfaces
destraynor
154
24k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.2k
Producing Creativity
orderedlist
PRO
341
39k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
[RailsConf 2023] Rails as a piece of cake
palkan
52
5k
Code Reviewing Like a Champion
maltzj
520
39k
Transcript
音楽と国 ~spotifyrを用いて~ Music×Analytics Meetup Vol.11 (2023/10/28) @bob3bob3
Spotify
Spotifyとは? Spotify(スポティファイ)は、スウェーデンの 企業スポティファイ・テクノロジーによって運 営されている音楽ストリーミングサービス。 (Wikipediaより引用)
spotifyr • R言語のspotifyrパッケージを使って、SpotifyのWeb APIから楽曲や アルバム、アーティストなどの情報を一括で取得。 • spotifyrで取得できる情報の一例 ◦ アルバム単位 ▪
ジャケット画像、曲数、アルバム名、リリース日、人気度など ◦ アーティスト単位 ▪ ジャンル、関連するアーティスト、人気度など ◦ 楽曲単位 ▪ アコースティック度、ダンス度、インスト度、音圧、テンポ、キー、人気度な ど ◦ 詳しくはspotifyのwebAPIのページを参照のこと。
プレイリスト • Spotifyにはプレイリストという機能が あります。好きな曲をまとめて公開す る機能です。 • Spotify公式のプレイリストもあって、 例えば各国のTop50がプレイリストと して公開されていたりします。 •
これもspotifyrで扱えて、プレイリスト ごとに含まれる楽曲のデータなどを抽 出できます。
やってみよう! • 「各国のTop50のプレイリストから、 含まれる楽曲を抽出し、各楽曲の 特徴を用いて各国をクラスタリング する。」というのをやってみます。 • 事前準備としてSpotifyのアカウント と開発者アカウントの登録が必要で す。
• 2023年07月14日時点のデータで す。
# パッケージ読み込み library(conflicted) #関数の衝突防止 library(tidyverse) #モダンなデータ処理 library(spotifyr) #Spotifyの Web API
操作 # 開発者アカウント認証 Sys.setenv(SPOTIFY_CLIENT_ID = 'xxxxxxxxxx') Sys.setenv(SPOTIFY_CLIENT_SECRET = 'xxxxxxxxxx') access_token <- get_spotify_access_token() 準備
# プレイリスト検索 res_search <- search_spotify( q = 'top50', type =
'playlist', limit = 50 ) |> dplyr::filter(owner.id == "spotify") |> #公式プレイリストに絞る select(name, id) |> #列を絞る mutate(name = name |> str_remove("Top 50 - ")) |> #プレイリスト名の整形 dplyr::filter( #ノイズになる行を削除 !(name %in% c("Global", "Greatest Hip-Hop Beats of All Time")) ) |> rowid_to_column() #ID番号を振る Top50のプレイリストを検索
検索結果 国名とプレイリストの id。
playlists_tracks <- res_search |> pull(id) |> map( #各プレイリストに含まれる楽曲を抽出 \(id) get_playlist_tracks(id)
|> select(track.id, track.name), .progress = TRUE ) |> list_rbind(names_to = "rowid") Top50のプレイリストから各楽曲のIDを検索
プレイリストに含まれる楽曲のリスト
各楽曲の分析情報を取得 res_track <- playlists_tracks |> pull(track.id) |> unique() |> map(
\(track.id) get_track_audio_features(track.id), .progress = TRUE ) |> list_rbind() |> right_join( playlists_tracks |> left_join(res_search, by = join_by(rowid)), by = join_by(id == track.id) ) |> mutate( duration_s = duration_ms / 1000, # ミリ秒を秒に country = as.factor(name) ) |> select( country, duration_s, energy, acousticness, liveness, speechiness, valence, danceability, tempo, id, track.name)
各楽曲の分析情報を取得
各楽曲の分析情報を取得 • duration_ms: 曲の長さ(ミリ秒) • energy: 0~1。騒がしい曲か静かな曲か。 • acousticness: アコースティック度合。電気的に増幅されている程度。
• liveness: 0~1。ライブ音源かスタジオ音源か。 • speechiness: 0~1。歌ではない話し言葉の量。 • valence: 0~1。ポジティブさ。 • danceability: 0~1。踊りやすさ。 • tempo: テンポ(BPM)。
各楽曲の分析情報
分析情報に関する発表事例
EDA library(summarytools) res_track |> select(!c(country, id, track.name)) |> dfSummary() |>
summarytools::view()
EDA library(GGally) res_track |> select(!c(country, id, track.name)) |> ggpairs(aes(alpha =
0.1))
国ごとの違い res_track2 |> ggplot( aes( x = reorder( country, duration_s,
FUN = median), y = duration_s)) + geom_boxplot() + coord_flip() + labs(x = "国", y = "演奏時間(秒)") + theme(text = element_text(size = 12))
クラスタリングしよう! # 国ごとに中央値を算出し、さらに標準化する median_by_country <- res_track |> select(!c(id, track.name)) |>
group_by(country, .drop = FALSE) |> summarise(across(everything(), median)) |> column_to_rownames(var = "country") |> scale() # 階層型クラスタリング library(factoextra) library(dendextend) cluster_tree <- median_by_country |> dist() |> hclust(method = "ward.D2") cluster_tree |> fviz_dend( k=6, cex=0.5, horiz = TRUE, label_cols = "black", k_colors = c( "#ff4b00", "#990099", "#03af7a", "#005aff", "#804000", "#ff8082"), rect = TRUE, rect_fill = TRUE, rect_border = 8 )
地図! clusters <- tibble( country = median_by_country |> rownames(), cluster
= cluster_tree |> cutree(k=6) ) library(ggrepel) library(sf) library(rnaturalearth) world_map <- ne_countries( scale = "small", returnclass = "sf" ) |> left_join( clusters |> mutate( country = country |> str_replace("USA", "United States") |> str_replace("South Korea", "Republic of Korea") ), by=join_by(name_long == country) ) world_map |> ggplot() + geom_sf(aes(fill = as.factor(cluster))) + theme_light() + labs(fill = "cluster") + scale_colour_brewer(palette = "Dark2")
None
Enjoy! 次回「2010年代 King Crimson のセットリスト分析」でお会いしま しょう!