SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ビジネスデータ解析のためのSQL入門

ユーザーによるアプリケーション機能利用分析ですぐに使えるSQL

ビジネスデータ解析のためのSQL入門 第6回

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

ユーザーによる機能利用状況を分析する

 アプリケーションではサービス内で複数の機能を提供していますが、全ての機能を全てのユーザーが利用しているわけではありません。

 例えば、

  • それぞれの機能をどのくらいのユーザーが使っているのか?
  • 特定の機能を使っていないユーザーはどのくらいか?

といった分析ができれば、機能やナビゲーションといったUI改善の有効な材料にすることができます。

 そのためには各種機能の利用状況を調べ、提供している機能がユーザーに受け入れられているのかどうか、想定してる通りに使ってもらえているのかなどを確認する必要があります。

 本稿では例としてストア型のアプリケーションでよく使われる「tagging(タグ付け:リスト追加や分類など)」「purchase(購入)」「review(レビュー投稿)」という3つの機能に対するユーザー行動を分析する場合について考えます。

 2つや3つの複数の機能をまたがって利用している(または利用していない)ユーザー数や構成比を把握するため、3つの機能の利用有無をクロス集計します。

 ここでは例えばタグ付けを行ったユーザーは「tagging」、行っていないユーザーは「not tagging」、いずれも含める場合は「all」としています。

 また「user_count」ではそれぞれのユーザー数、「ratio」では該当ユーザー数の全体に対する比(構成比)を示します。

 欲しい結果は以下のようになります。

 done_tagging | done_purchase | done_review | user_count | ratio
--------------+---------------+-------------+------------+--------
 all          | all           | all         |          4 | 100.00
 all          | all           | not review  |          1 |  25.00
 all          | all           | review      |          3 |  75.00
 all          | not purchase  | all         |          2 |  50.00
 all          | not purchase  | not review  |          1 |  25.00
 all          | not purchase  | review      |          1 |  25.00
 all          | purchase      | all         |          2 |  50.00
 all          | purchase      | review      |          2 |  50.00
 not tagging  | all           | all         |          1 |  25.00
 not tagging  | all           | review      |          1 |  25.00
 not tagging  | not purchase  | all         |          1 |  25.00
 not tagging  | not purchase  | review      |          1 |  25.00
 tagging      | all           | all         |          3 |  75.00
 tagging      | all           | not review  |          1 |  25.00
 tagging      | all           | review      |          2 |  50.00
 tagging      | not purchase  | all         |          1 |  25.00
 tagging      | not purchase  | not review  |          1 |  25.00
 tagging      | purchase      | all         |          2 |  50.00
 tagging      | purchase      | review      |          2 |  50.00

 この結果を得るためのSQLは以下の通りです。

リスト3 複数機能に対するユーザー行動集計(user_action_diaglam.sql)
with/* (1) */
user_action as (/* (2) */
    select
        user_id
        ,sign(sum(/* (2)-(b) */
            case when action_category = 'tagging' then 1 else 0 end/* (2)-(a) */
        )) as has_tagging
        ,sign(sum(
            case when action_category = 'purchase' then 1 else 0 end
        )) as has_purchase
        ,sign(sum(
            case when action_category = 'review' then 1 else 0 end
        )) as has_review
    from
        action_history
    group by user_id order by user_id
)
,action_diaglam as (/* (3) */
    select
        has_tagging
        ,has_purchase
        ,has_review
        ,count(*) as user_count
    from
        user_action
    group by cube(has_tagging, has_purchase, has_review)
)
select/* (4) */
    case has_tagging/* (4)-(a) */
        when 1 then 'tagging' when 0 then 'not tagging' else 'all'
    end as done_tagging
    ,
    case has_purchase
        when 1 then 'purchase' when 0 then 'not purchase' else 'all'
    end as done_purchase
    ,
    case has_review
        when 1 then 'review' when 0 then 'not review' else 'all'
    end as done_review
    ,user_count
    ,round(
        100.0 * user_count / nullif(/* (4)-(c) */
            sum(case when has_tagging is null/* (4)-(b) */
                    and has_purchase is null
                    and has_review is null
                    then user_count else 0
                end) over ()
            ,0)
        ,2)
    as ratio
from action_diaglam
order by done_tagging, done_purchase, done_review
;

(1)With句

 With句はサブクエリに名前を付け、SQLの中ではなく前に記述します。ここではサブクエリをWith句によりuser_actionと名付けています。サブクエリをSQLの中で記述する場合に比べ、視認性を高めることができます。以下のように記述します。

WITH
  <クエリ名> AS ( select <列>  ~ )

(2)ユーザーごとのアクション有無

 サブクエリの中では、まずユーザー単位でログを集約します。「tagging」「purchase」「review」の3つのアクションを行ったログが存在するかどうかを、0と1のフラグで付与します。

 このサブクエリによる結果テーブルは以下の通りです。

 user_id  | has_tagging | has_purchase | has_review
----------+-------------+--------------+------------
 UID0001  |           1 |            1 |          1
 UID0002  |           0 |            0 |          1
 UID0003  |           1 |            1 |          1
 UID0004  |           1 |            0 |          0

 このコード例の出力結果の「has_tagging」「has_purchase」「has_review」カラムにおいて、それぞれタグ付け、購入、レビューの各アクションを一度でも実行したとがある場合は1、一度も実行していない場合は0となります。

