SKAd Network コンバージョン値スキーマの収益バケットを計算する

1. はじめに

始める前に

iOS アプリのデベロッパーであれば、iOS 14.5 以降のプライバシー アップデートについてご存じでしょう。インストール後の重要なコンバージョン アクションを測定するために、Apple は SKAd Network API を提供しています。この API を使用すると、ユーザーのプライバシーを尊重しながら広告キャンペーンの成果を測定できます。ビジネスニーズに基づいて、SKAdNetwork を活用してキャンペーンに関する有益な分析情報を取得する最適な方法を検討できます。この Codelab では、BigQuery で GA4F データを活用して、アプリのインストール後の収益をバケットにグループ化する手法の例を検証します。このバケットは、アプリ アトリビューション パートナーとの設定に使用できます。この Codelab では収益ベースのアプローチを使用していますが、SKAN 測定にはイベント ベースのアプローチやファネル ベースのアプローチも使用できます。詳細な手順については、こちらのヘルプセンターをご覧ください。これは単なる例であり、Google の公式な推奨事項ではありません。特定のビジネスニーズに基づいて独自のスキーマを設計できます。

説明する内容

  • BigQuery で GA4F データを探索する
  • コンバージョンに至ったユーザーの収益データを 0 ~ 2 日以内に確認する
  • 収益データをバケットにグループ化する
  • 各バケットのユーザー分布を把握する
  • Appsflyer SKAN Conversion Studio でバケットを実装する

前提条件

  • iOS アプリに GA4F SDK が組み込まれており、すべての収益イベント(in_app_purchase または広告収益)が統合されている
  • Firebase から BigQuery へのエクスポートが有効
  • App Attribution Partner(すべての収益イベントも記録している)

2. BigQuery Export へのアクセス

[プロジェクトの設定] > [統合] > [BigQuery] に移動して、GA4F のデータセットにアクセスします。切り替えを有効にする必要があります。有効にすると、データセットが利用可能になるまでに約 48 時間かかります。次のリンクをクリックすると、BigQuery に移動します。

1aa4e20bfd3419d1.png

クエリを実行する

BigQuery に移動すると、生成された日次テーブルが表示されます。下のスクリーンショットの例では、64 個の日次テーブルが表示されているため、エクスポートが 64 日間実行されていることがわかります。初めてアクセスする場合は、前日のデータに関する日次テーブルが 1 つだけ表示されることがあります。右側にテーブル スキーマが表示されます。フィールドの詳細については、こちらをご覧ください。

クエリの作成を開始するには、[クエリ] > [新しいタブ] をクリックします。

42ba59ec655c5d1b.png

新しいタブでサンプルクエリを実行してみてください。

70ef90d32b7cd7f1.png

3. 収益データを分析する

インストール データを取得する

収益バケットの作成を開始するには、まず過去 24 ~ 72 時間以内にアプリをインストールしたユーザーのデータを確認する必要があります。SKAd Network 4.0 では 0 ~ 2 日間のデータを表示できますが、SKAd Network 3.5 ではデフォルトで 24 時間のデータを表示できます。(アプリ アトリビューション パートナーの機能によっては、このアクティビティ ウィンドウを一般的に 72 時間以下に変更できる場合があります)。ユーザーがアプリをインストールして初めて開くと、SDK によって first_open イベントがトリガーされ、BigQuery に記録されます。

BigQuery で使用できる識別子は user_pseudo_id(アプリ インスタンス ID とも呼ばれます)です。以下のクエリを使用すると、これらのユーザーを見つけることができます。

SELECT
  user_pseudo_id,
  event_name,
  event_date,
  event_timestamp
FROM `project_name.dataset_name.events_2023*`
WHERE
  event_name = 'first_open'
  AND platform = 'IOS'

このクエリについて、以下の点にご留意ください

  • テーブル名は、アナリティクスからエクスポートしたテーブルに置き換えてください。ワイルドカード を使用すると、複数の日次テーブルにクエリを実行できます。たとえば、2023* は 2023 年のすべてのデータをクエリします。
  • ユーザー数が多い場合は、処理を高速化するために過去 30 日間のみをクエリすることもできます。
  • platform = ‘IOS’ でフィルタします。Firebase プロジェクトに複数の iOS アプリがある場合は、app_info.firebase_app_id のフィルタを追加して、特定のアプリのデータを取得することもできます。

