Firebase イベント データ分析のための Google Cloud 活用方法 (5) AutoML Tables での特徴量の重要度の確認

Keiji Yoshida
google-cloud-jp
Published in
25 min readApr 21, 2020

--

本連載について

モバイルやウェブ アプリケーションの KPI を改善させるためには、ユーザーの日々の利用状況や行動を適切に把握した上で、施策を検討して実施することが重要となります。特に、実際に KPI 改善施策を検討して実施する企画者やマーケターが、自分自身でデータを分析し、その結果にもとづいて施策を検討できるようになることは、「現状把握 → 施策検討 → 施策実施 → 効果測定」という KPI 改善のサイクルを迅速に回すために必要不可欠となっています。

Firebase SDK で開発されているアプリケーションについては、Google Analytics for Firebase を利用することで、ユーザーのイベント データを簡単に Google Analytics で収集できるようになっています。さらに、収集したイベント データを BigQuery へエクスポートすることにより、企画者やマーケターが BigQueryデータポータルなどを活用して、自分自身でデータの可視化やレポーティング、詳細なユーザー行動の分析などを行い、データ分析にもとづいた KPI 改善施策の検討と実施を迅速に行うことができるようになります。

本連載では、KPI 改善施策を検討して実施されるサービスの企画者やマーケターの方へむけて、Firebase イベント データを分析するための Google Cloud のプロダクトの活用方法をご紹介します。

連載記事一覧

  1. Firebase イベント データのスキーマ
  2. SQL の基礎
  3. データポータルでのレポート作成
  4. BigQuery でのデータの探索
  5. AutoML Tables での特徴量の重要度の確認(本記事)

本記事について

第 5 回目の本記事では、AutoML Tables の「特徴量の重要度」の機能を用いて、KPI の値の決定に寄与していると考えられる指標のうち、特に重要であると思われるものを確認する方法をご紹介します。

前回の第 4 回目の記事「BigQuery でのデータの探索」では、「『翌日もゲームをプレイする新規ユーザー』と『翌日はゲームをプレイしない新規ユーザー』では、『初日のアプリケーション起動時間』に差があるのではないか?」という仮説を立て、SQL を書いて実行し、実際に差があるか否かを確認しました。

ユーザーの属性の数や Firebase イベントの種類の数が増え、「翌日もゲームをプレイする新規ユーザー」と「翌日はゲームをプレイしない新規ユーザー」の違いとして考えられる指標の数が多くなった場合、それらの指標を個々に手作業で分析することには、多くの労力と時間が必要となります。

Google Cloud の AutoML Tables では、予測モデルを構築した際に、そのモデルを構築する上で特に重要であると思われる特徴量を表示する「特徴量の重要度」という機能があります。この機能を利用することで、「翌日もゲームをプレイする新規ユーザー」と「翌日はゲームをプレイしない新規ユーザー」の違いとして考えられる指標のうち、特に重要であると考えられる指標を、ある程度把握することができるようになります。それにより、各指標の分析を行う際に、分析対象の各指標に優先度を付けて、限られた時間の中で、効率的にデータ分析作業を進めることができるようになります。

この記事では、この AutoML Tables の「特徴量の重要度」の機能を用いて、「翌日もゲームをプレイする新規ユーザー」と「翌日はゲームをプレイしない新規ユーザー」の違いとして考えられる指標のうち、特に重要であると思われるものを確認する方法をご紹介します。

1. トレーニング データを格納するテーブルの作成

AutoML Tables で予測モデルを構築する際は、そのトレーニング データが格納されているテーブルを作成する必要があります。今回は、以下のクエリを実行して、そのテーブルを作成します。(以下のクエリの先頭行の your_projectyour_dataset には、ご利用されているプロジェクト ID とデータセット名を入力してください。)

