青の統計学-DS Playground-

品質管理 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 でも同じ分母
flowchart LR CAT["seed カタログ
(全 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);
          
flowchart LR SEED["practice_problem_catalog
(seed)"] --> FCT["fct_problem_quality"] ATT["stg_supabase__problem_attempts
(latest state)"] --> FCT FCT --> REV["教材レビュー優先度"]

problem_attemptslatest-state table であり、answer event history ではありません。 模擬試験 exam_attempt_events はイベント履歴ですが、演習は 状態スナップショット です。

is_low_accuracy_outlier ルール

同時条件:

  1. attempted_users >= 3 — 極端に少ない母数を除外
  2. 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 へ進みます。


関連教材


確認問題

問題 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 を参照できているか