【AWS Glue】Data Qualityでカラム単位の品質スコアを算出したい
はじめに
データ事業本部の川中子(かわなご)です。
最近はデータマネジメント関連の記事を書くことが増えてきましたが、
今回はデータ品質としてGlue Data Quality
について書いていきます。
データ品質の活動では、ビジネスにおいて重要度の高いデータ を定義して、
それらを優先的に品質管理を進めていくことが推奨されています。
これをCritical Data Element(CDE)
と呼びます。
具体的にはCDEとして定義した論理要素を、テーブル上の物理カラムと対応させ、
そのカラムに対して品質目標(例:有効値が全体の99%以上)を定義する形になります。
カラムの中身によっては、1つの値に対して複数のルールで評価する必要があるため、
Glue Data Quality
のようなツールは非常に強い味方になります。
今回はGlue Data Quality
を使ってカラムごとにルールを設定して、
そのカラムごとのルール準拠スコアを評価することができるのか検証してみました。
Glue Data Qualityの使い方
Data Quality
の使い方としては大きく分けて2つあります。
Glue Data Catalog上で実行するパターン
GlueカタログのUI上からルールセットを作成して実行する方法です。
特徴としては以下が挙げられます。
- 推奨ルールの使用により簡単にルールが作成できる
- 動的ルールやアナライザーは利用できない
- ルールを満たさないレコードの特定などはできない
アナライザーは異常検知の仕組みで、以下の記事で紹介されています。
今回注目のポイントとしては、結果の出力方式についてです。
品質評価の結果として、各ルールセットの直近数回のスコア推移などが確認できます。
これはあくまで 「設定したルールのうちいくつが問題なく検証をパスしたか」 の数を表します。
各実行の詳細結果は以下の形式で確認することが可能なのですが、
複数条件を含むルールではそれぞれのメッセージが表示されているため、
結果このRule_1
は何%のレコードが品質を満たしているのか分かりません。
このように複数のルールを1つのカラムに適用して、
その詳細スコアを確認したい場合には、この方法はあまり適していません。
Glue ETLジョブ上で実行するパターン
こちらはGlue ETLジョブの中にData Quality
の実行を組み込む方法です。
特徴としては以下が挙げられます。
- VisualタイプならGUI上で簡単に
Data Quality
を組み込んで実行できる - 動的ルールやアナライザーが利用できる
- 全体スコアに加えて、ルールを満たさないレコードの特定や分類も可能
上記のテーブルからDataQualityRulesPass
ごとに集計をかければ、
ルールごとに詳細なルール適合率を算出することはできそうです。
しかしScriptやNotebookタイプならもっと簡単に集計が可能です。
Aggregated Metrics
ルールレベルの合格・失敗のレコード数を取得するオプションです。
この機能を有効化することで、各ルールの適合率を簡単に算出可能です。
実行時は以下のようにadditional_options
を設定する必要があります。
EvaluateDataQualityMultiframe = EvaluateDataQuality().process_rows(
frame=medicare_dyf,
ruleset=EvaluateDataQuality_ruleset,
publishing_options={
"dataQualityEvaluationContext": "EvaluateDataQualityMultiframe",
"enableDataQualityCloudWatchMetrics": False,
"enableDataQualityResultsPublishing": False,
},
additional_options={"publishAggregatedMetrics.status": "ENABLED"},
)
ドキュメントでは結果の取得方法として以下の2つが説明されています。
GetDataQualityResult
のAPIで取得ruleOutcomes
のデータフレームとして取得
APIでは以下のように結果IDを指定して取得することができます。
aws glue get-data-quality-result --result-id "{dqresult-result-id}"
レスポンスは以下のように、各ルールごとに合格や不合格のレコード数が返されます。
{
"Rule": "IsUnique \"customer_identifier\"",
"Outcome": "Passed",
"FailureReason": null,
"EvaluatedMetrics": {
"Column.customer_identifier.Uniqueness": 1
},
"EvaluatedRule": "IsUnique \"customer_identifier\"",
"PassedCount": 10,
"FailedCount": 0,
"SkippedCount": 0,
"TotalCount": 10
}
今回はもう一つの方法として、Notebook上でデータフレームを取得して、
Aggregated Metrics
を確認するところまでやってみました。
検証
データ準備
今回はテスト用に30行分のデータを準備しました。
customer_id
以外の各列で数行分ずつ、エラーケースのデータを入れています。
spark.sql(f"SELECT * FROM {DB_TBL} order by customer_id;").show(30)
# 出力
+-----------+-----------+------+----------+-------------+
|customer_id| name|gender|birth_date| phone_number|
+-----------+-----------+------+----------+-------------+
| CUST0001| 田中太郎| 男性|1965-07-30|090-1234-5678|
| CUST0002| 山田花子| 女性|2004-04-28|080-2345-6789|
| CUST0003| 佐藤次郎| 男性|1990-05-28|070-3456-7890|
| CUST0004| 鈴木美咲| 女性|1997-07-27|090-4567-8901|
| CUST0005| 高橋健一| 男性|1971-08-11|080-5678-9012|
| CUST0006| 伊藤 由美| NULL|1968-02-21|070-6789-0123|
| CUST0007| 渡辺 直樹| NULL|2003-09-01|090-7890-1234|
| CUST0008| 小林 愛| NULL|2000-05-28|080-8901-2345|
| CUST0009| 加藤 隆| NULL|1991-01-04|070-9012-3456|
| CUST0010| 吉田 恵子| NULL|1967-09-12|090-0123-4567|
| CUST0011| 中村 修| 男性|2026-02-03|080-1234-5678|
| CUST0012| 山口 理恵| 女性|2026-03-07|070-2345-6789|
| CUST0013| 松本 大輔| 男性|2025-11-19|090-3456-7890|
| CUST0014| 井上 美紀| 女性|2026-02-06|080-4567-8901|
| CUST0015| 木村 拓哉| 男性|2025-11-30|070-5678-9012|
| CUST0016| 斎藤 真一| 男性|1978-04-01| 09012345678|
| CUST0017| 清水 優子| 女性|1988-07-02| 0801234|
| CUST0018| 森 博之| 男性|1992-03-30|070-12-345678|
| CUST0019| 橋本 香織| 女性|1999-08-01| 9012345678|
| CUST0020| 山崎 正人| 男性|1981-08-03| 080-1234-567|
| CUST0021| 池田 綾子| 女性|1983-03-29|070-1122-3344|
| CUST0022| 岡田 浩二| 男性|1967-05-13|090-5566-7788|
| CUST0023| 長谷川 美希| 女性|2003-01-24|080-9900-1122|
| CUST0024| 藤田 勇気| 男性|1971-07-23|070-3344-5566|
| CUST0025| 村上 千尋| 女性|1981-08-12|090-7788-9900|
| CUST0026| 小川 達也| 男性|1970-04-27|080-2233-4455|
| CUST0027| 柴田 裕美| 女性|1964-11-13|070-6677-8899|
| CUST0028| 原田 慎太郎| 男性|1981-11-30|090-1010-2020|
| CUST0029| 前田 さくら| 女性|1992-09-23|080-3030-4040|
| CUST0030| 福田 康平| 男性|2001-08-24|070-5050-6060|
+-----------+-----------+------+----------+-------------+
エラーケースは以下のような想定になっています。
行番号 | エラーケース |
---|---|
0001 - 0005 | name 列の性名にスペースがない |
0006 - 0010 | gender 列がNULL |
0011 - 0015 | birth_date 列が未来の日付 |
0016 - 0020 | phone_number 列の形式が不正 |
0023, 0028, 0029 | name 列の文字列が6文字以上 |
検証
ルールセットとしては以下の内容で設定しました。
name
:文字列と文字列の間に半角スペースが1つ入る & スペース含めて6文字未満gender
:値が男性か女性のどちらかであるbirth_date
:値が実行時点よりも前の日付であるphone_number
:070,080,090のどれかから始まり、4桁-4桁が続く
# ルールセットを定義
DQ_RULESET = """Rules = [
(ColumnValues "name" matches "^[^ ]+ [^ ]+$") AND (ColumnLength "name" < 6),
ColumnValues "gender" in ["男性", "女性"],
ColumnValues "birth_date" <= now(),
ColumnValues "phone_number" matches "^0[789]0-[0-9]{4}-[0-9]{4}$"
]"""
上記のルールを用いてデータフレームの評価を行う際に、
"publishAggregatedMetrics.status": "ENABLED"
を有効化することで、
今回取得したい、ルールごとの合格レコード数などが出力されるようになります。
また今回はカラムごとではなく、レコード単位で各ルールを評価する必要があるため、
"compositeRuleEvaluation.method":"ROW"
の設定も必要です。
# 検証を実行
dyfc_eval_dq = EvaluateDataQuality().process_rows(
frame=dyf,
ruleset=DQ_RULESET,
publishing_options={
"dataQualityEvaluationContext": "dyfc_eval_dq",
"enableDataQualityCloudWatchMetrics": False,
"enableDataQualityResultsPublishing": False,
},
additional_options={
"performanceTuning.caching": "CACHE_NOTHING",
"compositeRuleEvaluation.method":"ROW",
"publishAggregatedMetrics.status": "ENABLED"
},
)
結果は想定通りFailedCount
がname
で8行、それ以外が5行になりました。
ちゃんとANDの評価もされたので、カラムに複数ルールがあっても対応可能です。
# 結果を取得して出力
dyfc_rule_outcomes = SelectFromCollection.apply(
dfc=dyfc_eval_dq,
key="ruleOutcomes"
)
dyfc_rule_outcomes.toDF().select('Rule', 'PassedCount', 'FailedCount', 'SkippedCount').show(truncate=False)
# 出力
+---------------------------------------------------------------------------+-----------+-----------+------------+
|Rule |PassedCount|FailedCount|SkippedCount|
+---------------------------------------------------------------------------+-----------+-----------+------------+
|(ColumnValues "name" matches "^[^ ]+ [^ ]+$") AND (ColumnLength "name" < 6)|22 |8 |0 |
|ColumnValues "gender" in ["男性","女性"] |25 |5 |0 |
|ColumnValues "birth_date" <= now() |25 |5 |0 |
|ColumnValues "phone_number" matches "^0[789]0-[0-9]{4}-[0-9]{4}$" |25 |5 |0 |
+---------------------------------------------------------------------------+-----------+-----------+------------+
このデータをベースにダッシュボードなどを作成すれば、
各カラム単位で品質基準を満たすレコードの割合が算出可能 になりますね。
また 各カラムの目標値を下回ったらエラー通知をする運用もできそうです。
さいごに
今回はGlue Data Quality
を使用して、
カラムごとに品質スコアを算出することが可能か、調べてみました。
まとめとしては以下になります。
- 単一ルールであれば
Glue Data Catalog
上で算出は可能 - ただしメトリクスというよりは、メッセージとして表示されるのみ
- ETLに組み込むことで、詳細な品質の状況を把握できる
Aggregated Metrics
が利用できれば、簡単に割合を算出可能- カラムごとの品質スコアを可視化するなら別でダッシュボードが必要
また今回紹介した方法以外にも、ルールセットを複数作成して、
それぞれのルールセットスコアのグラフを利用する方法などもあります。
このあたりはData Quality
をどんな場面で使うかによって、
最適な算出、可視化方法は変わってくるのかなぁと思います。
本記事が少しでも参考になれば幸いです。
最後まで記事を閲覧頂きありがとうございました。