create or replace table `your_project.your_dataset.new_users`
partition by event_date
cluster by user_pseudo_id
as
select
f.event_date
, f.user_pseudo_id
, n.user_pseudo_id is not null as retention_day1
, cast(coalesce(t.engagement_time_msec, 0) / 1000 / 60 as int64) as mins
, f.country
, f.platform
, coalesce(e.ad_reward, 0) as event_ad_reward
, coalesce(e.app_clear_data, 0) as event_app_clear_data
, coalesce(e.app_exception, 0) as event_app_exception
, coalesce(e.app_remove, 0) as event_app_remove
, coalesce(e.app_update, 0) as event_app_update
, coalesce(e.challenge_a_friend, 0) as event_challenge_a_friend
, coalesce(e.challenge_accepted, 0) as event_challenge_accepted
, coalesce(e.completed_5_levels, 0) as event_completed_5_levels
, coalesce(e.dynamic_link_app_open, 0) as event_dynamic_link_app_open
, coalesce(e.dynamic_link_first_open, 0) as event_dynamic_link_first_open
, coalesce(e.error, 0) as event_error
, coalesce(e.firebase_campaign, 0) as event_firebase_campaign
, coalesce(e.first_open, 0) as event_first_open
, coalesce(e.in_app_purchase, 0) as event_in_app_purchase
, coalesce(e.level_complete, 0) as event_level_complete
, coalesce(e.level_complete_quickplay, 0) as event_level_complete_quickplay
, coalesce(e.level_end, 0) as event_level_end
, coalesce(e.level_end_quickplay, 0) as event_level_end_quickplay
, coalesce(e.level_fail, 0) as event_level_fail
, coalesce(e.level_fail_quickplay, 0) as event_level_fail_quickplay
, coalesce(e.level_reset, 0) as event_level_reset
, coalesce(e.level_reset_quickplay, 0) as event_level_reset_quickplay
, coalesce(e.level_retry, 0) as event_level_retry
, coalesce(e.level_retry_quickplay, 0) as event_level_retry_quickplay
, coalesce(e.level_start, 0) as event_level_start
, coalesce(e.level_start_quickplay, 0) as event_level_start_quickplay
, coalesce(e.level_up, 0) as event_level_up
, coalesce(e.no_more_extra_steps, 0) as event_no_more_extra_steps
, coalesce(e.notification_foreground, 0) as event_notification_foreground
, coalesce(e.os_update, 0) as event_os_update
, coalesce(e.post_score, 0) as event_post_score
, coalesce(e.screen_view, 0) as event_screen_view
, coalesce(e.select_content, 0) as event_select_content
, coalesce(e.session_start, 0) as event_session_start
, coalesce(e.spend_virtual_currency, 0) as event_spend_virtual_currency
, coalesce(e.use_extra_steps, 0) as event_use_extra_steps
, coalesce(e.user_engagement, 0) as event_user_engagement
, coalesce(s.extra_steps, 0) as screen_view_extra_steps
, coalesce(s.game_board, 0) as screen_view_game_board
, coalesce(s.game_over, 0) as screen_view_game_over
, coalesce(s.how_to_play, 0) as screen_view_how_to_play
, coalesce(s.iap, 0) as screen_view_iap
, coalesce(s.level_select, 0) as screen_view_level_select
, coalesce(s.main_menu, 0) as screen_view_main_menu
, coalesce(s.out_of_steps, 0) as screen_view_out_of_steps
, coalesce(s.settings, 0) as screen_view_settings
, coalesce(s.shop_menu, 0) as screen_view_shop_menu
, coalesce(s.stats, 0) as screen_view_stats
from
(
select
parse_date('%Y%m%d', event_date) as event_date
, user_pseudo_id
, max(geo.country) as country
, max(platform) as platform
from
`firebase-public-project.analytics_153293282.events_*`
where
_table_suffix between '20180612' and '20181002'
and event_name = 'first_open'
group by
event_date
, user_pseudo_id
) f
left outer join
(
select distinct
parse_date('%Y%m%d', event_date) as event_date
, user_pseudo_id
from
`firebase-public-project.analytics_153293282.events_*`
where
_table_suffix between '20180613' and '20181003'
) n
on
n.user_pseudo_id = f.user_pseudo_id
and n.event_date = date_add(f.event_date, interval 1 day)
left outer join
(
select
parse_date('%Y%m%d', event_date) as event_date
, user_pseudo_id
, sum(p.value.int_value) as engagement_time_msec
from
`firebase-public-project.analytics_153293282.events_*` e
cross join
unnest(e.event_params) p
where
e._table_suffix between '20180612' and '20181002'
and p.key = 'engagement_time_msec'
group by
event_date
, user_pseudo_id
) t
on
t.event_date = f.event_date
and t.user_pseudo_id = f.user_pseudo_id
left outer join
(
select
parse_date('%Y%m%d', event_date) as event_date
, user_pseudo_id
, countif(event_name = 'ad_reward') as ad_reward
, countif(event_name = 'app_clear_data') as app_clear_data
, countif(event_name = 'app_exception') as app_exception
, countif(event_name = 'app_remove') as app_remove
, countif(event_name = 'app_update') as app_update
, countif(event_name = 'challenge_a_friend') as challenge_a_friend
, countif(event_name = 'challenge_accepted') as challenge_accepted
, countif(event_name = 'completed_5_levels') as completed_5_levels
, countif(event_name = 'dynamic_link_app_open') as dynamic_link_app_open
, countif(event_name = 'dynamic_link_first_open') as dynamic_link_first_open
, countif(event_name = 'error') as error
, countif(event_name = 'firebase_campaign') as firebase_campaign
, countif(event_name = 'first_open') as first_open
, countif(event_name = 'in_app_purchase') as in_app_purchase
, countif(event_name = 'level_complete') as level_complete
, countif(event_name = 'level_complete_quickplay') as level_complete_quickplay
, countif(event_name = 'level_end') as level_end
, countif(event_name = 'level_end_quickplay') as level_end_quickplay
, countif(event_name = 'level_fail') as level_fail
, countif(event_name = 'level_fail_quickplay') as level_fail_quickplay
, countif(event_name = 'level_reset') as level_reset
, countif(event_name = 'level_reset_quickplay') as level_reset_quickplay
, countif(event_name = 'level_retry') as level_retry
, countif(event_name = 'level_retry_quickplay') as level_retry_quickplay
, countif(event_name = 'level_start') as level_start
, countif(event_name = 'level_start_quickplay') as level_start_quickplay
, countif(event_name = 'level_up') as level_up
, countif(event_name = 'no_more_extra_steps') as no_more_extra_steps
, countif(event_name = 'notification_foreground') as notification_foreground
, countif(event_name = 'os_update') as os_update
, countif(event_name = 'post_score') as post_score
, countif(event_name = 'screen_view') as screen_view
, countif(event_name = 'select_content') as select_content
, countif(event_name = 'session_start') as session_start
, countif(event_name = 'spend_virtual_currency') as spend_virtual_currency
, countif(event_name = 'use_extra_steps') as use_extra_steps
, countif(event_name = 'user_engagement') as user_engagement
from
`firebase-public-project.analytics_153293282.events_*`
where
_table_suffix between '20180612' and '20181002'
group by
event_date
, user_pseudo_id
) e
on
e.event_date = f.event_date
and e.user_pseudo_id = f.user_pseudo_id
left outer join
(
select
parse_date('%Y%m%d', event_date) as event_date
, user_pseudo_id
, countif(p.value.string_value = 'extra_steps') as extra_steps
, countif(p.value.string_value = 'game_board') as game_board
, countif(p.value.string_value = 'game_over') as game_over
, countif(p.value.string_value = 'how_to_play') as how_to_play
, countif(p.value.string_value = 'iap') as iap
, countif(p.value.string_value = 'level_select') as level_select
, countif(p.value.string_value = 'main_menu') as main_menu
, countif(p.value.string_value = 'out_of_steps') as out_of_steps
, countif(p.value.string_value = 'settings') as settings
, countif(p.value.string_value = 'shop_menu') as shop_menu
, countif(p.value.string_value = 'stats') as stats
from
`firebase-public-project.analytics_153293282.events_*` e
cross join
unnest(e.event_params) p
where
e._table_suffix between '20180612' and '20181002'
and e.event_name = 'screen_view'
and p.key = 'firebase_screen_class'
group by
event_date
, user_pseudo_id
) s
on
s.event_date = f.event_date
and s.user_pseudo_id = f.user_pseudo_id

