【Tableau Tips】GA4データの可視化をこの記事一本でマスター!
2024年7月1日をもって、ユニバーサルアナリティクス(UA)へのアクセスが完全に停止され、今後はGoogleアナリティクス4(GA4)の運用が本格化します。
UAに慣れ親しんでいたユーザーにとって、GA4の新しいUIは戸惑いを感じさせるものかもしれません。そんな方々に強力なサポートを提供するのが、Tableauを活用したGA4データの可視化です。
本記事では、GA4データをTableauで可視化するためのデータ接続から加工、そして可視化までのプロセスを体系的に解説します。
TableauからGA4へのデータ接続
接続の方式について
TableauからGA4のデータに接続するのに2つの方式があります。
・GA4コネクタを用いる方法
・BigQueryを用いる方法
GA4の画面上に出ている集計をTableauで手軽に再現したい場合は、GA4コネクタでもよいですが、基本分析したい・GA4データを利活用したい場合はBigQueryを推奨します。
GA4コネクタの良さは、クエリを書かなくても集計できる点と、何よりも流入チャネルや滞在時間など、BigQueryに格納されていないGoogleのオリジナルロジックが入っている項目を集計したい時、数値の整合性が取りやすい点です。
※BigQueryでは流入チャネルの情報をmedium, source, campaignの3つの項目に保持させていますが、GA4の集客レポートの「トラフィック獲得」画面で表示している結果との差分が発生し、会社によっては無視できないほどの大差が出るケースもあります。
GA4のデータ接続方式の比較表
BigQueryに格納されているGA4データは、デフォルトのままでは配列データを含んでいるため、直接Tableauでの集計には適していません。そのため、一度クエリを使ってデータをマトリックス形式のテーブルに変換する必要があり、この手間が手軽さを欠く要因となります。
しかし、データを一度加工すれば、GA4のすべてのディメンションと指標を一括で取り込むことが可能になります。そのため、GA4のコネクタのように、分析の視点を変えるたびにデータを再抽出する必要がないという点で非常に優れています。
特にGA4コネクタを使用する場合、同時に取り込むディメンションが少ないときは問題ありませんが、3つを超えると集計結果が一気に不正確になることがあります。そのため、GA4コネクタだけでレポートを作成する際には、何度も条件を指定してデータを抽出する必要があり、集計がしにくくなります。
また、GA4コネクタのような一定の集計が済んだデータより、BigQueryのようなRaw DataのほうがTableauとの相性がよいため、Raw DataにLOD表現を使うことで、サイト内行動分析・顧客分析など、分析の自由度が一気に広がります。
GA4コネクタのデータ更新
GA4コネクタを使う場合、もう一つ留意すべき点はデータ更新です。
Tableauから直接GA4コネクタに接続する場合、日が跨いでも更新されません。これはダッシュボードなどモニタリングレポートを作成するときに大きな欠点となります。
しかし、TableauCloudやServerを使う時は、データソースをTableauCloudなどにアップロードすることで、解消されます。
この手法はあまり公開されておらず、困っている人も少なからずいるため、本記事では少しご紹介させてください。
データソースのアップロードは大きく分けると2つやることがあります。
Step1:GA4の認証権限をTableauCloudなどに埋め込む
TableauCloudの右上のユーザープロフィール画像をクリックし、マイアカウント設定をクリックしたら保存済み認証資格情報一覧がみれます。
※保存済み認証資格情報一覧
赤枠のGoogle Analytics4の追加ボタンを押したあとに、手順通りに操作すれば、ご自身の認証をTableauCloudに記憶させることができます。
Step2:TableauDesktopからGA4コネクタを使って、抽出条件を設定したうえで接続
実際の集計要件に合わせて期間やディメンション・指標を選択します。期間はRELATIVE TO REFRESH DATEのほうから選択するとよいです。
※GA4コネクタ期間設定画面
Step3:Tableauのナビゲーションから「サーバー」→「データソースのパブリッシュ」→ご自身のGA4プロパティを選択
Step3:Tableauのナビゲーションから「サーバー」→「データソースのパブリッシュ」→ご自身のGA4プロパティを選択
※GA4プロパティを選択し、TableauCloudにデータソースとしてパブリッシュ
パブリッシュする時は場所と名前を適宜にご設定ください。
※パブリッシュの場所と名前を設定
この時に大事なのは、「認証」のところで「ご自身のメールアドレスを埋め込み」を選択することです。こうすることで、認証情報が埋まり、TableauCloudにいるほかのユーザーさんもこちらのデータソースをご利用することが可能となります。
※認証情報を埋める
埋め込みができたら以下の画面が自動的に立ち上がります。
※アップロード済のデータソース画面
Step4:データソースの「抽出の更新」をクリックし、「新しい抽出更新」でバッチ処理を加える
※データソースの更新バッチを追加
Step5:ダッシュボードが接続するデータソースを変更
データソースを新規追加するときに「TableauServer」を選び、先ほどアップロードしたデータソースを選択します。
※TableauServerにアップロードしたデータソースに接続
接続後に、最初にGA4コネクタから接続しているデータソースを右クリックし、「データソースの置換」を選択し、置き換えを行えば完成です。
※データソースを置き換える
BigQueryのGA4データ加工
BigQueryにあるGA4データを活用する場合、2点加工する必要があります。
1点目はUNNEST処理です。
冒頭で述べた通り、BigQueryにあるGA4のデータでは配列が含まれているため、そのままではTableauで処理することが難しいです。
そのため、通常の項目に加え、event_paramsなどの配列データを抽出したい時はUNNEST処理を行う必要があります。
BigQueryにあるGA4データ
-- 文字列(string_value)のデータを抽出したい場合
-- page_locationの例
(select value.string_value from unnest(event_params) where key = 'page_location') as page_location
-- 数値(int_value)のデータを抽出したい場合
-- ga_session_numberの例
(SELECT value.int_value FROM UNNEST(event_params) AS params WHERE params.key = 'ga_session_number') AS ga_session_number
2点目はGA4画面にはあるものの、BigQueryのテーブルにない項目の集計となります。
BigQuery テーブルでは、個々のレコードが行の形式にまとめられています。各レコードは列(フィールドとも呼ばれる)で構成されています。
代表的なのは、流入チャネル、滞在時間、直帰などの項目となります。特に流入チャネルは会社によって定義が異なりますが、基本first touch channelの思想で集計するとよいでしょう。
以下、テンプレートとクエリをいくつか紹介します。
よく利用するテンプレート
自社データなら必要ないですが、クライアントワークをしている場合は、お客様のGA4データでどのようなeventが実装されているかを調べる必要があるため、すべてのeventsとparametersをユニークで抽出するクエリテンプレートは以下です。
select
event_name,
params.key as event_parameter_key,
case when params.value.string_value is not null then 'string'
when params.value.int_value is not null then 'int'
when params.value.double_value is not null then 'double'
when params.value.float_value is not null then 'float'
else null end as event_parameter_value
from
`yourprojectname.analytics_yourid.events_*`, -- テーブル名を書き換えてください
unnest(event_params) as params
group by
event_name,
event_parameter_key,
event_parameter_value
order by
event_name,
event_parameter_key
全量スキャンを避けるために、_table_suffixを使いますが、相対的な日付を抽出したい場合は、以下のクエリが有効でしょう。
select
*
from
`yourprojectname.analytics_yourid.events_*`, -- テーブル名を書き換えてください
where
regexp_extract(_table_suffix,'[0-9]+') between
format_date('%Y%m%d',date_sub(current_date(), interval 7 day))
and format_date('%Y%m%d', current_date())
分析用のクエリテンプレート
やや長いですが、比較的に汎用的なテーブルを作成したい時、以下のクエリをベースに変更を加えるとよいです。
SELECT DISTINCT
event_date
, FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_TRUNC(timestamp_micros(event_timestamp), SECOND), "Asia/Tokyo") AS event_timestamp_formatted
, FORMAT_TIMESTAMP('%Y-%m-%d', TIMESTAMP_TRUNC(timestamp_micros(event_timestamp), SECOND), "Asia/Tokyo") AS event_date_formatted
, user_pseudo_id AS ga_uu_id
, (SELECT value.int_value FROM UNNEST(event_params) AS params WHERE params.key = 'ga_session_id') AS ga_session_id
, (SELECT value.int_value FROM UNNEST(event_params) AS params WHERE params.key = 'ga_session_number') AS ga_session_number
, event_name
, (SELECT value.string_value FROM UNNEST(event_params) AS params WHERE params.key = 'page_title') AS page_title
, (SELECT value.string_value FROM UNNEST(event_params) AS params WHERE params.key = 'page_location') AS page_location
, (SELECT value.string_value FROM UNNEST(event_params) AS params WHERE params.key = 'page_referrer') AS page_referrer
-- 流入情報
, traffic_source.name AS name
, traffic_source.medium AS medium
, traffic_source.source AS source
, stream_id
, platform
-- その他情報
, device.category
, device.operating_system
-- , device.operating_system_version
, device.web_info.browser
, geo.country
, geo.region
, geo.city
, geo.sub_continent
, geo.metro
FROM `yourprojectname.analytics_yourid.events_*`, -- テーブル名を書き換えてください
WHERE
event_name = 'page_view'
もし流入チャネルや直帰なども集計したい場合は以下のテンプレートをご利用ください。
WITH pv_data AS
(
SELECT DISTINCT
event_date
, FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_TRUNC(timestamp_micros(event_timestamp), SECOND), "Asia/Tokyo") AS event_timestamp_formatted
, FORMAT_TIMESTAMP('%Y-%m-%d', TIMESTAMP_TRUNC(timestamp_micros(event_timestamp), SECOND), "Asia/Tokyo") AS event_date_formatted
, user_pseudo_id AS ga_uu_id
, (SELECT value.int_value FROM UNNEST(event_params) AS params WHERE params.key = 'ga_session_id') AS ga_session_id
, (SELECT value.int_value FROM UNNEST(event_params) AS params WHERE params.key = 'ga_session_number') AS ga_session_number
, event_name
, (SELECT value.string_value FROM UNNEST(event_params) AS params WHERE params.key = 'page_title') AS page_title
, (SELECT value.string_value FROM UNNEST(event_params) AS params WHERE params.key = 'page_location') AS page_location
, (SELECT value.string_value FROM UNNEST(event_params) AS params WHERE params.key = 'page_referrer') AS page_referrer
-- 流入情報
, traffic_source.name AS name
, traffic_source.medium AS medium
, traffic_source.source AS source
, stream_id
, platform
-- その他情報
, device.category
, device.operating_system
-- , device.operating_system_version
, device.web_info.browser
, geo.country
, geo.region
, geo.city
, geo.sub_continent
, geo.metro
FROM `yourprojectname.analytics_yourid.events_*`, -- テーブル名を書き換えてください
WHERE
event_name = 'page_view'
)
-- page_view_numberを加工
, add_page_number AS
(
SELECT
*
, CONCAT(ga_uu_id, '.', ga_session_id) AS renew_ga_session_id
, DENSE_RANK() OVER(PARTITION BY ga_uu_id ORDER BY ga_session_id) AS visit_number_renew /*visit_numを1から振り直す*/
, COUNT(1)OVER(PARTITION BY ga_session_id) AS cnt_pv
, DENSE_RANK() OVER(PARTITION BY ga_session_id ORDER BY event_timestamp_formatted) AS page_number_renew
, MAX(event_timestamp_formatted)OVER(PARTITION BY ga_uu_id, ga_session_id) AS max_event_timestamp_formatted
, MIN(event_timestamp_formatted)OVER(PARTITION BY ga_uu_id, ga_session_id) AS min_event_timestamp_formatted
FROM pv_data
)
SELECT
*
, DATETIME_DIFF(TIMESTAMP(max_event_timestamp_formatted), TIMESTAMP(min_event_timestamp_formatted), SECOND) AS datetime_diff_ses
-- 流入チャネル加工
, MIN(CASE WHEN page_number_renew = 1 THEN name ELSE NULL END)OVER(PARTITION BY renew_ga_session_id) AS ses_min_name
, MIN(CASE WHEN page_number_renew = 1 THEN medium ELSE NULL END)OVER(PARTITION BY renew_ga_session_id) AS ses_min_medium
, MIN(CASE WHEN page_number_renew = 1 THEN source ELSE NULL END)OVER(PARTITION BY renew_ga_session_id) AS ses_min_source
, MIN(CASE WHEN page_number_renew = 1 THEN page_referrer ELSE NULL END)OVER(PARTITION BY renew_ga_session_id) AS ses_min_page_referrer
, MIN(CASE WHEN visit_number_renew = 1 AND page_number_renew = 1 THEN name ELSE NULL END)OVER(PARTITION BY ga_uu_id) AS uu_min_name
, MIN(CASE WHEN visit_number_renew = 1 AND page_number_renew = 1 THEN medium ELSE NULL END)OVER(PARTITION BY ga_uu_id) AS uu_min_medium
, MIN(CASE WHEN visit_number_renew = 1 AND page_number_renew = 1 THEN source ELSE NULL END)OVER(PARTITION BY ga_uu_id) AS uu_min_source
, MIN(CASE WHEN visit_number_renew = 1 AND page_number_renew = 1 THEN page_referrer ELSE NULL END)OVER(PARTITION BY ga_uu_id) AS uu_min_page_referrer
FROM add_page_number
テーブル作成時のクエリテンプレート
GA4のBigQueryエクスポートスキーマは、常に「進行中のもの」です。
定期的に新しいフィールドが追加されるため、古いデータにはそれらが含まれず、エラーを引き起こす可能性があります。また、広範な期間をクエリすると、BigQueryはこれらのフィールドを認識しないと警告します。
そのために、Tableau用のGA4の中間テーブルを作る時は過去3日に遡ってmerge処理を加えることを推奨します。
そのテンプレートは以下です:
MERGE
`yourprojectname.analytics_yourid.ga_for_tableau` AS org
USING
(
SELECT DISTINCT
SAFE_CAST(FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_TRUNC(timestamp_micros(event_timestamp), SECOND), "Asia/Tokyo") AS TIMESTAMP) AS event_timestamp_formatted
, SAFE_CAST(FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_TRUNC(timestamp_micros(user_first_touch_timestamp), SECOND), "Asia/Tokyo") AS TIMESTAMP) AS user_first_touch_timestamp_formatted
, user_pseudo_id
, (SELECT value.string_value FROM UNNEST(event_params) AS params WHERE params.key = 'page_title') AS page_title
, (SELECT value.string_value FROM UNNEST(event_params) AS params WHERE params.key = 'page_location') AS page_location
, (SELECT value.string_value FROM UNNEST(event_params) AS params WHERE params.key = 'page_referrer') AS page_referrer
, SAFE_CAST((SELECT value.int_value FROM UNNEST(user_properties) AS params WHERE params.key = 'customer_user_id') AS STRING) AS customer_user_id
, CONCAT(user_pseudo_id, '.', (SELECT value.int_value FROM UNNEST(event_params) AS params WHERE params.key = 'ga_session_id')) AS session_id
-- 流入情報
, traffic_source.name AS name
, traffic_source.medium AS medium
, traffic_source.source AS source
, CONCAT(traffic_source.source, '.', traffic_source.medium, '.', traffic_source.name) AS channel
-- その他情報
, device.category
, device.operating_system
, device.web_info.browser
, device.web_info.hostname
, geo.country
, geo.region
, geo.city
, ecommerce.transaction_id
FROM `yourprojectname.analytics_yourid.events_*`, -- テーブル名を書き換えてください
WHERE
event_name = 'page_view'
AND _TABLE_SUFFIX BETWEEN format_date('%Y%m%d',date_add(current_date("Asia/Tokyo"),INTERVAL -3 day)) and format_date('%Y%m%d',date_add(current_date("Asia/Tokyo"),INTERVAL -1 day))
AND device.web_info.hostname IN ('www.housingstage.jp', 'account.housingstage.jp')
AND (SELECT value.int_value FROM UNNEST(user_properties) AS params WHERE params.key = 'customer_user_id') IS NOT NULL
) AS add
ON
org.event_timestamp_formatted = add.event_timestamp_formatted
AND
org.user_pseudo_id = add.user_pseudo_id
AND
org.session_id = add.session_id
WHEN NOT MATCHED BY TARGET THEN
INSERT ROW
ここでの補足ですが、初回クエリを走らせるときは、GA4データを全量スキャンし、オリジナルテーブルを作成する必要があります。
その時は前に紹介したテンプレートのクエリを使って、yourprojectname.analytics_yourid.ga_for_tableau
みたいなテーブルを作成してから、こちらのMERGEクエリを実行するとよいでしょう。
GA4のデータ可視化
GA4上では分析を行うと、流入詳細をみたり、CVデータをみたりすると、レポートのページを切り替えたり、探索レポートで新規タブを作ったりする必要がありますが、Tableauでダッシュボードを作る場合は、主要KPIを一画面に収めて作成することができるため、現在の事業状況がより一目瞭然になるメリットがあります。
最後に、BIダッシュボードの参考として、GA4分析のダッシュボードテンプレートを添付しますのでぜひ、参考にしてください。
この記事を書いた人
Tableauの資料請求はこちら
洞察に基づいた戦略的な意思決定と迅速なデータ分析でビジネスの成長をサポートします。