収益データの取得

次に、ユーザーの収益を調べるクエリを見てみましょう。この場合、収益イベントは in_app_purchase と ad_impression であると想定します。in_app_purchase の収益は event_value_usd で確認できます。一方、ad_impression の収益は、イベント パラメータ内の value パラメータで確認できます。BigQuery のイベント パラメータに精通していない場合は、こちらで定義を確認することをおすすめします。また、公式リファレンスでこのサンプルクエリを試すこともできます。このリファレンスでは、event_params から値を取得する方法についても説明しています。

SELECT
  user_pseudo_id,
  event_name,
  EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
  (
    SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
    FROM UNNEST(event_params)
    WHERE
      KEY = 'value'
      AND event_name = 'ad_impression'
  ) AS ad_funded_revenue,
  (
    SELECT value.string_value
    FROM UNNEST(event_params)
    WHERE
      KEY = 'currency'
      AND event_name = 'ad_impression'
  ) AS ad_revenue_currency,
  (
    CASE
      WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
      ELSE 0
      END) AS iap_revenue_usd,
FROM `project_name.dataset_name.events_2023*`
WHERE
  platform = 'IOS'
  AND event_name IN (
    'in_app_purchase',
    'ad_impression')

ここでクエリが何をしているのかを理解しましょう。これらの点に注意してください

  • WHERE 句では、収益イベントのみに関心があるため、収益イベントをフィルタしています。また、前回と同様に、iOS データを検索しています。
  • SELECT 句では、広告収入イベント(ad_impression)の値と通貨を取得し、イベントが in_app_purchase の場合は event_value_in_usd を取得します。
  • 複数の通貨で送信する場合は、まずこの分析用に単一の通貨に合わせる必要があります。この例では、広告収入の通貨も米ドルと仮定します。

出力は次のようになります(user_pseudo_id の列はここで編集されています)。

1e1e6943e4b3a6d8.png

このデータを組み合わせる

これまでに、アプリをインストールして開いたユーザーのデータを取得するクエリと、それらのユーザーの収益を取得するクエリの 2 つを実行しました。ここで、SKAdNetwork の制限について説明した内容を思い出してみましょう。アトリビューション期間は、インストール後 0 ~ 2 日間のみ利用できます。そのため、インストールと収益のイベント タイムスタンプを確認し、その期間内に発生した場合にのみ情報を取得する必要があります。アプリのインストールから 2 日後の各投稿の合計収益を取得するクエリに統合してみましょう。

#creating the install table
WITH
  install_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_date,
      event_timestamp
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      event_name = 'first_open'
      AND platform = 'IOS'
  ),
  #creating the revenue table
  revenue_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_timestamp,
      EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
      (
        SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
        FROM UNNEST(event_params)
        WHERE
          KEY = 'value'
          AND event_name = 'ad_impression'
      ) AS ad_funded_revenue,
      (
        SELECT value.string_value
        FROM UNNEST(event_params)
        WHERE
          KEY = 'currency'
          AND event_name = 'ad_impression'
      ) AS ad_revenue_currency,
      (
        CASE
          WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
          ELSE 0
          END) AS iap_revenue_usd,
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      platform = 'IOS'
      AND event_name IN (
        'in_app_purchase',
        'ad_impression')
  )
SELECT
  it.user_pseudo_id AS user_pseudo_id,
  #combine ad revenue and IAP revenue, assuming both are in same currency
  sum(ifnull(rt.iap_revenue_usd,0) + ifnull(rt.ad_funded_revenue,0)) AS total_revenue,
FROM install_table it
INNER JOIN revenue_table rt
  ON it.user_pseudo_id = rt.user_pseudo_id
WHERE
  rt.event_timestamp >= it.event_timestamp
  AND rt.event_timestamp
    <= it.event_timestamp + 86400000000 * 2  #added 86400 000 millisecond as 24 hours, taking for 2 days later
GROUP BY 1

このクエリは、user_pseudo_id フィールドでインストール データと収益データを結合しようとしています。また、タイムスタンプが 2 日以内であることを確認する必要があります。SKAd Network 3.5 を使用している場合、デフォルトは 24 時間です。条件を変更して 1 日分のデータのみを含めることもできます。

収益をバケットにグループ化する

