やってみよう分析!第7章: Google Charts Sankey Diagramを使ってデータ可視化

More than 1 year has passed since last update.

はじめに

今回も始まりました。やってみよう分析!シリーズ

前章まではExcelに着目してきましたが、本章ではデータの可視化に注目してみます。特にGoogle Charts Sankey Diagramを取り上げます。 Sankey Diagramは簡単に表すと、人や物等の流量を視覚的に表現した図です。Sankey DiagramはGoogle Charts以外でも描画できるのですが、Javascriptなどに詳しくなくても比較的容易にSankey Diagramを扱えると思われるのがGoogle Charts Sankey Diagramです。

本章で取り扱う項目は以下のものです。

  • Sankey Diagramとは
  • Google Charts Sankey Diagram
  • データ準備例(Excelを使う)

では早速始めましょう!

Sankey Diagramとは

Google Analyticsを使ったことのある方ならばユーザーフローで下記のような図を見たことがあるかもしれません。

fig01.png

例えばGoogle Analyticsでは、ユーザがあるウェブページから別のウェブページにどれくらいの人数が遷移したかを視覚的にフローの方向とフローの太さで表現されています。このように、ある遷移状態を流量とともに表現した図を一般に Sankey Diagramと呼ぶそうです。

Sankey Diagramは本章で紹介するGoogle Charts Sankey Diagram以外にもjavascript libraryD3.jsでも扱うことが可能です。一方で、Google ChartsのSankey Diagramは扱いが簡潔で詳しいjavascriptの知識がなくても使うことが可能です。本章はGoogle Charts Sankey Diagramを紹介します。

Google Charts Sankey Diagram

とりあえず、細かいことは抜きに下記のHTMLをhtml形式でエディタ等に保存して、それをブラウザで開いてみましょう( HTML5が動作する環境で実行してください)。

<html>
<head>
<script type="text/javascript"
  src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['sankey']}]}">
</script>

<div id="sankey_basic" style="width: 900px; height: 300px;"></div>

<script type="text/javascript">
   google.setOnLoadCallback(drawChart);

   function drawChart() {
    var data = new google.visualization.DataTable();
    data.addColumn('string', 'From');
    data.addColumn('string', 'To');
    data.addColumn('number', 'Weight');
    data.addRows([
        [ 's' , 'a', 5 ],
        [ 's' , 'b', 3 ],
        [ 's' , 'c', 2 ],
        [ 'a' , 'd', 2 ],
        [ 'a' , 'e', 5 ],
        [ 'b' , 'd', 1 ],
        [ 'c' , 'e', 1 ],
        [ 'c' , 'd', 1 ],
    ]);

    // Set chart options
    var options = {
      width: 500,
      sankey:   { node: { nodePadding: 80, 
                        label : {   fontName: 'Times-Roman',
                                    fontSize: 14,
                                    color: '#871b47',
                                    bold: true,
                                    italic: true } } },
    };
    // Instantiate and draw our chart, passing in some options.
    var chart = new google.visualization.Sankey(document.getElementById('sankey_basic'));
    chart.draw(data, options);
   }
</script>
</head>
</html>

うまく動作すれば、本記事最上部の図が出力されるはずです。
以下、上記HTMLの意味を解説していきたいと思います(最低限のHTMLの使い方は理解しているとします)。

基本の枠をhtmlファイルに用意する

最低限のhtmlファイル構成として次のものを準備します。

<html>
<head>

</head>
</html>

このheadタグの中にGoogle Charts APIの呼び出しなどの命令を記述していきます。

google charts apiのSankey Diagramを呼び出す

Sankey Diagramを呼び出すために下記のscriptを挿入します。これは呼び出すための決まった命令文です。

<script type="text/javascript"
  src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['sankey']}]}">
</script>

フローを描画する領域を準備

ブラウザ上にSankey Diagramを表示するための領域をdiv要素で準備します。

<div id="sankey_basic" style="width: 900px; height: 300px;"></div>

