TreasureDataとgraphvizでパス分析(ダイアグラムを出力する)


本家で紹介されている記事に沿ってやる(終了)

  • アクセスログ分析最前線:Treasure Data JavaScript SDK で始めるパス分析 その3
    • この記事、1〜3までありますが、1は手法の紹介、2はTD上のクエリ実行、3がダイアグラム化という感じの構成です
    • ただ、3で実際に利用してるデータは2で作ったものじゃなく、3で新たに発行したものなので、正直3だけでも良さそうですw
  • 今回は、上記に沿ってやったことを自分の中でフロー化するためのまとめです

 やり方

1. データ準備

まず、クエリを作るための分析用データを準備します

大事なのは決まったカラムを出力すること。これだけ。
カラム名は任意です。以後のコマンドも変更してもらえれば動きます。

  • データ内容
    • 分析対象にしたいアクセスログ
  • 必須カラム

    • user_id:ユーザを一意に特定するもの
    • td_url:アクセスURL

      • パラメータ付与されている場合は事前に整形しておいてください
      • URLと言ってますがパスが良ければpath使ってください
      • 整形例:

        • いろんなところにリンク貼られてたりすると/がついてるかついてないかが違う
        • パス作る人によっては大文字小文字が別
        • 実際に解析するときにエンコードされてるとなんのページかわからない
        SELECT URL_DECODE(LOWER(TRIM(td_url, '/'))) as td_format_url
        FROM access_log
        
    • time:アクセス日時

必須カラム以外はあってもなくてもダイアグラム抽出には不要ですので、
別途分析したい場合はご自由に追加どうぞ

2. クエリを作成する

上記データを整形する
クエリフォーマットは以下の通り
(本家記事にもありますのでそっちから取ってきてください)

-- 先月の訪問ユーザのパス分析
SELECT td_format_url_from, td_format_url_to, COUNT(1) AS cnt
FROM (
    SELECT td_format_url AS td_format_url_from,
      LEAD(td_format_url) OVER( PARTITION BY unique_id ORDER BY td_pageviews_time ) AS td_format_url_to
    from (

    --      
    -- ここに上記で準備したデータがSELECTされるようにする 
    -- 

    )pas_all
)pas_format
GROUP BY
  td_format_url_from, td_format_url_to
HAVING ( td_format_url_from IS NOT NULL AND td_format_url_to IS NOT NULL )
ORDER BY cnt DESC
LIMIT 50 -- 出力したい矢印の量だけ設定すれば良い。多すぎるとカオスになるので注意

このクエリを実行して、結果を保存します。
ファイル名はdata.csvとします。

3. ダイアグラムにする

graphvizは導入しておいてください。
作業ディレクトリに先程のdata.csvを入れておきます。

#こっからは自分用。作業しやすいように
$ ls your/path
data.csv

#dotファイルに起こす
$ mgv.rb ei=data.csv ef=td_format_url_from,td_format_url_to ev=cnt -el -d o=result_transition.dot

#dotファイルを整形(後述)
$ vim result_transition.dot

#ダイアグラム出力
$ dot -Tpng result_transition.dot > result_transition.png

基本的な流れは上記の通りです。

<補足>ダイアグラムの整形

実際図にしてみると見辛かったりするので、その場合の回避策

上から下の図を左から右に変える

rankdir=LRを追加する

digraph G {

rankdir=LR;  #これを追加する

n0 [label="https://domain/aaa" height=0.5 width=0.75] 
n1 [label="https://domain/bbb" height=0.5 width=0.75] 
・・・

ノードを小さくする

上記のlabel="https://aaa"の文字列を短くすればノードも広がらなくなります。
よくやる方法としては、https://domain/などのドメインを除いたりするとすっきり。

数値を小数にしない

label="51.0"などの.0を一律削除(オプションでできそう)

・・・
n0 -> n1 [style="setlinewidth(10.0)",label="51.0"]
n2 -> n2 [style="setlinewidth(7.8936170212765955)",label="40.0"]
n2 -> n0 [style="setlinewidth(5.404255319148936)",label="27.0"]
・・・