ecetio's blog

データ品質と異常検知について。すべては個人的見解です。

簡単なFunctional Dependencies Violationの検知

functional dependencies(FDs)とは、データの列同士の関係において、ある列の組み合わせXがあった場合、別の列Aの値を一意に決定できることを言います。(X -> A)

例えば、「郵便番号」列があった場合、「住所」列の値が一意に決定できる場合、FDsであると言います。

これは、データ品質のうち、データセット内の「一貫性」の指標として利用されます。

例えば、「郵便番号」列の値1つにつき、「住所」列の値が2つ以上あれば、FDsについて逸脱があり、データの一貫性がないと判断されます。

opencleanというライブラリでは「fd_violation」という関数があり、FDsの逸脱を検知することがあります。また、SQLでもgroup byを用いて検知することもできます。

GitHub - VIDA-NYU/openclean: openclean - Data Cleaning and data profiling library for Python

ただし、opencleanは値の修復まで含み、関数の使い方がやや難しいことと、分析の中でSQLpythonを行き来するのが大変なため、簡単なFDsの検知スクリプトを作成しました。

github.com

簡単なデータ例

df = pd.DataFrame({'a':['A','A','C','D'],
                    'b':['AA','BB','CC','DD']})
df = df.astype({'a': 'string', 'b': 'string'})
groups = fd_violations(df, lhs='a', rhs='b')
df
a b
0 A AA
1 A BB
2 C CC
3 D DD

この場合、「a」列の値「A」について、「b」列の値が「AA」「BB」の2つとなるので、FDsの逸脱となります。 結果はdictで出力されます。

groups
{'A': Counter({'AA': 1, 'BB': 1})}

想定のデータが検知できています。 次に、もう少し現実的な例で実験してみます。 データはopencleanのテストデータを利用します。

datafile = 'data/jt7v-77mi.tsv'
df = pd.read_table(datafile)
df.head(5)
Plate ID Registration State Plate Type Meter Number Street Vehicle Body Type Vehicle Make Vehicle Color
661 FXY1858 NY PAS 407-3018 QUEENS BLVD SDN NISSA GY
780 89988JX NY COM 3 - FRESH POND TRD VAN FORD WHITE
901 FGX2747 NY PAS 504-3043 <NA> SDN HONDA SILVE
2287 23161JR NY COM 144-3942 WEST 42 STREET P-U FORD WHITE
2346 47153MC NY COM 144-3987 W 40TH ST SDN TOYOT SILV

スクリプトを実行すると、次のようになります。

groups = fd_violations(df, lhs='Meter Number', rhs='Street')
# 検出結果明細の表示
print('Meter Number | Street (Count)')
print('=============|===============')
for key in groups:
    conflicts = groups.get(key).most_common()
    street, count = conflicts[0]
    print('{:<12s} | {} x {}'.format(key, count, street))
    for street, count in conflicts[1:]:
        print('             | {} x {}'.format(count, street))
    print('-------------|---------------')
Meter Number | Street (Count)
=============|===============
144-3937     | 1 x WEST 42 STREET
             | 1 x WEST 42 ST
-------------|---------------
143-3785     | 2 x WEST 43RD ST
             | 1 x WEST 43 ST
-------------|---------------
144-6376     | 1 x 8TH AVE
             | 1 x 8TH AVENUE
-------------|---------------

さまざまなデータ品質の逸脱を検知するツールやアルゴリズムがありますが、現実的には一番よく使う手法かと思います。

データ品質の定量的属性と定性的属性

前回は、データ品質の例として、「完全性」を取り上げました。

ecetio.hatenablog.com

「データ品質管理ガイドブック」[1]では、ISO25012を参考に、15の指標が記載されています。DMBOKやデータ品質管理ガイドブックでは、一応指標の定量的な計算について記載がありますが、形式的な計算が多く、データの実態を反映するのは容易ではありません。

このような中で、どのようにデータ品質を定量的に計算できるかを考えてみます。

多くの指標は定性的観点を反映していますが、定量的に把握できうる指標としては次のようなものがあります。

正確性(Accuracy)
データの基本は正確であることです。データの正しさを以下の点に着目して評価します。

完全性(Completeness)
データは目的に応じて抜け漏れなくあることで、詳細な分析をすることができるようになります。データが完全であることを以下の点に着目して評価します。

一貫性(Consistency)
データには整合性や一貫性が必要で、データ内の項目や値に矛盾があるとエラー処理をする必要があります。データに矛盾がないことを以下の点に着目して評価します。

データ品質管理ガイドブック[1]より

このような指標を具体的にどのように計測するかを考えていきたいと思います。

 

 

1.デジタル庁. 「データ品質管理ガイドブック」.2022年3月31日. 最終アクセス 2022年11月15日.

github.com

データ品質とデータ分析

論文に掲載されているようなベンチマークデータセットの場合、所与の属性(列)を利用すれば良いですが、実際のデータ分析においては、そもそも分析にたりうる属性を持っているのかということが問題になります。

例えば、次のようなデータを考えます。このデータから、D列の値を予測するようなデータ分析を想定します。

この場合、A列〜C列の値が同じであるにも関わらず、D列の値にばらつきがあります。この場合、分析を行ってもD列の値を特徴づけることは困難です。

 

このように、データ分析を行うにあたり、分析に値するデータであるか判断することは重要です。では、「データ分析に値するデータ」かどうかはどのように判断すれば良いのでしょうか。

 

考え方の一つとして、「データ品質」があります。

データ品質はDMBOKやISO25012などにより様々な尺度が考えられています。

また、「データ品質管理ガイドブック」[1]ではデータ品質について、「データ品質を考える時には、利用目的に応じた適切なデータ品質を考えていく必要があります。」

つまり、目的によって無数のデータ品質が考えられるということです。

 

データ分析の文脈で考慮した時、上述のような例は「完全性(Completeness)」が満たされていないと考えられます。

ISO25012に基づく「データ品質管理ガイドブック」では完全性について、「データは目的に応じて抜け漏れなくあることで、詳細な分析をすることができるようになります。」とあり、その評価項目として「用途に応じて必要な項目が網羅されているか。」と記載されています。

これは、なかなか難しい問題です。

通常は業務要件に基づきデータが定義されますが、「D列の予測」という用途について、どのような項目があれば「必要な項目が網羅されている」と言えるのでしょうか。

 

このような問題について、どのようにデータ品質を定量的に判断することができるのか考えてみたいと思います。

 

1.デジタル庁. 「データ品質管理ガイドブック」.2022年3月31日. 最終アクセス 2022年11月15日.

github.com