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

1. はじめに

始める前に

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

対象となる内容

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

前提条件

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

2. BigQuery Export へのアクセス

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

1aa4e20bfd3419d1.png

クエリを実行する

BigQuery に移動すると、生成された日次テーブルが表示されます。以下のスクリーンショットの例では、64 個の 1 日ごとのテーブルが表示されているため、エクスポートは 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 で使用できる ID は 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'

このクエリに関する注意事項

  • テーブル名は、アナリティクスからエクスポートしたテーブルに置き換えてください。ワイルドカード を使用して、複数の 1 日あたりのテーブルにクエリを実行できます。たとえば、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 つのクエリを実行しました。1 つはアプリをインストールして開いたユーザーのデータを見つけるためのクエリで、もう 1 つはこれらのユーザーの収益を見つけるためのクエリです。SKAd Network の制限について、これまでに説明した内容を振り返ってみましょう。アトリビューション期間は、インストール後 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 に変更すると、LOW、MEDIUM、HIGH のしきい値を取得できます。

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 広告でキャンペーンを実施し、SKAd Network コンバージョン値スキーマで影響を測定している場合は、以下の推奨事項をご確認ください。

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

4fd625aae9d4a43.png

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

6c7a4d703567700a.png

5. 完了

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

学習した内容

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