scriptタグ内にSankey Diagramを描画する命令を書いていく

scriptタグを準備して、直下にsetOnLoadCallbackメソッドでページが読み込まれた時にdrawChart関数(以下で定義される)が呼び出されるようにする。

<script type="text/javascript">
   google.setOnLoadCallback(drawChart);

次に呼び出されるdrawChart()関数を定義します。

   function drawChart() {
    var data = new google.visualization.DataTable();
    data.addColumn('string', 'From');
    data.addColumn('string', 'To');
    data.addColumn('number', 'Weight');
    data.addRows([
        [ 's' , 'a', 5 ],
        [ 's' , 'b', 3 ],
        [ 's' , 'c', 2 ],
        [ 'a' , 'd', 2 ],
        [ 'a' , 'e', 5 ],
        [ 'b' , 'd', 1 ],
        [ 'c' , 'e', 1 ],
        [ 'c' , 'd', 1 ],
    ]);

    // Set chart options
    var options = {
      width: 500,
      sankey:   { node: { nodePadding: 80, 
                        label : {   fontName: 'Times-Roman',
                                    fontSize: 14,
                                    color: '#871b47',
                                    bold: true,
                                    italic: true } } },
    };
    // Instantiate and draw our chart, passing in some options.
    var chart = new google.visualization.Sankey(document.getElementById('sankey_basic'));
    chart.draw(data, options);
   }

この関数が実行している命令を書き出すと次のようになります。

  • data変数にフローを描画するためのデータを格納するテーブル(オブジェクト)を代入します。
  • dataオブジェクトのaddColumnメソッドでカラムのデータ型とデータ種類をdata.addColumn(データ型, データ種類)のように定義します。
  • データ種類は始点'From'、終点'To'、フローの幅'Weight'で指定します。
  • ノード始点を('string', 'From')、ノード終点を('string', 'To')、フローの太さを('number', 'Weight')でテーブルに指定。
  • addRowsメソッドでデータを挿入。 多次元配列(ここでは行数×3列の配列)を渡します
  • 列はadColumnメソッドで定義したように左からノード始点(From)、終点(To)、フローの太さ(Weight)とデータが並んでいます。
  • option変数に表示オプションを記憶させる。widthは画面表示された時の図の幅を指定しています。
  • sankeyオプションは省略可能。ここではノードのラベルフォントや広がりを指定しています。
  • ここまではSankey Diagramに入力するデータとオプションの準備。
  • id="sankey_basic"のdiv要素を見つけ、そこにSankey Diagramを表示することをchart変数に覚えさせます。
  • chartのdrawメソッドで、data, optionを引数に渡してフローを表示。

最後に</script>でscriptタグを閉じます。

データ準備例(Excelを使う)

実際にGoogle Charts Sankey Diagramを使った感じですと、データを挿入するaddRowsメソッドに渡している配列の部分以外はほとんど固定です(オプションも頻繁には変更しないと思われます)。言い換えればaddRowsメソッドの配列部分を用意する処理を何らかの方法で準備できれば、Sankey Diagramが簡単に出力されます。このためHTMLやJavaScriptに詳しくない方でもSankey Diagramを描画させることができると思います。

ここで非常に簡単なデータを使ってSankey Diagram用のデータをExcelで作ってみます。使うテストデータは下記のものです。

uu seq To flag
uu1 0 a 1
uu1 1 a 1
uu1 2 a 1
uu1 3 a 1
uu1 4 b 1
uu2 0 b 1
uu2 1 a 1
uu2 2 b 1
uu2 3 b 1
uu2 4 b 1
uu3 0 b 1
uu3 1 a 1
uu3 2 b 1
uu3 3 a 1
uu3 4 b 1
uu4 0 b 1
uu4 1 b 1
uu4 2 a 1
uu4 3 b 1
uu4 4 b 1
uu5 0 b 1
uu5 1 b 1
uu5 2 a 1
uu5 3 a 1
uu5 4 a 1

