Treasure Data に蓄積した行動履歴から決定木を使ってユーザの継続要因を調べる
Treasure Data Presto R

Treasure Data に蓄積した行動履歴から決定木を使ってユーザの継続要因を調べる

このエントリーをはてなブックマークに追加

こんにちは、ベガルタ仙台サポーターのCSMです。 本職は (たぶん) サーバ/インフラエンジニアです。

※ CSM: 認定スクラムマスター

私はプリ画像というサービスを運営するコミュニティ事業部にインフラ・運用担当として所属しているのですが、今回はこのプリ画像ユーザの継続要因を決定木分析で調べてみたお話をします。

経緯

部内のチャットツールで下記のような課題が挙がっていました。

  • 施策を考える上で、継続率が高いユーザはなぜ継続率が高いのか知りたい
    • 各アクションの日次件数は取れているが、そのアクションをしたユーザーの継続率の変化を追えてないので追う
    • 何回やれば継続率が高いのか、集計できないか
    • 検索1回だけだと継続率低いけど、5回やれば高い!とかがわかれば、より具体的なアプローチができそう
    • 例) Facebookは初日に友達7人以上と繋がると、その後の継続率がかなり高くなる

よくある課題だと思います。

これまでのうちのチームでの経験だと「集計はしたけどよくわからない」という状態になるところまで含めてありがちな課題でした。

なので、今回はそうならないようにデータマイニングの手法を使い分析してみました。

継続要因アクションと継続ユーザを決める

先ずはじめに分析対象とするユーザアクションと継続ユーザを定義します。

プリ画像ではユーザのアクションを記録したログを Treasure Data に保持しています。 このログに記録されている以下のプリ画像主要アクションを継続要因となるアクションの調査対象としました。

  • 画像検索 (search_image)
  • 画像へのコメント (comment_image)
  • ユーザのフォロー (follow_user)
  • 画像アルバムのフォロー (follow_album)
  • トーク機能への参加 (join_talk)
  • トーク機能でのコメント (comment_talk)
  • 画像投稿 (upload_image)

今回は継続ユーザは会員登録の翌日から7日目までに2回以上プリ画像アプリを起動しているユーザとしました。

Treasure Data からデータを取得

前項の条件を定義したときの継続/非継続ユーザの会員登録日のアクション回数を抽出します。 2016/4/18 に会員登録したユーザで継続と見做せるユーザのアクション回数を抽出する場合、下記のようなクエリでデータを取得します。(Presto で抽出してます)


SELECT
   c.search_image,
   c.comment_image,
   c.follow_user,
   c.follow_album,
   c.join_talk,
   c.comment_talk,
   c.upload_image,
   'YES' AS Continuation
FROM (
   SELECT
      ac.{ユーザID},
      COUNT(CASE WHEN ac.{アクション} = '{画像検索アクション}' THEN 1 ELSE NULL END) AS search_image,
      COUNT(CASE WHEN ac.{アクション} = '{画像へのコメント}' THEN 1 ELSE NULL END) AS comment_image,
      COUNT(CASE WHEN ac.{アクション} = '{ユーザのフォロー}' THEN 1 ELSE NULL END) AS follow_user,
      COUNT(CASE WHEN ac.{アクション} = '{画像アルバムのフォロー}' THEN 1 ELSE NULL END) AS follow_album,
      COUNT(CASE WHEN ac.{アクション} = '{トーク機能への参加}' THEN 1 ELSE NULL END) AS join_talk,
      COUNT(CASE WHEN ac.{アクション} = '{トーク機能でのコメント}' THEN 1 ELSE NULL END) AS comment_talk,
      COUNT(CASE WHEN ac.{アクション} = '{画像投稿}' THEN 1 ELSE NULL END) AS upload_image
   FROM
      {ユーザのアクションが記録されたテーブル} ac
   WHERE
      TD_TIME_RANGE(time,
         '2016-04-18 00:00:00',
         '2016-04-18 23:59:59',
         '+0900')
   GROUP BY ac.{ユーザID} ) c
   JOIN (
      SELECT
         a.{ユーザID}
      FROM (
         SELECT
            ac.{ユーザID},
            COUNT(ac.{アクション}) AS count_launch
         FROM
            {ユーザのアクションが記録されたテーブル} AS ac
         WHERE
            TD_TIME_RANGE(time,
               '2016-04-19 00:00:00',
               '2016-04-25 23:59:59',
               '+0900')
            AND
               ac.{アクション} = '{アプリ起動}'
         GROUP BY ac.{ユーザID}
         ) a
      JOIN (
         SELECT
            ac.{ユーザID}
         FROM
            activity AS ac
         WHERE
            TD_TIME_RANGE(time,
               '2016-04-18 00:00:00',
               '2016-04-18 23:59:59',
               '+0900')
            AND
               ac.{アクション} = '{会員登録完了}'
           ) b
           ON a.{ユーザID} = b.{ユーザID}
      WHERE a.count_launch >= 2 ) d
      ON c.{ユーザID} = d.{ユーザID}

このような感じで非継続ユーザについてもデータを取得し、CSV 形式でダウンロードして適当にマージします。

R で決定木分析

ここからは R を使い取得したデータで決定木分析を実行してみます。 決定木分析に基本パッケージの rpart を、グラフ描画用に partykit を使います。

> install.packages("rpart")
> install.packages("partykit")
> library("rpart")
> library("partykit")

CSV データの読み込み 先に抽出した CSV データを R に読込みます。

> x <- read.table("/PATH/TO/FILE/filename.csv", header=T, sep=",")

とりあえず今回は基本的な操作をやってみようということでデータのクレンジングとか考えずにこのまま分析してみます。

> tree <- rpart(Continuation~., data=x)

こんな感じに結果が出ます。

> tree
n= 4060
node), split, n, loss, yval, (yprob)
      * denotes terminal node

 1) root 4060 1070 NO (0.73645320 0.26354680)  
     2) search_image< 0.5 2363   92 NO (0.96106644 0.03893356) *
     3) search_image>=0.5 1697  719 YES (0.42368886 0.57631114)  
       6) search_image< 10.5 1443  671 YES (0.46500347 0.53499653)  
         12) follow_user< 0.5 1329  651 YES (0.48984199 0.51015801)  
          24) search_image< 3.5 768  353 NO (0.54036458 0.45963542) *
          25) search_image>=3.5 561  236 YES (0.42067736 0.57932264) *
        13) follow_user>=0.5 114   20 YES (0.17543860 0.82456140) *
       7) search_image>=10.5 254   48 YES (0.18897638 0.81102362) *

上記のままではぱっと見で理解しずらいのでグラフを描画します

> plot(as.party(tree))

この結果から、

  • 会員登録した日に画像検索を11回以上しているユーザはアプリ利用を継続してくれる傾向にある
  • また、画像検索が10回以下でもユーザフォローをしているユーザもアプリ利用を継続してくれる傾向にある

とわかります。

以上のように行動履歴からユーザのアクション回数を取得できれば決定木で基本的な結果を得るのはインフラエンジニアの私にも簡単にできました。

この結果を見て単純に「◯◯を何回以上させればよい」というだけでなく、今回の結果で言えば、画像を検索したユーザやユーザフォローをしたユーザはどんな体験ができているのかを考えると打つべき施策のヒントになるのではないでしょうか。


名無しのエンジニア
ES6で始めるjavascriptリファクタ
WWDC 2016現地レポート(Keynote編)