(2)-(a)case式による行動有無の判定

 case式の構文は2種類あり、WHENのあとに値のみ記述する構文(単純case式)と、「<項目> = <値1>」のように比較演算が利用可能な構文(検索case式)があります。この箇所では検索case式の構文を利用しています。ここではaction_categoryの判定内容に応じて該当するユーザーの行動回数を加算することで、行動の有無を判定します。

[構文]検索case式(比較演算子は"="のほか不等号などが使用可能)
case WHEN <項目> = <値1>  THEN  <値4>
      WHEN <項目> = <値2>  THEN  <値5>
 ELSE  <値3>  END

 単純case式は後述の(4)-(a)の部分で利用しているので参照してください。

(2)-(b)sign関数

 signは引数の符号を返す関数です。以下のように記述します。

sign(expr)

 戻り値は符号としては [ -1 | 0 | +1 ] またはNULLを返します。

expr < 0 ... -1
expr = 0 ... 0
expr > 0 ... +1
expr IS NULL ... NULL

 このsign関数により行動回数のような正の整数は丸められて1になるため、行動回数ではなく行動有無を表すフラグとして利用できます。

(3)全てのアクションの組み合わせの集計

 このサブクエリでは3つの機能の組み合わせの利用(アクション)を集計します。

 (2)の結果からアクション別に集約するだけでは、複数の機能をまたがって利用しているユーザー数や構成比を知ることができません。例えば「購入とレビューを行ったユーザー数」など、2つ(または3つ)のアクションの組み合わせに対するユーザー数が必要です。

 標準SQLに定義されていてPostgreSQL9.5以降でサポートされているCUBE関数を用いると、利用した機能の組み合わせの集計を比較的簡単に実現できます。

 このサブクエリによる結果のテーブルは以下の通りです。

 has_tagging | has_purchase | has_review | user_count
-------------+--------------+------------+------------
           0 |            0 |          1 |          1
           0 |            0 |            |          1
           0 |              |            |          1
           1 |            0 |          0 |          1
           1 |            0 |            |          1
           1 |            1 |          1 |          2
           1 |            1 |            |          2
           1 |              |            |          3
             |              |            |          4
           1 |              |          0 |          1
             |              |          0 |          1
           0 |              |          1 |          1
           1 |              |          1 |          2
             |              |          1 |          3
             |            0 |          0 |          1
             |            0 |          1 |          1
             |            0 |            |          2
             |            1 |          1 |          2
             |            1 |            |          2

(3)-(a)cube関数

 クロス集計するには、group by句にcube関数を使用します。cube関数は、PostgreSQL9.5で追加された新機能です。以下のように記述します。

[構文]cube関数
group by cube(expr1,expr2,・・・])

 引数expr1~を集計項目として、クロス集計を行います。ここでは「has_tagging」「has_purchase」「has_review」を引数としているので、これら3つを集計項目としたクロス集計を行います。

(4)データ整形

 (3)のクエリの結果でも分析は可能ですが、可読性が高い形式になるように、クエリ結果データを整形します。各アクションの組み合わせでのユーザー数の構成比も一緒に計算します。

(4)-(a)case式によるフラグから文字列への変換

 ここでは単純case式の構文を利用しています。単純case式の構文は以下の通りです。

[構文]単純case式
 case  <項目>
   WHEN <値1> THEN  <値4>
   WHEN <値2> THEN  <値5>
   ELSE <値3>
 END

 case式を利用することにより例えばフラグが1の場合は「tagging」、0の場合は「not tagging」のように文字列に変換します。文字列に変換することで可読性が高まります。

(4)-(b)sum関数(ウィンドウ関数)による集計

 sum関数がover句とともに用いられ、ウィンドウ関数(コラム参照)として利用されています。以下のように記述します。

[構文]over句
sum ( expr1 ) over ( expr2 )

 expr2では通常「PARTITION BY 項目名」などと指定することで、集計対象の行を絞ります。

 今回の例ではexpr2が空なので、全ての行を対象として集計を行います。

[コラム]ウィンドウ関数

 上記のようにsum()がover句とともに用いられる場合はウィンドウ関数と呼ばれる関数になります。GROUP BYによる集計がグループをまとめる(行が減る)のに対し、ウィンドウ関数は行はそのままで算出結果の列が増えます。別途集計結果を列に追加できるため、分析で活躍します。PostgreSQLのほかOracle・SQL Serverといった主なDBMSに実装されています。

(4)-(c)

 ユーザー数を全体のユーザー数で割ることで構成比を求めます。

 全体のユーザー数は上記のsumのウィンドウ関数とnuffif関数を用いて集計されています。nullifは指定された2つの引数が等しい場合にNULL値を返します。以下のように記述します。

[構文]nullif関数
nullif ( expr1 , expr2 )

まとめ

 今回は複数の機能を提供しているアプリケーションにおける、ユーザーアクション分析についてのSQLを紹介しました。

 ユーザー行動ログデータがあればSQLで分析が実施できます。データが利用できる場合はぜひ活用してください。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
ビジネスデータ解析のためのSQL入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 西 潤史郎(ニシ ジュンシロウ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook<個人紹介>フリーランスとしてデータ解析エンジニアとして主にビッグデータ関連の仕事をしています。TableauなどBIやビッグデータ処理などビジネスデータ解析環境の構築・運用、また解析系のアプリケーション開発やGoogleアナリティクス活用支援などを行っています。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10650 2018/02/23 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング