data-warehouse-experimentation について
成熟したデータチーム向けのデータウェアハウスネイティブ実験スキルです。専用プラットフォームではなく既存のデータスタックで実験を行う方法として、割り当て、露出ログ、dbt の指標、SQL または Python による統計分析を扱います。
主な機能
- 01ウェアハウスネイティブ方式の適合性評価
- 02ハッシュ、フラグ、テーブルによる割り当て
- 03ユーザーの初回露出イベントの記録
- 04dbt モデルでの実験指標の定義
- 05SQL または Python による結果分析
活用シーン
- 01ウェアハウスネイティブ実験基盤の構築
- 02既存の実験データフローの監査
- 03プラットフォームで扱えない指標やセグメントの分析
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rampstackco/ claude-skills --skill data-warehouse-experimentationインストール後、Claude Code で/data-warehouse-experimentationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdreferences/assignment-and-exposure-patterns.mdcommon-pitfalls.mdmetric-definitions-in-dbt.mdpower-analysis-calculations.mdsequential-testing-patterns.mdstatistical-analysis-templates.mdvariance-reduction-techniques.mdwarehouse-vs-platform-decision.md詳細
データウェアハウスでの実験
BigQuery、Snowflake、またはその他の最新データウェアハウス上でネイティブに実験を実施するための、シニアデータサイエンティスト向けプレイブックです。メトリクス定義には dbt を、統計分析には SQL または Python を使用します。
大規模に実験を実施する企業の多くは、専用プラットフォームを利用しています。Statsig、Optimizely、実験機能を備えた LaunchDarkly、PostHog、Amplitude Experiment などです。これらのプラットフォームは優れています。割り当て、計測、分析を1つのプロダクトで処理できるため、SQLに精通したデータチームが分散低減の仕組みを一から作り直す必要がありません。
一方で、成熟したデータチームがますます採用する別の運用モデルがあります。それが、データウェアハウスネイティブの実験です。割り当てはコード内で、またはフィーチャーフラグを使って行います。曝露イベントは、ほかのイベントと同様にデータウェアハウスへ送信されます。メトリクスは dbt モデルとして定義します。統計分析は、データウェアハウスのデータを対象に SQL または Python ノートブックで実行します。「実験プラットフォーム」となるのは、既存のデータスタックだけです。
このスキルでは、データウェアハウスネイティブが適切なケース、アーキテクチャ、そして実現に役立つ具体的な手法を解説します。割り当てのパターン、曝露ログ記録の徹底、dbt でのメトリクス定義、SQL での t 検定と CUPED、逐次検定、そして自前の仕組みを破綻させる落とし穴などが含まれます。
このスキルを使う場面:プラットフォームとデータウェアハウスネイティブのどちらを選ぶかを判断するとき、データウェアハウスネイティブの実験基盤を構築するとき、既存の基盤を監査するとき、または、標準のプラットフォームではカスタムメトリクスやセグメンテーションに対応できない場合に特定の実験を実施するときです。
このスキルの用途
このスキルは、データウェアハウスネイティブの実験を運用・実行する方法を扱います。方法論や解釈に関するスキルに取って代わるものではなく、それらと組み合わせて使います。
experiment-designは方法論を扱います。仮説、サンプルサイズ、ランダム化単位、主要メトリクスなどです。特定のツールに依存しません。実験を実施する場所にかかわらず、適切に設計するため、最初に読んでください。experimentation-analyticsは結果の解釈を扱います。信頼区間、p 値、効果量、意思決定のフレームワークなどです。特定のツールに依存しません。結果が出たら読んでください。experimentation-platform-orchestratorは、プラットフォームとデータウェアハウスのどちらを選ぶかを詳しく扱います。プラットフォームを使うか、このスキルを使うか判断する際に読んでください。feature-flaggingは、プラットフォームを経由しない場合の割り当て基盤を扱います。このスキルが前提とするフラグ管理の徹底については、こちらを読んでください。- このスキル(
data-warehouse-experimentation)は、運用・実行の方法を扱います。SQL ベースの割り当て、曝露ログ記録、dbt でのメトリクス定義、SQL または Python での統計分析、分散低減、逐次検定などです。
ここでの違いは、「何をするか」(方法論や解釈に関するスキル)と「ベンダープラットフォームを使わずにどう実行するか」(このスキル)です。データウェアハウスネイティブが適切だと判断した後に、このスキルを読んでください。まだ判断中の場合は、まず experimentation-platform-orchestrator を読んでください。
ウェアハウスネイティブが適している場合
6つの要因が、ウェアハウスネイティブを選ぶ判断を後押しします。
- 大量利用時のコスト。 プラットフォームはMAUまたはイベント数に応じて課金します。MAUが1万ならプラットフォームは安価ですが、MAUが100万になると、請求額は無視できない予算項目になります。ウェアハウスネイティブは、すでに料金を支払っているインフラ上で動作します。
- カスタム指標。 主要指標が複雑なビジネス指標(返金を考慮したロジックによる売上、コホートLTV、リテンションの区分、複数イベントの複合指標)の場合、プラットフォームでは対応が難しいことがあります。ウェアハウスネイティブでは、SQLで記述できるあらゆる指標を表現できます。
- カスタムセグメンテーション。 エンタープライズ顧客、アカウント階層をまたいだ分析、複雑な行動セグメントなどです。プラットフォームにもセグメンテーション機能はありますが、その詳細度はさまざまです。dbtモデルなら制限なく組み合わせられます。
- 信頼性に関する要件。 規制対象の業界(医療、金融、政府)では、計算の完全な透明性が必要です。ウェアハウスネイティブなら、計算のあらゆる手順をSQLで監査できます。
- 既存のデータチームの強さ。 データエンジニアやデータサイエンティストがいるなら、インフラの大部分はすでに整っています。その上に実験の規律を加えるほうが、新しいプラットフォームを導入するよりも低コストです。
- 指標定義の反復。 プラットフォームでは、指標の更新はプラットフォーム側のペースで行われます。ウェアハウスネイティブなら、dbtのデプロイと同じ速さで反復できます。
5つの要因が、プラットフォームを選ぶ判断を後押しします。
- フロントエンドのビジュアル実験。 Optimizelyの得意分野です。スクリプトタグでバリアントのコードを挿入し、WYSIWYG編集ができます。
- 1週間未満での反復速度。 プラットフォームによっては30分で実験を設定できますが、ウェアハウスネイティブでは、新しい指標パターンの初回実行に1日以上かかることもよくあります。
- 強固なデータ基盤を持たないチーム。 ウェアハウス、dbt、アナリストがいない場合は、ウェアハウスネイティブから始めないでください。プラットフォームが適切な選択です。
- モバイル実験。 オフライン対応のSDKベースの割り当てはプラットフォームの役割であり、ウェアハウスの役割ではありません。
- 厳格な保証を備えた、すぐに使える逐次検定。 StatsigとEppoは、調整済みのアルファ消費を伴うmSPRTを提供しています。これを社内で構築するには、かなりの作業が必要です。
詳細と意思決定ツリーについては、references/warehouse-vs-platform-decision.mdを参照してください。成熟したチームの多くは両方を使い分け、難しいケースにはウェアハウスネイティブを、標準的な実験の迅速な反復にはプラットフォームを利用しています。
アーキテクチャ
データの流れに沿った4つのコンポーネントです。
- 割り当て。 ユーザーをどのようにバリアントに振り分けるかです。ハッシュ関数、フィーチャーフラグ、またはランダム化された割り当てテーブルを使います。
- エクスポージャーログ。 ユーザーが実験に初めてさらされたときに発行される個別イベントです。他のイベントと同様にウェアハウスに書き込まれます。
- 指標定義。 ウェアハウスのイベントから主要指標と副次指標を算出するSQLクエリ(またはdbtモデル)です。
- 分析。 エクスポージャーと指標を結合し、信頼区間を伴う効果推定値を出す、SQLまたはPythonによる統計計算です。
データの流れは次のとおりです。ユーザーがプロダクトを訪れます。割り当てによってバケット(コントロールまたはトリートメント)が決まります。ユーザーがバリアントにさらされると(トリートメント固有の挙動を目にすると)、エクスポージャーイベントがウェアハウスに送信されます。ユーザーがアクションを起こすと、同じウェアハウスに指標イベントが生成されます。分析時には、割り当て単位(通常はuser_id)をキーにエクスポージャーを指標と結合します。分析ではリフトを計算し、判断を導きます。
エクスポージャーイベントのパターンは非常に重要です。これがないと、計算できるのは「インテント・トゥ・トリート」分析(バリアントを見たかどうかにかかわらず、割り当てられた全員を対象とする分析)だけです。これがあれば、実際にバリアントを体験したユーザー集団を対象とする「エクスポージャー」分析を計算できます。通常は後者が望ましく、特にバリアントが割り当てられたユーザーの一部(たとえば、特定のページに到達したユーザー)にのみ影響する場合に有効です。
割り当てパターン
3つのアプローチがあります。
決定論的ハッシュによる割り当て。 ウェアハウスネイティブの場合のデフォルトです。
MOD(ABS(FARM_FINGERPRINT(CONCAT(user_id, 'exp_button_color_v1'))), 100) < 50
ソルト('exp_button_color_v1')を使うことで、同じユーザーでも異なる実験では相関のない割り当てが生成されます。再現性があり(同じ入力からは常に同じバケットが生成されます)、サービスへの依存がなく、実験ごとにソルトを分離できます。割り当ては任意の SQL クエリ内で直接計算できます。
フィーチャーフラグによる割り当て。 フィーチャーフラグサービス(LaunchDarkly、Statsig flags、Unleash、社内サービス)でバケット分けを行い、ウェアハウスにはフラグサービスが決定した割り当てを記録します。
-- Read assignment from the flag service's logs
SELECT user_id, variant_id, assigned_at
FROM flag_service.assignments
WHERE flag_key = 'exp_button_color_v1'
フラグサービスが割り当ての信頼できる情報源であり、ウェアハウスが割り当てテーブルをミラーリングする場合に有効です。SQL で再現するのが不便なフラグサービスのルール(例:段階的な割合ロールアウト、ターゲティングルール)に割り当てを従わせる必要がある場合に便利です。
ランダム化した割り当てテーブル。 実験開始時にユーザーをテーブルへランダムに割り当てます。
CREATE TABLE exp_button_color_v1_assignments AS
SELECT
user_id,
CASE WHEN RAND() < 0.5 THEN 'control' ELSE 'treatment' END AS variant_id
FROM dim_users
WHERE eligible = true;
あまり一般的ではありませんが、実験開始時に適格ユーザーの集合が確定していて、割り当てを決定論的かつ明示的にしたい場合(例:コンプライアンス監査)に便利です。デメリットは、実験の途中で参加した新規ユーザーがテーブルに含まれないことです。その場合は、対象から外すか、ハッシュによる割り当てにフォールバックします。
決定論的ハッシュによるアプローチは、サービスへの依存がなく、安定した監査可能な割り当てを生成するため、ウェアハウスネイティブの場合のデフォルトです。詳しくは references/assignment-and-exposure-patterns.md を参照してください。
エクスポージャーログ
ウェアハウスネイティブな実験で、最も重要な規律です。
必須のエクスポージャーイベントスキーマ:
| フィールド | 型 | 備考 |
|---|---|---|
experiment_id | 文字列 | 実験ごとの一意な識別子です。 |
variant_id | 文字列 | ユーザーが割り当てられたバリアントです。 |
user_id | 文字列 | 割り当ての単位です。 |
exposed_at | タイムスタンプ | ISO 8601 UTC 形式です。エクスポージャーが発生した時刻です。 |
context_* | さまざま | デバイス、ページ、account_id などの任意のコンテキストプロパティです。 |
ユーザーがバリアント固有の動作を実際に見たタイミングで、正確にエクスポージャーを記録します。ページの読み込み時ではありません。セッション開始時でもありません。アプリの起動時でもありません。
「エクスポージャーの遅延」の落とし穴。バリアントの影響がボタンのクリック時にしか現れないのに、ページの読み込み時にエクスポージャーを記録すると、ユーザーが実際にバリアントを見たかどうかにかかわらず、ページを読み込んだすべてのユーザーが分析対象になります。コントロールグループにもボタンまで到達しなかったユーザーが含まれます。トリートメントグループも同様です。その結果、分析では実際の効果が薄まります。
具体例。トリートメントでは新しい料金ページを、コントロールでは古い料金ページを表示します。ユーザーがホームページに到達した時ではなく、料金ページが読み込まれた時にエクスポージャーを記録します。料金ページに到達しなかったユーザーはどちらのバリアントにもエクスポージャーしていないため、分析対象に含めるべきではありません。
「常時記録」の落とし穴。一部の実装では、バリアント固有の操作が行われるたびにエクスポージャーを記録します。ユーザーがボタンを5回クリックすると、エクスポージャーが5回記録されます。エクスポージャーログが本来の5倍の大きさになります。エクスポージャー内の distinct user_id を数える分析ツールでは正しく処理できますが、行数を数えるツールでは正しく処理できません。
守るべき規律。実験ごとにユーザーあたり1件だけ、バリアント固有のエクスポージャーが初めて発生した時点で、正確にエクスポージャーイベントを記録します。クライアントの決定論的フラグ(またはサーバー側のキャッシュ)を使って、一度だけ記録されるようにします。詳しくは references/assignment-and-exposure-patterns.md を参照してください。
dbt モデルでの指標の定義
指標を dbt モデルとして定義すると、次の 4 つのメリットがあります。
- 指標定義のバージョン管理。 指標への変更はすべて git のコミットになります。変更履歴をクエリできます。
- テスト可能性。 指標の出力に対する dbt テストで、リグレッションを検出できます。
- 合成可能性。 同じ
fct_ordersモデルを、ボードダッシュボード、実験分析、経営陣向けレポートで使用できます。定義が統一され、乖離しません。 - 信頼できる唯一の情報源。 実験では X、ボードでは Y と示された場合、答えは互いに無関係な 2 つの SQL ファイルではなく、dbt モデルにあります。
パターンです。
-- models/experiments/exp_metrics_revenue.sql
SELECT
user_id,
SUM(CASE WHEN refunded THEN 0 ELSE amount_cents END) AS net_revenue_cents,
MIN(occurred_at) AS first_purchase_at
FROM {{ ref('fct_orders') }}
WHERE occurred_at >= '{{ var("experiment_start") }}'
GROUP BY user_id
実験分析では、これを user_id で曝露ログに結合し、グループ平均を計算します。
分散を防ぐためのルールです。同じ指標定義を、ボードダッシュボードと実験分析の両方で使用します。わずかに異なる「実験専用の収益計算」は行いません。そうしないと、「実験では収益が増加したと言っているのに、ボードでは変化がない」という問題が発生します。これはほとんどの場合、指標定義の不一致が原因です。
名前空間のパターンです。user_id でグループ化し、ユーザーごとに 1 行を出力する実験用モデルには exp_metrics_* を使用します。指標モデルとダッシュボードの両方にデータを提供する基盤のファクトテーブルには fct_* を使用します。詳細は references/metric-definitions-in-dbt.md を参照してください。
SQL での統計分析
SQL で行う、基本的な 2 標本 Welch の t 検定です。
WITH metric_by_variant AS (
SELECT
e.variant_id,
COUNT(*) AS n,
AVG(m.net_revenue_cents) AS mean,
VAR_SAMP(m.net_revenue_cents) AS variance
FROM exposures e
LEFT JOIN exp_metrics_revenue m USING (user_id)
WHERE e.experiment_id = 'exp_button_color_v1'
GROUP BY e.variant_id
)
SELECT
control.mean AS control_mean,
treatment.mean AS treatment_mean,
treatment.mean - control.mean AS absolute_lift,
(treatment.mean - control.mean) / NULLIF(control.mean, 0) AS relative_lift,
-- Welch's t-statistic
(treatment.mean - control.mean) /
SQRT(treatment.variance / treatment.n + control.variance / control.n)
AS t_statistic
FROM
(SELECT * FROM metric_by_variant WHERE variant_id = 'control') control,
(SELECT * FROM metric_by_variant WHERE variant_id = 'treatment') treatment
t 統計量を p 値または信頼区間に変換するには、SQL 関数(BigQuery:UDF、Snowflake:組み込み関数またはストアドプロシージャ)を使うか、SQL クエリの結果を Python で計算します。
この SQL パターンは、連続指標に対する単純な t 検定には適しています。比率の検定では、分散を p * (1 - p) に置き換えます。ノンパラメトリック検定(Mann-Whitney)では SQL がすぐに複雑になるため、Python に切り替えてください。
単純な t 検定より複雑な分析(CUPED、ブートストラップ、二重ロバスト推定、逐次検定)は、Python のほうが簡単です。SUM と AVG の集計には SQL を使い、結果を Python に渡して統計計算を行います。詳細は references/statistical-analysis-templates.md を参照してください。
Python での統計分析
通常は Jupyter または Hex のノートブックで行う、Python のパターンです。
import pandas as pd
import numpy as np
from scipy import stats
# Pull aggregated data from the warehouse
df = warehouse.query("""
SELECT user_id, variant_id, net_revenue_cents
FROM exp_results
WHERE experiment_id = 'exp_button_color_v1'
""")
control = df[df.variant_id == 'control'].net_revenue_cents
treatment = df[df.variant_id == 'treatment'].net_revenue_cents
# Welch's t-test
t, p = stats.ttest_ind(treatment, control, equal_var=False)
# Confidence interval on the mean difference
diff = treatment.mean() - control.mean()
se = np.sqrt(treatment.var() / len(treatment) + control.var() / len(control))
ci_low, ci_high = diff - 1.96 * se, diff + 1.96 * se
print(f"Lift: {diff:.2f} cents (95% CI: [{ci_low:.2f}, {ci_high:.2f}])")
print(f"p-value: {p:.4f}")
Python を使うと、SQL では簡単に表現できない手法に対応した、統計処理のエコシステム(scipy、statsmodels、numpy)を利用できます。
ノートブックのパターンです。実験ごとに 1 つのノートブックを作成し、experiment_id をパラメーターとして指定します。git または Hex プロジェクトでバージョン管理します。各ノートブックの最後に、分析結果をまとめた意思決定ドキュメントを作成し、クエリ可能なリポジトリ(Notion、GitHub の Markdown、またはウェアハウス内の専用実験結果テーブル)に保管します。
詳細とブートストラップのテンプレートは references/statistical-analysis-templates.md を参照してください。
分散削減:CUPED とその先
データウェアハウスネイティブな実験において、最も強力な分散削減手法が CUPED(Controlled-experiment Using Pre-Experiment Data)です。Microsoft が考案しました。
考え方はこうです。実験前のデータからユーザーの指標の挙動を予測できるなら、その予測された分散を差し引き、検定対象となる残差を小さくできます。
# Pre-experiment metric for each user (e.g., last 28 days revenue)
pre = pre_period_revenue(user_id)
# Theta is the regression coefficient of the metric on the pre-period
theta = np.cov(metric, pre)[0, 1] / np.var(pre)
# Adjusted metric
adjusted_metric = metric - theta * (pre - pre.mean())
生の指標ではなく、調整済みの指標に対して t 検定を実施します。平均値は保たれます(CUPED は点推定値を変えません)が、分散が小さくなるため、信頼区間の幅が狭くなります。
CUPED によって、エンゲージメント指標の分散は通常 30~50 パーセント削減されます。これは、同じ統計的検出力を得るために実験を 1.5~2 倍長く実施するのと同等です。四半期に 5 件以上の実験を実施するチームであれば、エンジニアリングへの投資に見合います。
その他の分散削減手法。
- 層別化。 実験前の共変量(セグメント、地域、デバイス)で分析を分割し、各層の推定値を統合します。共変量が指標を強く予測する場合に有効です。
- 回帰調整。 共変量を使って OLS 回帰を当てはめます。残差分析では分散が小さくなります。CUPED を複数の共変量に一般化した手法です。
- 二重ロバスト推定。 結果のモデリングと傾向スコアによる重み付けを組み合わせます。ランダム化が不完全だった観察研究や準実験の状況で有効です。一般的な A/B テストの範囲外ですが、分散削減の参考ファイルに学術的な参考文献を記載しています。
実例を含む詳細は、references/variance-reduction-techniques.md をご覧ください。
実験前の検出力分析
実験を開始する前に、必要なサンプルサイズを計算します。
from statsmodels.stats.power import tt_ind_solve_power
# Solve for sample size given desired MDE
n_per_arm = tt_ind_solve_power(
effect_size=0.05, # Cohen's d
nobs1=None,
alpha=0.05,
power=0.8
)
# Or solve for MDE given sample size
mde = tt_ind_solve_power(
effect_size=None,
nobs1=8000,
alpha=0.05,
power=0.8
)
「想定より 10 倍多くのユーザーが必要」という教訓です。検出力不足の実験の多くは、効果量を楽観的に想定したことが原因です。チームは 10%のリフトを期待して実験を設計しますが、実際の効果は 1%で、計画したサンプルサイズでは検出できません。その結果、実験がいつまでも終わらないか、結論が出ないまま終了します。
解決策は、過去の実験で観測された効果の分布に基づいて、現実的な MDE の期待値を設定することです。直近 30 件の実験で観測された効果の中央値が 0.5%なら、新しい実験では MDE を 0.5%として計画します。楽観視の非対称性は実際に存在します。これを正すには、望ましい効果の分布ではなく、実際の効果の分布を見る必要があります。
詳細は、references/power-analysis-calculations.md をご覧ください。
順次検定のパターン
「のぞき見」の問題です。実験の完了前に結果を見ると、偽陽性率が上昇します。単純な解決策は「のぞき見しない」ことです。実践的な解決策は、有効な早期終了を可能にする順次検定の手法です。
3つのアプローチがあります。
- mSPRT(mixture Sequential Probability Ratio Test)。Optimizely と Statsig で使用されています。のぞき見をしても有効性が保たれる、常に有効な p 値を提供します。Python では
statsmodelsまたは独自コードで実装できますが、SQL には標準搭載されていません。 - 信頼系列を用いる Always-Valid Inference。Howard らによる手法です。任意のサンプルサイズで有効な信頼区間を提供します。実装には慎重な Python のコーディングが必要です。論文を読んでいないデータチーム向けではありません。
- 群逐次デザイン(O'Brien-Fleming 境界)。事前に指定した中間解析の時点で、調整済みのアルファ消費を行います。古典的な頻度論的アプローチです。
データウェアハウスネイティブな方法として実践的に推奨するのは、Python での mSPRT です。使用したアルファ消費関数を文書化してください。チームメンバー1人に数学を習得してもらい、ブラックボックスの実装に頼らないでください。
率直に言うと、チームに順次検定の数学を理解している人がいない場合は、のぞき見をしないでください。サンプルサイズを事前登録し、最後まで実行して、分析は一度だけ行ってください。順次検定は正しく実装した場合にのみ統計的に正しいものです。誤った実装は、のぞき見をしない運用をまったくしないよりも悪い結果になります。
詳細は references/sequential-testing-patterns.md を参照してください。
よくある落とし穴
データウェアハウスネイティブな実験では、11のパターンが繰り返し発生します。詳細は references/common-pitfalls.md を参照してください。
- 「露出ログはページ読み込み時に記録されます。」ページ読み込み時ではなく、バリアント固有の動作が表示された時点で記録する必要があります。「露出の遅延」という落とし穴により、効果が薄まります。
- 「コントロール群ではリフトが見られますが、トリートメント群では見られません。」割り当てハッシュの衝突、またはソルトの再利用が原因です。ソルトを監査し、同じユーザーに対して異なる実験で異なるバケット割り当てが生成されることを確認してください。
- 「p 値は 0.04 です。リリースしましょう。」検出力不足に多重比較とのぞき見が重なっている可能性が高いです。計画したサンプルサイズでのみ検定を行い、複数の副次指標について補正してください。
- 「実験で 30% のリフトが示されました。」ほぼ間違いなくバグです。このように大きな効果が存在することはまれです。喜ぶ前に、まず露出ログと指標の定義を監査してください。
- 「トリートメント群のユーザーは異なります。」サンプル比率の不一致(SRM)です。割り当てハッシュが壊れているか、露出ログに偏りがあります。指標を計算する前に SRM を確認してください。
- 「昨日の数値を再現できません。」明示的な ORDER BY のないウィンドウ関数、シードなしのサンプリングなど、非決定的なクエリや、集計での浮動小数点の問題が原因です。クエリを決定的にし、乱数シードを使用する場合は文書化してください。
- 「カスタム指標の定義がダッシュボードの指標と一致しません。」問題です。同じ dbt モデルを使用して定義を揃えてください。そうしないと、誰もどちらの数値も信用しなくなります。
- 「実験がいつまでも終わりませんでした。」終了基準を事前登録し、それを守ってください。いつまでも続く実験はチームの時間を無駄にし、判断を曖昧にします。
- 「トリートメント群では iOS ユーザーのコンバージョンが3倍になりました。」セグメント効果か、計測のバグです。iOS の計測方法が他と異なるか確認してください。小さなセグメントについて過剰に主張しないよう注意してください。
- 「フェーズ1ではうまくいきましたが、フェーズ2では崩れました。」コホート構成の変化によるシンプソンのパラドックスです。フェーズごとに基礎となるセグメントの重み付けが異なると、集計値の傾向が逆転します。
- 「統計的有意性はありますが、効果はわずかです。」サンプル数が多いため、検出力が高くなっています。p 値は 0.05 未満ですが、効果は 0.3% です。実務上の有意性を検討してください。0.3% のためにリリースする価値はありますか?
フレームワーク:データウェアハウスネイティブな実験のための12の考慮事項
データウェアハウスネイティブな実験を設計または実施する際は、次の12項目を確認してください。
- プラットフォームとデータウェアハウスの選択。 コスト、カスタム指標、セグメンテーション、信頼性、チームの能力を考慮します。決めかねている場合は、
experimentation-platform-orchestratorをご覧ください。 - 割り当て単位。 ユーザー、アカウント、セッション、デバイスから選びます。実験の開始時に一度選択し、途中で変えないでください。
- 割り当てソルト。 以前の実験との相関を防ぐため、実験ごとに一意の値を使います。ソルトの規則を文書化してください。
- エクスポージャーログの運用規律。 ページ読み込み時ではなく、バリアントが意味を持つタイミングで記録します。実験ごとにユーザーあたり1件のエクスポージャーイベントを記録してください。
- SRMチェック。 サンプル比率の不一致は割り当てのバグを示します。指標の計算前に必ず確認してください。
- 指標定義の再利用。 ダッシュボードと実験で同じ dbt モデルを使います。標準指標から乖離する、実験固有の計算は行わないでください。
- 実験前の検出力分析。 過去に観測された効果の実際の分布に基づいて、現実的なMDEを設定します。
- 分散の低減。 エンゲージメント指標にはCUPEDを使います。四半期に5件以上の実験を実施するチームであれば、分散を30~50%低減できるなら、エンジニアリングに投資する価値があります。
- 統計手法。 デフォルトではWelchのt検定を使います。歪んだ分布にはブートストラップを、準実験には二重ロバスト推定を使います。
- 逐次検定。 mSPRTまたはN時点での停止を使います。アルファ消費を文書化してください。正しく実装できない場合は、途中で結果を確認しないでください。
- 多重比較。 副次指標全体にボンフェローニ補正またはBenjamini-Hochberg補正を適用します。
- 意思決定の文書化。 結果をまとめて、検索可能なリポジトリに保存します。次の実験では、組織に蓄積された知見を活用できます。
このフレームワークの成果物は実験記録です。事前登録したサンプルサイズと停止基準、割り当てソルト、エクスポージャーログの仕様、dbt指標モデル、分析ノートブック、そして文書化された意思決定を含みます。記録はバージョン管理または専用の実験追跡システムに保存し、記録から分析を再現できるようにします。記録に必要な入力が得られない場合は、データ利用可否のルールに従って、その不足を明記してください。
必要なデータを利用できない場合
このスキルの出力は、それ自体では生成できないデータ、測定値、またはツールの結果に依存します。必要な入力、ツール、またはデータソースを利用できない、あるいは検証できない場合、認められる出力は、不足を明記した成果物です。何が必要だったのか、実際に何を取得または検証できたのか、出力のどの部分に影響するのかを記載します。成果物を完成させるために必要な数値を捏造、推定、補間することは、決して認められません。不足を明記すれば、それで完全な回答です。
参考ファイル
references/warehouse-vs-platform-decision.md- それぞれの運用モデルが適しているケース。規模ごとのコスト上の考慮事項。ハイブリッドパターン。移行パターン。references/assignment-and-exposure-patterns.md- BigQuery と Snowflake 向けのハッシュ割り当て SQL テンプレート。ソルトの命名規則。エクスポージャーイベントのスキーマ。SRM チェック SQL。references/metric-definitions-in-dbt.md- 実験メトリクス用の dbt モデルパターン。fct モデルの再利用。exp_metrics 名前空間。バージョン管理。references/statistical-analysis-templates.md- Welch の t 検定、比率検定、Mann-Whitney 検定、ブートストラップ用の SQL および Python テンプレート。ノートブックの構成。references/variance-reduction-techniques.md- 具体例を含む CUPED の計算と Python 実装。層別化。回帰調整。二重ロバスト推定の入門。references/power-analysis-calculations.md- MDE の計算。サンプルサイズの計算。過去の実験データに基づく効果量の仮定の調整。references/sequential-testing-patterns.md- mSPRT、信頼系列、群逐次デザイン。途中で結果を見るべきタイミングについての率直な説明。references/common-pitfalls.md- 11 の失敗パターンと、その診断および対処法。
締めくくり:構築するか購入するかという判断は重要です
ウェアハウスネイティブな実験は強力ですが、エンジニアリングに多くの時間がかかります。実験チームを立ち上げる最初の年は、ほとんどの場合、まずプラットフォームから始めるべきです。プラットフォームがケースの 90 パーセントに対応してくれるため、インフラではなく仮説に集中できます。ウェアハウスネイティブに移行するチームは、実験の量、カスタムメトリクスのニーズ、または信頼性に関する要件が、プラットフォームで提供される範囲を超えたから移行するのです。
「プラットフォームは高すぎる」という理由で、まず計算もせずにウェアハウスネイティブな仕組みを構築しているなら、チームのエンジニアリング時間にかかるコストを過小評価しています。調達申請書では高額に見えるプラットフォーム料金も、データエンジニアが 3 か月かけて CUPED を一から作り直すコストより安く済むことがよくあります。
プラットフォームでは特定のニーズに対応できないという理由で構築しているなら、その判断はおそらく正しく、投資に見合う成果が得られるでしょう。プラットフォームは汎用的ですが、ビジネスには固有の事情があります。プラットフォームでは表現できないカスタムメトリクスこそ、意思決定にとって最も重要な指標であることがよくあります。
現実的な折衷案として、多くの成熟したチームは両方を使っています。結果が出るまでの時間がカスタム性より重要な標準的な実験では、迅速な反復のためにプラットフォームを使います。プラットフォームのメトリクスライブラリやセグメンテーションでは対応できない難しいケースには、ウェアハウスネイティブな仕組みを使います。ハイブリッド運用は複雑になるため、どの実験をどちらで行うかのルールを文書化し、毎年見直してください。