ストーリー
データ品質の6次元
品質の測定軸
| 次元 | 定義 | チェック方法 | 例 |
|---|---|---|---|
| 正確性(Accuracy) | データが現実を正しく反映しているか | 外部データとのクロスチェック | 売上金額がStripeの明細と一致 |
| 完全性(Completeness) | 必要なデータが欠損していないか | NULL率、レコード数チェック | メールアドレスのNULL率 < 1% |
| 一貫性(Consistency) | 複数のデータソース間で整合しているか | クロスデータベースの突合 | DWHの売上 = Stripeの売上 |
| 適時性(Timeliness) | データが期待されるタイミングで利用可能か | 鮮度モニタリング | 日次バッチが朝8時までに完了 |
| 一意性(Uniqueness) | 重複データがないか | 重複チェック | order_idの重複がゼロ |
| 妥当性(Validity) | データが定義されたルールに従っているか | ドメインルールチェック | statusが定義済みの値のみ |
データ品質テストの設計
テストピラミッド
データ品質テストピラミッド:
┌──────────┐
│ ビジネス │ ← 少数だが重要
│ ルール検証 │ KPI整合性、クロスチェック
├──────────┤
│ 統計的 │ ← 異常検知
│ テスト │ 分布の変化、外れ値
├──────────┤
│ スキーマ │ ← 中程度
│ テスト │ 型、NULL、値域
├──────────┤
│ 基本テスト │ ← 多数、自動化
│ │ not_null, unique, freshness
└──────────┘
dbt testsによる品質チェック
# models/silver/schema.yml
models:
- name: slv_orders
description: "クレンジング済み注文データ"
config:
tags: ['quality-critical']
columns:
- name: order_id
description: "注文の一意識別子"
tests:
- not_null
- unique
- name: total_amount
tests:
- not_null
- dbt_utils.expression_is_true:
expression: ">= 0"
- dbt_utils.expression_is_true:
expression: "< 10000000" # 1000万円以上は異常値
- name: status
tests:
- not_null
- accepted_values:
values: ['PENDING', 'COMPLETED', 'CANCELLED', 'REFUNDED']
- name: order_date
tests:
- not_null
- dbt_utils.expression_is_true:
expression: "> '2020-01-01'"
- dbt_utils.expression_is_true:
expression: "<= CURRENT_DATE()"
tests:
# テーブルレベルのテスト
- dbt_utils.equal_rowcount:
compare_model: ref('brz_orders') # Bronze と Silver のレコード数が一致
Great Expectationsによる品質チェック
Expectation Suite
# Great Expectations: 注文データの品質チェック
import great_expectations as gx
context = gx.get_context()
# Expectation Suite の定義
suite = context.add_expectation_suite("orders_quality")
# 基本チェック
suite.add_expectation(
gx.expectations.ExpectColumnValuesToNotBeNull(column="order_id")
)
suite.add_expectation(
gx.expectations.ExpectColumnValuesToBeUnique(column="order_id")
)
# 値域チェック
suite.add_expectation(
gx.expectations.ExpectColumnValuesToBeBetween(
column="total_amount",
min_value=0,
max_value=10000000
)
)
# 統計チェック(異常検知)
suite.add_expectation(
gx.expectations.ExpectTableRowCountToBeBetween(
min_value=1000, # 日次で最低1000件
max_value=100000 # 日次で最大10万件
)
)
# 鮮度チェック
suite.add_expectation(
gx.expectations.ExpectColumnMaxToBeBetween(
column="order_date",
min_value={"$PARAMETER": "yesterday"},
max_value={"$PARAMETER": "today"}
)
)
データ品質スコアの算出
スコアリングモデル
| カテゴリ | 重み | 計算方法 |
|---|---|---|
| 完全性 | 30% | (1 - NULL率) × 100 |
| 正確性 | 25% | クロスチェック一致率 × 100 |
| 一貫性 | 20% | ソース間整合率 × 100 |
| 適時性 | 15% | SLA遵守率 × 100 |
| 一意性 | 10% | (1 - 重複率) × 100 |
品質スコアの例:
テーブル: slv_orders
完全性: 98.5% × 0.30 = 29.55
正確性: 99.2% × 0.25 = 24.80
一貫性: 97.0% × 0.20 = 19.40
適時性: 100.0% × 0.15 = 15.00
一意性: 99.9% × 0.10 = 9.99
────────────────────────
総合スコア: 98.74 / 100
判定基準:
95-100: 優良(Green)
85-94: 注意(Yellow)
0-84: 問題あり(Red)
「データ品質スコアをダッシュボードに表示し、全社に公開する。『このテーブルのスコアは98点』とわかれば、そのデータを信頼して意思決定できる。スコアが下がったら即座にアラートを発報する」 — 田中VPoE
まとめ
| ポイント | 内容 |
|---|---|
| 6次元 | 正確性、完全性、一貫性、適時性、一意性、妥当性 |
| テストピラミッド | 基本テスト → スキーマ → 統計 → ビジネスルールの4層 |
| ツール | dbt tests(SQL)、Great Expectations(Python) |
| 品質スコア | 重み付きスコアで品質を定量化し、ダッシュボードで可視化 |
チェックリスト
- データ品質の6次元を説明できる
- dbt testsで基本的な品質チェックを実装できる
- Great Expectationsの基本的な使い方を理解した
- データ品質スコアの算出方法を理解した
次のステップへ
次は「データリネージ」を学びます。データがどこから来て、どう変換され、どこに行くのかを追跡する仕組みを身につけましょう。
推定読了時間: 30分