D ビジネス/PM — OKR 設計 × ICE スコアリング × A/B テスト事前登録 × KPI ツリー(GMV 分解)× dbt mart_campaign_kpi_weekly(MOps 意思決定 Bad→Good)

2026-06-18 (Day 73) 木曜 D: ビジネス/PM ★★★★☆ OKR / ICE / A/B テスト / KPI ツリー プロダクト思考 / 意思決定フレームワーク

概要

🎯

OKR: Outcome KR で「活動」でなく「成果」を測る

「売上を上げる」は目標ではなく意図。OKR では KR に数値・ベースライン・期限を必ず含める。「GMV ¥80M → ¥120M(Q3末)」が正しい形。KR が測定不可能だと OKR は飾りになる。

📊

ICE スコアリング: 施策の定量優先順位付け

Impact × Confidence × Ease で 1〜1000 のスコアに変換。「声の大きさ」ではなく数値で施策をランク付けし、ICE ≥ 300 を今スプリントで着手するルールにすることで意思決定会議を 60min → 15min に短縮できる。

🔬

A/B テスト事前登録: HARKing(後知恵仮説)を防止

結果を見てから仮説を立てる「HARKing (Hypothesizing After Results are Known)」は統計的偽陽性を生む。サンプルサイズ・停止規則・成功基準を実施に commit することで再現性のある施策検証が実現する。

🌳

KPI ツリー: GMV を分解してボトルネックを特定

GMV 単一指標では「なぜ下がったか」が分からない。送信数 × 開封率 → クリック数 → CVR × AOV の段階に分解すると、どのプロセスがボトルネックかが週次で一目で分かり、改善レバーを絞り込める。

問題

ECサイト MOps チームで「メールキャンペーン施策の意思決定プロセス」を抜本的に改善したい。現状フローには 7つの設計上の問題 が潜んでいる。問題点を全て洗い出し、OKR 設計・ICE スコアリング・A/B テスト事前登録・KPI ツリー・dbt mart を活用した Bad→Good リファクタリングを行え。

制約・前提条件

  • チーム規模: PdM 1名、エンジニア 3名、マーケター 2名
  • 扱うデータ: メール送信数/開封率/CTR/CVR/AOV/GMV(BigQuery + dbt)
  • 意思決定の頻度: 週次スプリント + 月次戦略レビュー
  • 既存ツール: BigQuery, dbt Core 1.8+, Looker Studio, Argo Workflows, DataDog
期待する回答形式: 問題点の列挙(番号付き)+ 改善後の意思決定フロー設計(OKR / ICE / A/B テスト設計書 / KPI ツリー / dbt mart SQL)

現状フロー (Before)

このフローには 7つのビジネス/PM 設計の問題 が隠れています。
現状の意思決定フロー — 手動集計 / 直感 / 測定不能目標 / 効果測定なし
# ① PdM が月末に売上データを Excel で手動集計(3時間)
# 問題①: データ集計が属人化・遅延。意思決定が最新データで行われない

# ② 施策の優先順位は「声が大きい人」の直感で決定
# 問題②: バイアスが入る。定量的根拠なし

# ③ 目標は「売上を上げる」(抽象的、測定不可能)
# 問題③: KR が測定不可能 → OKR が飾りになる

# ④ 施策リリース後、効果測定なし(次の施策へ)
# 問題④: 何が効いたか蓄積されない。同じ失敗を繰り返す

# ⑤ A/B テストは担当者が Excel で統計計算(p値間違いあり)
# 問題⑤: 手動計算の誤り + HARKing(結果見てから仮説作り)

# ⑥ KPI は GMV のみ追跡(途中プロセスの指標なし)
# 問題⑥: ブラックボックス。「なぜ下がったか」が分からない

