Technically Impossible

Lets look at the weak link in your statement. Anything "Technically Impossible" basically means we haven't figured out how yet.

RでのiTunesデータの集計、ワードクラウドによる視覚化

f:id:espio999:20201203222556p:plain
新型コロナウイルスの流行により春学期のコースは途中からオンライン対応となり、夏学期、秋学期に希望したコースは、希望者不足のため開講されず、今年の学生活動は非常に物足りないものとなった。

春学期の思い出と言えば、データ分析のクラスでの中間提出物が大変に高評価だったことだ。主題に関する背景に乏しい受講者の多いクラスだったため、まさかRでの成果物が提出されるとは、講師は期待していなかったのだろう。加えて、データ集計作業がシンプルでありながら、その過程はデータ分析の要所を抑えながら追体験でき、ワードクラウドも見た目にアピールするプレゼン要素になる。

この投稿では、その一連の作業過程を紹介する。作業環境はWindowsを前提としており、集計の前処理にExcelを用いる。

構想

データ分析、集計結果を表やグラフの形態で提示するのは、データから読み取れる事実を飾ることなく抽出、提示できる方法ではあるものの、あらゆるデータに適した提示形態であるとは言えない。例えば、自己紹介的に好みの音楽を第三者に伝える場面だ。
典型例は、好きなアーティストや楽曲名を提示するのだが、それで当人の好みは十分に伝わるだろうか?それは特徴的な事実の一部を伝えているにすぎない。よく聴くジャンルやアーティスト、アルバムなどを網羅的に伝えることで、好みについて直接的には語れない傾向や背景などの情報を言外に包含しながら、当人の好みに関する漠然とした全体像を提示することができるはずだ。そして、そのような伝達の表現手段としてワードクラウドはとても有効に機能する。

計画

iTunesからジャンル、アーティスト、アルバム、楽曲ごとの再生回数を集計し、音楽的な好みをワードクラウドとして提示する。

データ取得

iTunesから目的のデータを取得するには、まず楽曲ごとにリスト表示する。行頭のカラムを右クリックし、コンテキスト・メニューから必要な情報を取捨選択する。
f:id:espio999:20201203222331p:plain

今回の場合、必要とされる最低限の情報は次の項目だ。

Genre ジャンル
Artist アーティスト名
Album アルバム名
Name 楽曲名
Plays 楽曲の再生回数

取捨選択したら、「Ctrl+A」でリストを全選択し、「Ctrl+c」でコピーする。そしてExcelで「Ctrl+V」で貼りつける。このExcelファイルを集計データのマスターデータとする。

集計の前準備:データ・クレンジング

まずデータを直接編集するので、元データのタブをマスターとし、新たに編集用のタブを用意して、データをコピーする。あるいはマスターと編集用を別ファイルにしておくと良い。
集計を始める前に、取得したデータを適した状態に編集しなければならない。今回の場合では、次のような問題に対処する必要がある。

同一のアーティスト名について、ある楽曲では日本語表記、またある楽曲では他国語表記されている場合がある。もしくは、ある楽曲では略称、またある楽曲では正式名称で登録されている場合もある。次のような具合だ。

坂本龍一 Ryuichi Sakamoto
Bjork Björk
YMO Yellow Magic Orchestra

さらには、いわゆるタイポであったり、冠詞(The)の有無によって、異なるアーティスト名として集計される場合もある。正しく集計するために、必要なものはExcelの置換機能などを用いて統一しておく。

また集計対象外とする楽曲が含まれているならば、そのデータは予め削除しておく必要がある。例えば、例えば語学学習コンテンツやpodcastingなどだ。

集計

集計は各項目のレコード毎に再生回数を合算する、いわゆる"group by"集計だ。これはパイプ処理で実現できる。そして、集計データを元にワードクラウドを生成する。ここでは次のライブラリを使用する。

readxl Excelを読み込み、DataFrameにする。
dplyr パイプ処理
wordcloud2 ワードクラウドの生成
htmlwidgets HTML出力

例えばExcelを読み込み、ジャンルについて集計するとしよう。その手順は次のようになる。

  1. Excelを読み込み、DataFrameに格納する。
  2. DataFrameから、ジャンルと再生回数を抽出し、新たなDataFrameへ格納する。
  3. ジャンルのDataFrameで、ジャンル名毎にGroup-by集計する。
  4. ジャンルのDataFrame内のデータを降順ソートする。
  5. ジャンルのDataFrameから、先頭10行(最も再生回数の多い10ジャンル)を表示する。
  6. ワードクラウドを生成する。
  7. ワードクラウドを描画するためのCSS、JSファイルを含むフォルダと合わせて、一式のファイルを出力する。

コードは次のようになる。

R code

library(readxl)
library(dplyr)
library(wordcloud2)
library(htmlwidgets)

mydata = read_excel("C:/user/document/Temple University/DTA101/week05/itunes.xlsx", sheet = "cleaned")

mygenre = data.frame(genre = mydata$genre, plays = mydata$plays)
mygenre = mygenre %>% group_by(genre) %>% summarise(plays = sum(plays))
mygenre = mygenre[order(mygenre$plays, decreasing = TRUE),]

head(mygenre, 10)
wc1 = wordcloud2(mygenre, size = 0.8, shuffle = FALSE)
saveWidget(wc1, "wc1.html" ,selfcontained = FALSE)


アーティスト、アルバム、楽曲の集計も、新たなDataFrameを定義し、抽出項目を適切に変更することで、同様のコードで対応できる。

ワードクラウドJavaScriptによって描画される。どうやら一つのHTMLに対して、複数のワードクラウドを描画できない仕様のようだ。単一のHTMLにつき、一つのワードクラウド、ということだ。
1画面で複数のワードクラウドを描画するには、ワードクラウドごとに個別にHTMLを生成し、別のHTMLに記述したiframeを通じて、それらを個別に呼び出すような工夫が必要だ。
そのためアーティスト、アルバム、楽曲毎のワードクラウドを描画するファイル一式も個別に出力することになる。

プレゼン

従来型のデータ表示とワードクラウドによる視覚化を対比することで、与える印象、理解度の違いを提示したい。そのためプレゼン用に次のHTMLを用意した。これをindex.htmlとして保存している。
左側のペインにはRStudioから出力したノートブックhtmlを表示する。ここには典型的なサマリー情報を表示する。具体的には、各項目ごとに最も再生された10レコードを表示する。
右側のペインには、各項目ごとのワードクラウドを縦1列に並べる。

index.html

<html>
<head>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="parent">
    <div class="left-cell">
      <iframe height=100% width=100% src="wordcloud2.nb.html"></iframe>
    </div>
    <div class="right-cell">
      <iframe height=25% width=100% src="wc1.html"></iframe>
      <iframe height=25% width=100% src="wc2.html"></iframe>
      <iframe height=25% width=100% src="wc3.html"></iframe>
      <iframe height=25% width=100% src="wc4.html"></iframe>
    </div>
  </div>
</body>
</html>


どのように表示されるか、次のURLを参照してみてほしい。ちなみに次の特徴に注意してほしい。

  • ワードクラウドは参照の度に再描画され、その表現は描画ごとに異なる。
  • 最も再生回数のレコードが枠からはみ出す場合、描画されない。
    • 例えばジャンルで最も再生回数の多いレコードは"Soundtrack"なのだが、描画されないことが多い。

Word cloud from my iTunes library - DTA101 midterm assignment