前のクエリの後、user_pseudo_id と合計収益を取得します。

2c1986b93e937d19.png

これをコンバージョン値の範囲に使用できるバケットに統合する必要があります。この目的のために、BigQuery の approx_quantiles 関数を使用します。この関数は、これらの範囲を自動的に作成します。この例では、5 つの範囲を作成するとします。SELECT approx_quantiles(total_revenue, 5) AS buckets を使用します。

それでは、これを全体的なクエリに組み込みましょう。

#creating the install table
WITH
  install_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_date,
      event_timestamp
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      event_name = 'first_open'
      AND platform = 'IOS'
  ),
  #creating the revenue table
  revenue_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_timestamp,
      EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
      (
        SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
        FROM UNNEST(event_params)
        WHERE
          KEY = 'value'
          AND event_name = 'ad_impression'
      ) AS ad_funded_revenue,
      (
        SELECT value.string_value
        FROM UNNEST(event_params)
        WHERE
          KEY = 'currency'
          AND event_name = 'ad_impression'
      ) AS ad_revenue_currency,
      (
        CASE
          WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
          ELSE 0
          END) AS iap_revenue_usd,
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      platform = 'IOS'
      AND event_name IN (
        'in_app_purchase',
        'ad_impression')
  ),
  total_revenue_table AS (
    SELECT
      it.user_pseudo_id AS user_pseudo_id,
      #combine ad revenue and IAP revenue, assuming both are in same currency
      sum(ifnull(rt.iap_revenue_usd,0) + ifnull(rt.ad_funded_revenue,0)) AS total_revenue,
    FROM install_table it
    INNER JOIN revenue_table rt
      ON it.user_pseudo_id = rt.user_pseudo_id
    WHERE
      rt.event_timestamp >= it.event_timestamp
      AND rt.event_timestamp
        <= it.event_timestamp + 86400000000 * 2  #added 86400 000 millisecond as 24 hours
    GROUP BY 1
  )
SELECT approx_quantiles(total_revenue, 5) AS buckets FROM total_revenue_table

このクエリは収益を 5 つのバケットに分割し、BigQuery は一貫したパーセンタイル分布を維持しようとします。

ba46f5d993449948.png

これらのバケットでユーザー分布を分析する

これは、各バケットのユーザー分布を把握したい場合に任意で行う手順です。この例では、前のクエリで返されたバケット範囲は次のとおりです。

  • 0.1
  • 0.5
  • 2
  • 2.5
  • 5 [範囲構成では最後の値は使用されません]

最後の範囲については、通常は最大値である最後のバケット 5 を無視し、2.5 を最後の範囲と見なします。これは、アプリ アトリビューション プロバイダが範囲の平均値を使用して広告費用対効果を計算する傾向があるため、より均一な計算を行うには外れ値を除外する必要があるためです。

次に、すべての範囲の日付ごとのユーザー数を確認して、各バケットの 1 日あたりのユーザー数を把握します。これを行うには、次のサンプルクエリを使用します。バケット値を実際のデータに置き換えると、クエリは次のようになります。

#creating the install table
WITH
  install_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_date,
      event_timestamp
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      event_name = 'first_open'
      AND platform = 'IOS'
  ),
  #creating the revenue table
  revenue_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_timestamp,
      EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
      (
        SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
        FROM UNNEST(event_params)
        WHERE
          KEY = 'value'
          AND event_name = 'ad_impression'
      ) AS ad_funded_revenue,
      (
        SELECT value.string_value
        FROM UNNEST(event_params)
        WHERE
          KEY = 'currency'
          AND event_name = 'ad_impression'
      ) AS ad_revenue_currency,
      (
        CASE
          WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
          ELSE 0
          END) AS iap_revenue_usd,
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      platform = 'IOS'
      AND event_name IN (
        'in_app_purchase',
        'ad_impression')
  ),
  total_revenue_table AS (
    SELECT
      it.user_pseudo_id AS user_pseudo_id,
      rt.event_date,
      #combine ad revenue and IAP revenue, assuming both are in same currency
      sum(ifnull(rt.iap_revenue_usd,0) + ifnull(rt.ad_funded_revenue,0)) AS total_revenue,
    FROM install_table it
    INNER JOIN revenue_table rt
      ON it.user_pseudo_id = rt.user_pseudo_id
    WHERE
      rt.event_timestamp >= it.event_timestamp
      AND rt.event_timestamp
        <= it.event_timestamp + 86400000000 * 2  #added 86400 000 millisecond as 24 hours
    GROUP BY 1, 2
  )