# ⑦ 四半期 OKR は「お飾り」で実行に紐づかない
# 問題⑦: OKR と週次スプリントが接続していない
問題点サマリー(7点)
1手動集計による遅延と属人化 — Excel 3時間作業は dbt mart + Looker Studio で自動化。PdM の工数を施策企画に充てる
2施策優先順位の定量根拠欠如 — ICE スコア(Impact × Confidence × Ease)で数値化。ICE ≥ 300 を今スプリント着手ルール
3測定不可能な目標設定 — OKR の KR に「数値・ベースライン・期限」を必須化。「GMV ¥80M→¥120M (Q3末)」が正解形
4A/B テスト事前登録なし(HARKing) — サンプルサイズ・停止規則・成功基準を実施前に GitHub commit
5手動 p値計算の誤り — BigQuery SQL で Z検定を自動化(SAFE_DIVIDE + z_score 計算)
6GMV 単一 KPI によるブラックボックス — KPI ツリーで開封率・CTR・CVR・AOV を可視化。ボトルネック段を特定
7OKR と実行の断絶 — 週次スプリントレビューに KR 進捗確認 15min を必須議題として組み込む

ヒント(段階的開示)

ヒント1 — 方向性
「声が大きい人」の直感意思決定は、証拠に基づく意思決定(Evidence-Based Decision Making)が欠如している。根本は「測定可能な目標・プロセス指標・因果推論の枠組み」が揃っていないこと。OKR・ICE スコア・A/B テスト事前登録の3フレームワークを組み合わせて設計する。
ヒント2 — アプローチ
  • 問題①: 手動集計 → dbt mart_campaign_kpi_weekly + Looker Studio 自動ダッシュボード
  • 問題②: 直感 → ICE スコア(Impact × Confidence × Ease)で定量評価
  • 問題③: 抽象目標 → OKR 設計(KR = 数値・ベースライン・期限の三点セット)
  • 問題④: 効果測定なし → A/B テスト事前登録(仮説・サンプルサイズ・停止規則を先に書く)
  • 問題⑤: 手動 p値 → BigQuery SQL で Z検定自動化
  • 問題⑥: GMV のみ → KPI ツリーで開封率・CTR・CVR・AOV を週次追跡
  • 問題⑦: OKR 乖離 → 週次スプリントに KR 進捗レビュー 15min を組み込む
ヒント3 — 骨格
-- ICE スコア計算式
ICE = Impact(1-10) × Confidence(1-10) × Ease(1-10)

-- 例:
-- 件名 A/B テスト(絵文字有無): Impact=7, Confidence=8, Ease=9 → ICE=504 ✓
-- 新規セグメント開拓:              Impact=9, Confidence=3, Ease=2 → ICE=54  ✗

-- KPI ツリー構造
-- GMV = 送信数 × 開封率 × CTR × CVR × AOV

-- OKR の正しい KR 形式
-- NG: 「メールの品質を向上させる」
-- OK: 「開封率を 2026-Q3末までに 18% → 25% に引き上げる」

問題点分析(7点)

1手動集計による遅延と属人化 — 週次・月次の意思決定が最新データで行われない。PdM の工数を施策企画ではなくデータ整形に浪費
2施策優先順位の定量的根拠欠如 — 「声の大きさ」はバイアスの塊。定量スコアリングが必要
3測定不可能な目標設定 — 「売上を上げる」は KR にならない。数値・期限・ベースラインが必須
4A/B テストの事前登録なし — 結果を見てから仮説を作る(HARKing)と偽陽性率が上がる
5統計計算の手動誤り — Excel での p値計算は誤りが多く、BigQuery SQL に置き換えるべき
6GMV 単一 KPI によるブラックボックス — どのプロセスがボトルネックか分からない
7OKR と実行の断絶 — 四半期 OKR が週次スプリントに紐づいていないと「お飾り」になる

KPI ツリー図(GMV 分解)

KPI ツリー — GMV 分解(MOps メールキャンペーン) GMV 最終指標(¥/週) 開封数 送信数 × 開封率 クリック数 開封数 × CTR CVR × AOV GMV の最終変換 開封率 改善 件名・送信時間・セグメント 送信数 改善 リスト拡張・セグメント追加 CTR 改善 CTA・コンテンツ・パーソナライズ CVR 改善 LP 最適化・クーポン AOV 改善 アップセル dbt: mart_campaign_kpi_weekly.open_rate / sends dbt: mart_campaign_kpi_weekly.ctr dbt: mart_campaign_kpi_weekly.cvr / aov 最終指標 中間指標(KPI ツリー段) 改善レバー dbt mart モデル

模範解答

① 自動データ基盤 — dbt mart_campaign_kpi_weekly

