利用深度 mart:スコア・tier・分布の設計
Stage 4 — 第2章 | dbt入門カリキュラム 推定学習時間:45〜55分 | 難易度:★★★★☆
この章で学ぶこと
前章 では、課金状態を intermediate に固定しました。 Activity mart が DAU など 「来たかどうか」 を数えるのに対し、Engagement mart は 「どれだけ・どれだけ広く・どれだけ深く使っているか」 を会員単位で表します。
エンゲージメント分析は、Recency(最終利用)、Consistency(継続頻度)、Breadth(機能の広さ)、Depth(完了量)など複数の概念を組み合わせます。 これらを mart ごとに別定義すると、power user の閾値や dormant の日数が表ごとにずれます。
dbt では 行レベル mart(1 会員 1 行)と 分布 mart(セグメント別の構成比)を分け、後者をダッシュボードの SSOT にするパターンが一般的です。 行レベルには疑似匿名キーを使い、公開用途には集計済み分布を優先します。
まず dbt の作法を整理し、続けて DS Playground の fct_user_engagement_current と fct_user_engagement_distribution_current を読み解きます。
この章を終えると、こんなことができるようになります:
- Recency / Consistency / Breadth / Depth / Intensity の 5 概念を列名と対応づけられる
engagement_tierの 5 段階定義を説明できるanon_user_keyが 疑似匿名 であり公開安全ではない理由を説明できる- 行レベル mart と分布 mart の使い分けを説明できる
Engagement 分析
DAU / WAU / MAU は アクティブの有無 を期間単位で数えます。 Engagement はその延長線上にあり、残っているか・深いか・広いか を会員単位で測ります。
| 概念 | 典型列 | 意味 |
|---|---|---|
| Recency | days_since_last_activity |
最後に利用したのはいつか |
| Consistency | active_days_30d, active_weeks_12w |
戻ってくる頻度 |
| Breadth | activity_types_used, categories_touched |
触れた機能・カテゴリの広さ |
| Depth | items_completed, problems_attempted |
完了・保存の量 |
| Intensity | usage_intensity_score |
上記を組み合わせた ヒューリスティック |
| Tier | engagement_tier |
人が読めるラベル |
Intensity スコアや tier は プロダクト利用強度 の内部モニタリング指標です。 学力・合格力・購買意欲そのものを表すスコアではありません。YAML の caveats にもその旨を書きます。
1 会員 1 行"] DIST["分布 mart
status × goal × tier"] ACT --> ROW MEM --> ROW ROW --> DIST
行レベル mart の grain は 1 行 = 1 会員 です。 分布 mart は行レベルを GROUP BY し、構成比(share) を出します。 grain と business question が異なるため、1 表に混ぜません(Mart 設計)。
tier と intensity の設計
engagement_tier は、閾値ベースの 5 段階ラベル です。 registered_only(行動ゼロ)、activated(1 回以上)、engaged(一定頻度)、power_user(高頻度 + 深度)、dormant(長期非活性)——このような段階分けは SaaS でよく見られます。
-- tier 判定(概念)
case
when active_days_lifetime = 0 then 'registered_only'
when days_since_last_activity > 90 then 'dormant'
when active_days_30d >= 8
and (problems_attempted >= 30
or curriculum_pages_completed >= 5
or mock_exams_saved >= 2)
then 'power_user'
when active_days_30d >= 3 or active_weeks_12w >= 3 then 'engaged'
else 'activated'
end as engagement_tier
閾値は 設定可能なヒューリスティック です。変更時は YAML・singular test・ダッシュボードを同時更新します。
usage_intensity_score は 0〜100 に clamp した加重式(例: active_days_30d * 4 + mock_exams_saved * 5 + ...)です。
singular test で範囲(0〜100)を守り、スコア列の契約を CI で固定します。
疑似匿名キーとガバナンス
行レベル mart では、raw user_id の代わりに ハッシュ化キー(例: md5(user_id::text))を露出することがあります。
これは 疑似匿名(pseudonymous) であり、完全匿名化ではありません。
内部キーとの対応表があれば再識別可能です。 Engagement mart の行レベル出力を外部公開せず、集計分布 mart をダッシュボード SSOT にする——この使い分けがガバナンスの要です。
ガバナンス実践 の「利用目的に応じた最小露出」と一致します。
| 誤解 | 事実 |
|---|---|
| md5 だから公開 OK | 内部キーとの対応表があれば再識別可能 |
| engagement mart は外部共有可能 | 集計分布 mart を優先 |
| カリキュラムに実キーを載せてよい | 載せない |
Engagement mart ファミリー
DS Playground では Engagement ファミリーに 2 モデルがあります。
fct_user_engagement_current— 1 会員 1 行(anon_user_key)fct_user_engagement_distribution_current— status × goal × tier の分布
入力の組み立て
business question: 「各会員は今どの程度プロダクトを使っているか」
user_id は内部 JOIN に使い、最終 SELECT では anon_user_key = md5(user_id::text) を主キー相当として露出します。
engagement_tier 語彙
| Tier | 定義 | プロダクト上の読み |
|---|---|---|
registered_only |
Learning Action ゼロ | 登録したが未体験 |
activated |
1 回以上は使ったが engaged 閾値未満 | 初期活性 |
engaged |
30 日で 3 日以上 or 12 週で 3 週以上 | 習慣化途中 |
power_user |
高頻度 + 深度(演習/カリキュラム/模試) | コアユーザー |
dormant |
90 日超非活性 | 復帰候補 |
fct_user_engagement_distribution_current
business question: 「会員全体の engagement 構成はどうなっているか」
grain: 1 行 = member_status × primary_goal × engagement_tier
select
member_status,
coalesce(primary_goal, 'unset') as primary_goal,
engagement_tier,
count(*) as members,
safe_ratio(members, total_members) as member_share,
avg(usage_intensity_score) as avg_usage_intensity_score
from fct_user_engagement_current
group by 1, 2, 3;
| mart | 行レベル | ダッシュボード向き |
|---|---|---|
fct_user_engagement_current |
あり(anon) | 内部調査・サンプル確認 |
fct_user_engagement_distribution_current |
なし | Metabase 主役(PII リスク低) |
exposure metabase_product_health_dashboard は 分布 mart を depends_on に含みます。
free / premium 比較の読み方
分布 mart で member_status を軸に power_user share を比較する例:
select
member_status,
engagement_tier,
member_share
from fct_user_engagement_distribution_current
where primary_goal = 'unset' -- 例: 全体
order by 1, 2;
前章 で学んだ current-state の member_status であること(過去 as-of 不可)を必ず併記してください。
体系コラム:カリキュラム上の位置づけ
| 項目 | 内容 |
|---|---|
| Stage / 章 | Stage 4 — 第2章 |
| 今回の論点 | 5 概念、tier、intensity、anon キー、分布 mart |
| 前章との接続 | Monetization status |
| 次章への伏線 | Survey mart |
まとめ
Engagement は DAU の延長線上にあり、「残っているか・深いか」 を測ります。 DS Playground では activity・practice・curriculum・exam・survey・skill check を組み合わせた行レベル mart と、その分布 mart を分け、会議では後者を SSOT にしています。
行レベルは内部、分布はダッシュボード——この使い分けがガバナンスの要です。
関連教材
- 前章: Monetization status
- 次章: Survey mart
- 関連(Analytics): コホート・継続
確認問題
問題 1
エンゲージメント tier で「行動 1 件もない登録ユーザー」を分ける 主な理由 はどれですか。
A. SQL が短いから
B. 登録のみと、実際に行動したユーザーを区別するため
C. incremental だから
D. seed が必須だから
正解: B
問題 2
分布(distribution)mart を raw 行 mart とは 別モデル にする主な理由はどれですか。
A. PII を削除するため
B. grain と business question が異なるため(集計済み vs 1 行 1 ユーザー)
C. source() が使えないため
D. YAML が書けないため
正解: B
問題 3
疑似匿名キー(hashed user key)について 正しい 説明はどれですか。
A. 公開 Web にそのまま載せてよい完全匿名 ID
B. 内部向けの識別子であり、行レベル出力の公開には別途ガバナンスが必要
C. OLTP の主キーそのもの
D. BI ツールのユーザー ID
正解: B
用語メモ(この章)
| 用語 | 意味(この章での使い方) |
|---|---|
| Engagement | 利用の深さ・広さ・継続性 |
engagement_tier |
閾値ベースの 5 段階ラベル |
usage_intensity_score |
0〜100 の内部ヒューリスティック |
| 分布 mart | セグメント別構成比の集計表 |
| 疑似匿名 | ハッシュ化キー。完全匿名ではない |