品質管理 mart:seed を分母にレビュー対象を見つける
Stage 4 — 第4章 | dbt入門カリキュラム 推定学習時間:40〜50分 | 難易度:★★★★☆
この章で学ぶこと
前章 では Demand 分析(goal / survey share)を学びました。 「どの演習問題が難しすぎるか」を議論するとき、attempts だけを見ると 母数(全問題数) が見えません。
コンテンツ品質 mart の設計では、行動データ(分子) と カタログ(分母) を分離します。 行動表だけを GROUP BY すると、触られた問題だけが見え、未出題・未回答の問題は分母から漏れます。
dbt では seed で 静的カタログ を warehouse に載せ、LEFT JOIN で全 ID を分母に含めるパターンが一般的です。 Seeds 章 で学んだ「参照マスタ」の実践が、ここで marts に接続します。
まず dbt の作法を整理し、続けて DS Playground の fct_problem_quality を読み解きます。
この章を終えると、こんなことができるようになります:
- seed を analytics 分母として使う理由を説明できる
- latest-state accuracy と first-try accuracy の違いを説明できる
is_low_accuracy_outlierフラグのビジネスルールを読める- singular test による catalog カバレッジを理解できる
コンテンツ品質 mart
品質指標を語るとき、分母の定義が指標の意味を決めます。
| 方式 | 問題 |
|---|---|
| attempts に存在する ID だけ | 未挑戦・未出題が 見えない |
| アプリ API を毎回叩く | analytics 境界・再現性が弱い |
| seed / カタログを dbt で固定 | リポジトリ内 SSOT。CI でも同じ分母 |
(全 ID = 分母)"] ACT["行動 fact
(触られた ID = 分子)"] FCT["品質 mart"] REV["レビューキュー"] CAT --> FCT ACT --> FCT FCT --> REV
mart の grain は 1 行 = 1 コンテンツ ID(問題、記事、レッスンなど)です。
LEFT JOIN により、行動のない ID も attempted_users = 0 として残ります。
外れ値フラグ(例: is_low_outlier)は 自動下架 ではなく、人間レビューのキュー です。
ダッシュボード上でフィルタ・説明できるように mart に持たせます。
latest-state と first-try の区別
同じ「正答率」という列名でも、ソースの性質で意味が変わります。
| 指標 | latest-state fact が測るもの | 測らないもの |
|---|---|---|
current_accuracy_rate |
最新状態が correct なユーザー比率 | 初回正答率 |
attempted_users |
一度でも保存したユーザー | セッション数 |
latest-state 表は再回答・更新で行が上書きされます。 イベント履歴表(append-only)とは別物です。 データ品質 6 軸 の「同じ列名でも意味が違う」典型例です。
staging / intermediate ではソースの性質を変えず、mart の YAML caveats で 何を測っているか を明示します。
テストによる分母保護
seed を分母に使うとき、singular test が横断断言として機能します。
| テスト | 目的 |
|---|---|
| catalog grain の一意性 test | seed 側重複 → 分母膨張防止 |
| attempts が catalog を被覆 test | 未知 ID 参照の検知 |
staging に新 problem が出たら seed 更新 + test 通過 がデプロイ条件になります。 品質インシデント の予防線です。
fct_problem_quality
DS Playground では seed practice_problem_catalog を正本とし、fct_problem_quality で問題単位の品質指標を出します。
seed ファイル: seeds/practice_problem_catalog.csv
テスト: assert_practice_problem_catalog_unique, assert_problem_attempts_catalog_covered
モデル構造
business question: 「どの演習問題が品質レビュー対象か」
grain: 1 行 = 1 問題(category × section × problem_id)
with attempts as (
select
category_slug,
section_slug,
problem_id,
count(distinct user_id) as attempted_users,
count(distinct case when attempt_state = 'correct' then user_id end) as correct_users
from stg_supabase__problem_attempts
group by 1, 2, 3
),
catalog as (
select * from {{ ref('practice_problem_catalog') }}
)
select
catalog.problem_title,
catalog.problem_level,
coalesce(attempts.attempted_users, 0) as attempted_users,
case
when attempted_users > 0
then correct_users::numeric / attempted_users
end as current_accuracy_rate,
case
when attempted_users >= 3
and correct_users::numeric / nullif(attempted_users, 0) < 0.10
then true
else false
end as is_low_accuracy_outlier
from catalog
left join attempts using (category_slug, section_slug, problem_id);
(seed)"] --> FCT["fct_problem_quality"] ATT["stg_supabase__problem_attempts
(latest state)"] --> FCT FCT --> REV["教材レビュー優先度"]
problem_attempts は latest-state table であり、answer event history ではありません。
模擬試験 exam_attempt_events はイベント履歴ですが、演習は 状態スナップショット です。
is_low_accuracy_outlier ルール
同時条件:
attempted_users >= 3— 極端に少ない母数を除外- accuracy
< 0.10— 10% 未満
コンテンツチームが問題文・解説・難度ラベルを確認する レビューキュー です。
関連 mart fct_problem_category_quality はカテゴリ粒度の集約版(同ファミリー)。
research exposure との接続
metabase_pre_monetization_research_dashboard は survey mart と 同じ exposure に content quality を並べます。
| レイヤー | 見ること |
|---|---|
| Demand | 何を学びたいか(goal / survey) |
| Supply quality | どの問題が壊れているか(quality mart) |
有料化前の product-market + content fit を 1 ダッシュボード lineage で追えます。
体系コラム:カリキュラム上の位置づけ
| 項目 | 内容 |
|---|---|
| Stage / 章 | Stage 4 — 第4章(Stage 4 完結章) |
| 今回の論点 | seed 分母、latest-state、outlier フラグ、カバレッジ test |
| 前章との接続 | Survey mart |
| 次章への伏線 | safe_ratio マクロ |
まとめ
教材品質は「attempts だけ見ればいい」ではなく、全カタログを分母にしたレビュー表 として設計します。 DS Playground では seed を LEFT JOIN し、latest-state 正答率と outlier フラグを mart に持たせ、singular test で catalog カバレッジを守っています。
Stage 4 では Monetization status → Engagement → Survey → Content quality と、ビジネス次元ごとの mart ファミリー を通しました。 Stage 5 ではマクロ・snapshot・CI/docs へ進みます。
関連教材
- 前章: Survey mart
- 次章(Stage 5): safe_ratio マクロ
- 関連(Analytics): データ品質チェック SQL
確認問題
問題 1
コンテンツ品質 mart が seed カタログを LEFT JOIN する 主な理由 はどれですか。
A. 行動 fact を隠すため
B. 未発生の ID も分母に含め、母集団全体に対する率を計算するため
C. incremental だから
D. PII 削除のため
正解: B
問題 2
latest-state fact から作る正答率が表すものとして 最も近い のはどれですか。
A. 初回挑戦の正答率
B. 最新保存状態が correct なユーザー比率
C. 試験の得点率
D. ページ閲覧率
正解: B
問題 3
外れ値フラグ(例: is_low_outlier)を mart に持たせる 主な理由 はどれですか。
A. すべての未発生行を除外するため
B. 利用者がダッシュボード上で異常値をフィルタ・説明できるようにするため
C. seed を不要にするため
D. incremental を無効にするため
正解: B
用語メモ(この章)
| 用語 | 意味(この章での使い方) |
|---|---|
| 分母 | 割合計算の全体集合(全公開問題) |
| latest-state | 再回答で上書きされる行動表 |
current_accuracy_rate |
最新状態が correct なユーザー比率 |
| outlier フラグ | 人間レビューキュー用の boolean |
| 被覆 | attempts が catalog を参照できているか |