Bad — Excel 手動集計(属人化・遅延)
# 問題①: PdM が毎週 Excel で手動集計(3時間)
# - VLOOKUP でキャンペーン名を結合
# - 開封率を手動で割り算
# - 前週比を手動で計算
#
# 結果: データが1週間遅れ・属人化・PdM の施策企画時間が0になる
Good — dbt mart + Looker Studio 自動化
-- models/mart/mart_campaign_kpi_weekly.sql
-- KPI ツリーの全段指標 + 前週比(WoW)を自動計算
{{
  config(
    materialized   = 'incremental',
    partition_by   = {'field': 'week_start', 'data_type': 'date'},
    cluster_by     = ['campaign_id'],
    on_schema_change = 'fail'   -- スキーマ変更時は明示的にエラー
  )
}}

WITH base AS (
  SELECT
    DATE_TRUNC(sent_at, WEEK(MONDAY))              AS week_start,
    campaign_id,
    COUNT(*)                                        AS sends,
    COUNTIF(opened_at IS NOT NULL)                  AS opens,
    COUNTIF(clicked_at IS NOT NULL)                 AS clicks,
    COUNTIF(converted_at IS NOT NULL)               AS conversions,
    SUM(IF(converted_at IS NOT NULL, order_amount, 0)) AS gmv
  FROM {{ source('mops', 'email_events') }}
  {% if is_incremental() %}
    -- 過去2週ルックバック(遅延データを補正)
    WHERE sent_at >= DATE_SUB(
      DATE_TRUNC(CURRENT_DATE(), WEEK(MONDAY)), INTERVAL 2 WEEK
    )
  {% endif %}
  GROUP BY 1, 2
)
SELECT
  week_start,
  campaign_id,
  sends,
  opens,
  clicks,
  conversions,
  gmv,
  -- KPI ツリー各段の中間指標(SAFE_DIVIDE で ZeroDivision ガード)
  SAFE_DIVIDE(opens,       sends)       AS open_rate,  -- 開封率
  SAFE_DIVIDE(clicks,      opens)       AS ctr,        -- クリック率
  SAFE_DIVIDE(conversions, clicks)      AS cvr,        -- コンバージョン率
  SAFE_DIVIDE(gmv,         conversions) AS aov,        -- 平均注文単価
  -- 前週比(LAG ウィンドウ関数)
  SAFE_DIVIDE(
    gmv - LAG(gmv) OVER (PARTITION BY campaign_id ORDER BY week_start),
    LAG(gmv) OVER (PARTITION BY campaign_id ORDER BY week_start)
  )                                     AS wow_gmv     -- GMV 前週比
FROM base

② 施策優先順位 — ICE スコアリングフォーマット

Bad — 「声の大きい人」で施策決定
# 問題②: 施策会議での会話例
# マーケター A「件名を変えればいいんじゃないですか」
# マーケター B「いや、やっぱり送信頻度を増やすべき」
# PdM「では両方やりましょう」(根拠なし、工数∞)
#
# 結果: 工数分散・優先順位なし・効果不明
Good — ICE スコア定量優先順位付け
## 施策評価シート(2026-06-18 Sprint #73)

| 施策 | Impact | Confidence | Ease | ICE | 仮説 | 成功 KR |
|------|:------:|:----------:|:----:|:---:|------|---------|
| 件名 A/B テスト(絵文字) | 7 | 8 | 9 | 504 | 絵文字で開封率+3pt | 開封率 22%→25% (2w) |
| 送信時刻パーソナライズ    | 6 | 5 | 6 | 180 | 受信直後 CTR+2pt | CTR 8%→10% (4w) |
| 新規セグメント(休眠顧客)| 9 | 3 | 2 |  54 | 3ヶ月離脱顧客の再活性 | CVR 1%→1.5% (8w) |

# ICE ≥ 300: 今スプリントで着手(件名 A/B テスト)
# ICE 100-299: 来スプリントに検討
# ICE < 100: バックログへ移動(根拠が弱い → Confidence を上げてから再評価)

# ICE = Impact(1-10) × Confidence(1-10) × Ease(1-10)
# ポイント: Confidence が低い施策は小規模プロトで確認してから再評価