このデータは5人のユーザuu1からuu5が2つのクリエイティブ(バナー広告)a, bを見たデータを時系列で並べたものと仮定しています。見た状態をflag=1で表しています。このデータからabのクリエイティブを見たユーザ数が時間とともにどのように推移しているかsankey diagramで可視化してみましょう。

まず上記のデータを下記の図のようにExcelに貼り付けます。

fig03.png

セルD1Fromラベルを記入。セルD3=IF(A2=A3,C2,IF(B3=0,"",C3))と数式を挿入してセルD26までコピーペーストします。この処理はD列に1つ前に見たToのクリエイティブをラベリングするためのものです。これによってseq>0の行に対してユーザごと1区間あたり始点から終点への遷移状態を表すことができます(例えばuu1aを見てaを見たというイベントが1回発生ということがわかります)。seqごとにflagの数をカウントすることでevent(t-1) ==> event(t)のペアが何回起きたか集計できます。この数値をsankey diagramに表示することができれば、ユーザフローを可視化することができます。これを実行するために、上記のデータを更にpivotで集計してみます。

fig04.png

セルA1からセルE26を選択してpivotします。ここでは便宜上、同一セル上にピボットテーブルを表示しました。 行にはseq, From, Toの順に上からフィールドを設定します (順番に注意してください)。∑値にはflagの合計を設定します。更にFromToにフィルターを掛けて空白とラベルなしのもののチェックを外します。これによって下記のようなテーブルが表示されます。

fig05.png

ピボット領域のセルH2からセルK14までを選択してセルH18から貼付けします。seqFromの列の空白は空白から上にさかのぼって空白ではないセルのラベルをコピーペーストします。

fig06.png

つぎにセルM18=$H18&"_"&I18をセルN18=($H18+1)&"_"&J18を入力します。入力したら数式をそれぞれセルM30, N30までコピーペーストします。

fig07.png

最後にセルP18=CONCATENATE("[","'",M18,"'",",","'",N18,"'",",",K18,"]",",")と入力し、セルP30までコピーペーストします。

fig08.png

上記で出来たデータをHTMLサンプルのaddRowsメソッドに下図のようにコピーして挿入します。

fig11.png

これを保存してブラウザで表示すると下図のようなSankey Diagramが表示されます。

fig02.png

この例では2つのクリエイティブa, bを扱いました。しかしフローを描くときのラベルには1_aのように先頭に 何回目の閲覧なのか明確化させていましたこれは、Google Charts Sankey Diagramのページによると、下記のようにサイクリックなラべリングではうまく図が表示されないからです
Avoid cycles in your data: if A links to itself, or links to B which links to C which links to A, your chart will not render.

addRowsメソッドに同時挿入可能な行数

厳密に調査していませんが、自分が挿入可能なデータ行数を調べてみたところ、どうやらaddRowsメソッドに 800行程度以上データを挿入しようとするとGoogle Charts Sakey Diagramが表示されなくなるようでした。

まとめ

本章ではGoogle Charts Sankey Diagramを紹介してきました。Sankey Diagramを使うと人や物の流量を視覚的に表示することが可能です。Google Charts Snakey Diagramは扱えるデータに上限があるものの、記述するスクリプトの量も少なく使い方も簡単で、定められた形式にデータを加工するとすぐにSankey Diagramを表示させれることが魅力でした。データを上手く要約することでちょっとしたユーザ行動ログの可視化なんかに使えそうです。ここで紹介したデータ下処理をExcelではなく別の言語で処理して自動化してみるなんてのも応用の可能性が広がりそうですね。皆さん、ぜひいろいろ試してみてください!

===========================================

こちらもよろしくおねがいいたします。

入門編

第1部イントロダクション

第2部エクセルで学ぶ分析入門

==================

お知らせ:Fringe81エンジニアチームでは仲間を募集しています!

 

 チームの雰囲気や採用情報については下記ページをご覧下さい。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.