SELECT
  event_date,
  sum(CASE WHEN total_revenue BETWEEN 0 AND 0.1 THEN 1 ELSE 0 END) AS Bucket1,
  sum(CASE WHEN total_revenue BETWEEN 0.1 AND 0.5 THEN 1 ELSE 0 END) AS Bucket2,
  sum(CASE WHEN total_revenue BETWEEN 0.5 AND 2 THEN 1 ELSE 0 END) AS Bucket3,
  sum(CASE WHEN total_revenue BETWEEN 2 AND 2.5 THEN 1 ELSE 0 END) AS Bucket4,
  sum(CASE WHEN total_revenue > 2.5 THEN 1 ELSE 0 END) AS Bucket5
FROM total_revenue_table
GROUP BY 1 ORDER BY 1 DESC

以下のように、収益の範囲ごとにユーザーを日別に返します。いずれかのバケットの数値が非常に低い場合や、分布が全般的に不均一な場合は、バケットの数を調整してクエリを再実行することをおすすめします。

bf7d73085fe94cb6.png

SKAd Network 4.0 について

SKAd Network 4.0 では、最大 2 日間、3 ~ 7 日間、8 ~ 35 日間の複数の計測期間が提供されます。上記のアプローチでは、これらの追加シナリオのデータを分析するウィンドウも簡単に変更できます。LOW、MEDIUM、HIGH の粗粒度値も使用できます。このアプローチを使用する場合は、3 つのバケットがあると考えてください。バケットの数を 3 に変更すると、低、中、高のしきい値を取得できます。

4. アトリビューション プロバイダとのデプロイ

このガイダンスは、プラットフォームによって変更される場合があります。この件に関する最新情報については、プラットフォームの担当者にお問い合わせください。この例では、AppsFlyer で現在この機能をデプロイする方法について説明します。

先ほど実行したクエリでは、出力として受け取った最終的な範囲は次のとおりでした。

ba46f5d993449948.png

  • 範囲 1 : 0 ~ 0.1
  • 範囲 2 : 0.1 ~ 0.5
  • 範囲 3 : 0.5 ~ 2
  • 範囲 4 : 2 ~ 2.5

最後の収益範囲は外れ値となり、アプリ アトリビューション プロバイダの平均計算が歪められるため、無視することにしました。

AppsFlyer では、SKAN Conversion Studio を提供しています。このツールでは、UI に直接入力するだけで簡単に設定できます。4.0 を直接使用するか、3.5 を使用している場合は「カスタム」モードを使用して「収益」の測定を追加します。その後、先ほどの分析で計算した収益範囲を追加します。

f8c56abdf9b405f4.png

Google 広告のベスト プラクティスと学習内容

Google 広告でキャンペーンを実施し、SKAdNetwork コンバージョン値スキーマで効果を測定している場合は、以下の推奨事項をご参照ください。

  • Google 広告で使用している計測期間が、アプリ アトリビューション プラットフォームで指定したアクティビティ ウィンドウと一致していることを確認します。SKAdNetwork 3.5 の場合、通常は 1 ~ 3 日以内です。Google 広告で、こちらの手順に沿って、この期間を調整できます。

4fd625aae9d4a43.png

  • Appsflyer を使用している場合、現在のデフォルトのイベント カウンタは 1 です。つまり、ユーザーあたりの複数のイベントはカウントされません。SKAN 測定にイベントベースのモデルを使用し、Google 広告で目標アクション単価キャンペーンと比較している場合は、Appsflyer のこちらのガイダンスに沿ってカスタマイズできます。

6c7a4d703567700a.png

5. 完了

これで、SKAdNetwork コンバージョン値スキーマの設定が完了しました。この機能が有効になると、Google 広告の SKAdNetwork レポートでデータをモニタリングし、Google 広告キャンペーンのコンバージョン値を確認できるようになります。

学習した内容

  • BigQuery で GA4F の豊富な元データを探索する方法
  • ビジネスの収益バケットを計算する分析アプローチ
  • AppsFlyer でスキーマをデプロイする