③ OKR 設計(測定可能な KR)

## Q3 2026 OKR — MOps メールチャネル

Objective: MOps メールチャネルを「顧客に届く」主力チャネルに変える

  KR-1: GMV を 2026-Q3末までに ¥80M → ¥120M(+50%)に引き上げる
  KR-2: 開封率を 2026-Q3末までに 18% → 25% に引き上げる
  KR-3: CVR を 2026-Q3末までに 5.2% → 7.5% に引き上げる
  KR-4: A/B テスト実施数を週1本以上に増やす(Q3合計 ≥ 13本)

## OKR アンチパターン(NG の KR)
# ❌ 「メールの品質を向上させる」  → 測定不可能
# ❌ 「施策を積極的に推進する」    → 活動(Output)であり成果(Outcome)でない
# ❌ 「A/B テストを頑張る」         → 数値・期限なし

## 正しい KR の書き方
# ✅ 「[指標] を [ベースライン] から [目標値] に引き上げる(by [期限])」

④ A/B テスト事前登録フォーマット(HARKing 防止)

## A/B テスト設計書(必ず実施前に GitHub commit)
# ファイル: experiments/exp_emoji_subject_2026q3.md

実験ID: exp_emoji_subject_2026q3
登録日: 2026-06-18(← 実施前に commit することが証明になる)

### 仮説
件名に絵文字を追加することで、開封率が +3pt 向上する
(ベースライン: 22%、目標: 25%)

### 介入
- Control:   「今週限定クーポン」
- Treatment: 「🎁 今週限定クーポン」

### 主要指標 / 副次指標
- Primary: 開封率
- Secondary: CTR(クリック率)
- Guardrail: 配信停止率 ≤ 0.5%(悪化しないことを確認)

### 統計設計
- 最小検出差(MDE): 3pt(絶対値)
- 検出力(Power): 80%
- 有意水準(α): 0.05(両側検定)
- 必要サンプルサイズ: 各群 3,500通(BigQuery で power analysis 済)

### 停止規則
- 7日間 OR サンプルサイズ到達(どちらか先に達した方)
- 早期停止禁止(バノーニ補正なしの常時監視は偽陽性を生む)

### 成功基準
- p < 0.05 かつ open_rate_diff > 0.02(統計的 + 実用的 両方の有意性)

⑤ BigQuery A/B テスト自動集計(Z検定 SQL)

Bad — Excel での手動 p値計算(誤り多発)
# 問題⑤: Excel TTEST 関数を手動で入力
# → 引数の順序間違い・片側/両側の混同・繰り返し回数の誤設定
# → 「有意差あり」と誤判断してロールアウト → 本番で再現しない
Good — BigQuery SQL で Z検定を自動化
-- mart/ab_test_results.sql
-- 大標本(n ≥ 30)の2標本 Z検定(中心極限定理)
WITH stats AS (
  SELECT
    variant,
    COUNT(*)             AS n,
    AVG(opened)          AS mean_open_rate,
    STDDEV_SAMP(opened)  AS std_open_rate
  FROM mart.ab_test_email_opens
  WHERE experiment_id = 'exp_emoji_subject_2026q3'
  GROUP BY variant
),
-- Control と Treatment を横並びに
control   AS (SELECT * FROM stats WHERE variant = 'control'),
treatment AS (SELECT * FROM stats WHERE variant = 'treatment'),
-- Z検定計算
z_test AS (
  SELECT
    t.mean_open_rate - c.mean_open_rate AS lift,
    SAFE_DIVIDE(
      t.mean_open_rate - c.mean_open_rate,
      SQRT(
        SAFE_DIVIDE(c.std_open_rate * c.std_open_rate, c.n) +
        SAFE_DIVIDE(t.std_open_rate * t.std_open_rate, t.n)
      )
    ) AS z_score,  -- |z| > 1.96 で p < 0.05(両側)
    c.n AS n_control,
    t.n AS n_treatment
  FROM control c, treatment t
)
SELECT
  lift,                                              -- 差分(絶対値)
  z_score,                                           -- Z統計量
  n_control,
  n_treatment,
  IF(ABS(z_score) > 1.96 AND ABS(lift) > 0.02,
     '✅ 有意差あり(採用)',
     '❌ 有意差なし(継続 or 中止)') AS conclusion  -- 統計的+実用的有意性