このクエリは、各日の新規ユーザーについて、以下の情報を保持するテーブルを作成します。

  • 翌日もゲームをプレイしたかどうか( retention_day1 カラム)
  • 初日のアプリケーション起動時間( mins カラム)
  • アクセス元の国( country カラム)
  • プラットフォーム( platform カラム:IOS または ANDROID
  • 初日の各イベントの発生回数( event_XXXX カラム)
  • 初日の各スクリーンの表示回数( screen_view_XXXX カラム)

このクエリの実行により、以下のようなテーブルが作成されます。

クエリ実行で作成される、各日の新規ユーザーの情報が格納されるテーブル

2. AutoML Tables でのトレーニングの実施

前節「1. トレーニング データを格納するテーブルの作成」で作成したテーブルを使用して、AutoML Tables で「ある日の新規ユーザーが、翌日もゲームをプレイするか否か」を予測するモデルを構築します。

https://console.cloud.google.com/automl-tables/datasets へアクセスし、AutoML Tables の「データセット」ページを開きます。

AutoML Tables の「データセット」ページ

「新しいデータセット」をクリックし、表示されるモーダル ウインドウで「データセット名」を入力して「データセットの作成」ボタンをクリックします。

「データセットの作成」をクリック

「データのインポート」エリアで、前節「1. トレーニング データを格納するテーブルの作成」で作成したテーブルのプロジェクト ID、データセット名、テーブル名を入力して「インポート」ボタンをクリックします。

プロジェクト ID、データセット名、テーブル名を入力して「インポート」ボタンをクリック

以下のような「トレーニング」ページが表示されます。

「トレーニング」ページ

country カラムの「データ型」を「カテゴリ」へ修正します。event_XXXX カラムと screen_view_XXXX カラムで、「データ型」が「カテゴリ」になっているものについては、「データ型」を「数値」へ修正します。

画面右上の「ターゲット列」に retention_day1 を設定し、「モデル トレーニング」ボタンをクリックします。

「ターゲット列」に retention_day1 を設定し、「モデル トレーニング」ボタンをクリック

「モデルのトレーニング」というモーダル ウインドウが表示されます。「予算」に 1 などの任意の値を入力します。「入力特徴量の選択」で、 event_date , user_pseudo_id のチェックを外します。「モデル トレーニング」のボタンをクリックします。

「予算」と「入力特徴量の選択」の値を設定し、「モデル トレーニング」をクリック

モデルのトレーニングが完了するまで待ちます。

モデルのトレーニング中

モデルのトレーニングが完了すると、以下の画面が表示されます。

モデルのトレーニングの完了

3. 「特徴量の重要度」の確認

前節「2. AutoML Tables でのトレーニングの実施」で構築したモデルの「評価」ページを開き、一番下の「特徴量の重要度」の内容を確認します。

特徴量の重要度

この内容により、「翌日もゲームをプレイする新規ユーザー」と「翌日はゲームをプレイしない新規ユーザー」を識別する際に、以下の指標が大きく影響している可能性がある、ということがわかりました。

  • 初日の app_remove イベント(アプリケーションのアンインストール)の発生
  • 初日の firebase_campaign イベントの発生
  • 初日の session_start イベント(セッション開始)の発生
  • country (アクセス元の国)

ここでは、「初日の app_remove イベント(アプリケーションのアンインストール)の発生」について、もう少し調査してみます。「初日にアプリケーションをアンインストールしたユーザーは、翌日に再びアプリケーションを利用する可能性は限りなく低くなりそうである」、ということは直感的に想像できることかと思います。「初日にアプリケーションをアンインストールしたユーザーが、どれくらいいたのか?」を、以下のクエリを実行して確認してみます。(以下のクエリの your_projectyour_dataset には、前節「1. トレーニング データを格納するテーブルの作成」で入力したプロジェクト ID とデータセット名と同じものを、それぞれ入力してください。)

select
retention_day1
, count(1) as users
, countif(event_app_remove > 0) as uninstalled
, round(countif(event_app_remove > 0) / count(1), 2) as uninstalled_rate
from
`your_project.your_dataset.new_users`
group by
retention_day1
order by
retention_day1 desc

このクエリの実行結果は、以下のようになります。

初日にアンインストールしたユーザー数の確認

「翌日はゲームをプレイしない新規ユーザー」のうち、25% のユーザーが、初日にアプリケーションをアンインストールしていたことがわかりました。これらのユーザーについては、さらに Firebase イベント データの分析を行い、たとえば「どのポイントでゲームをプレイすることを止めてアンインストールしたのか?」を調査することで、KPI 「1 日後の継続率」の改善方法を検討できるかもしれません。

このように、AutoML Tables の「特徴量の重要度」機能を活用することで、分析対象の指標が多数ある場合に、各指標に優先度を付けて、効率的にデータ分析作業を進めることができるようになります。

おわりに

本連載では、KPI 改善施策を検討して実施されるサービスの企画者やマーケターの方へむけて、Firebase イベント データを分析するための Google Cloud のプロダクト(BigQueryデータポータルAutoML Tables)の活用方法をご紹介しました。もし Firebase SDK を利用したアプリケーションを運用されていましたら、ぜひ今回ご紹介したような方法で Google Cloud をご活用いただき、KPI 改善施策の検討、実施のためのユーザー行動分析を実施いただければと思います。Firebase イベント データを BigQuery へエクスポートする方法につきましては、Firebase ヘルプ ページ「Firebase の BigQuery Export — Firebase ヘルプ」をご参照ください。

--

--