FROM z_test

⑦ OKR ↔ スプリント週次マッピング

## 週次スプリントレビュー議題(必須 15min — 毎週月曜)

### 1. KR 進捗確認(各 KR の現在値/目標値/トレンド)
   KR-1: GMV ¥○○M / ¥120M(○%達成)↑↓
   KR-2: 開封率 ○% / 25%(トレンド: ↑↓)
   KR-3: CVR ○% / 7.5%(トレンド: ↑↓)
   KR-4: A/B テスト本数 ○本 / 13本(週1本ペース確認)

   ※ Looker Studio ダッシュボードに KR ターゲットラインを重ねて表示 → 2クリックで確認

### 2. 今週完了施策の ICE vs 実績乖離
   施策名: ○○ | ICE予測: 504 | 実績: open_rate +1.2pt(乖離の原因分析)

### 3. 来週着手施策の選定(ICE ≥ 300 から選ぶ)

### 4. A/B テスト状況
   実施中: exp_emoji_subject_2026q3(残 3日 / 現在 n=2,100)
   完了: exp_send_time_opt → 有意差なし → バックログへ

## エスカレーションルール
# KR 進捗が2週連続で前進なし → ブロッカー特定 + PdM ↔ EM でスコープ見直し

ポイント解説

⚠️

ICE スコアリングの限界

ICE は相対比較ツールであり絶対的な正解ではない。「Confidence」が低い施策は小規模プロトタイプで確信度を上げてから再評価すること。ICE が高くても「前提仮説が間違っている」場合は全て水の泡になる。

🎯

Output KR vs Outcome KR

「A/B テストを週1本実施する」は Output KR(活動量)。KR-1〜3 は Outcome KR(成果)。Output KR だけでは事業価値が測れないため、必ず Outcome KR とセットにする。KR-4 は Output だが「実験文化の醸成」を測る指標として例外的に有効。

🔬

停止規則の事前登録(α エラー膨張)

A/B テストで「良い結果が出たら早めに止める」は第1種過誤率を膨張させる。バノーニ補正やシーケンシャル検定(mSPRT)でない限り、事前登録サンプルサイズまで走り切ること。早期停止は「再現しない施策」の主因。

🌳

KPI ツリーの因果と相関の混同

開封率が上がっても CVR が下がれば GMV は改善しない。「どの段でロスが最大か」をボトルネック分析し、レバーを絞る。週次でツリー全段の前週比(WoW)を確認することで真の改善ポイントを特定できる。

🛡️

SAFE_DIVIDE の実務意義

送信数0のキャンペーンで ZeroDivision になるとダッシュボード全体が壊れる。SAFE_DIVIDE は NULL を返すため Looker Studio でグラフが崩れず、dbt テストで not_null チェックとも相性が良い。本番 SQL での必須イディオム。

実務への応用

MOps/販促チームでは毎週「どの施策を優先するか」の議論に多くの時間が費やされる。ICE スコアと事前登録 A/B テストを導入すると:

  • 意思決定会議の時間を 60分 → 15分に短縮(感情論ではなく ICE 数値で決まる)
  • 偽陽性の A/B テスト結果によるロールアウト失敗を防止(「効果あったはずなのに本番で再現しない」問題の根絶)
  • OKR と Looker Studio ダッシュボードの接続で、週次 KR 進捗確認が 2クリックで完了
  • PdM の工数配分を変える: データ整形 3時間 → 施策企画・仮説立案 3時間
実装順序: ① dbt mart + Looker Studio(データ基盤)→ ② ICE シート導入(即日適用可能)→ ③ OKR 見直し(四半期頭)→ ④ A/B テスト事前登録ルール化(次スプリントから)

今日のまとめ

「声の大きさ」による意思決定を排除するには OKR(目標の数値化)・ICE(施策の定量優先順位)・A/B テスト事前登録(因果推論の厳密化)の3フレームワークが相互補完的に機能する必要がある。KPI ツリーで中間指標を可視化し、ボトルネック段にレバーを絞る構造が MOps の意思決定品質を根本から変える。

自己評価

理解度
自分の回答
気づき・メモ