簡単な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は値の修復まで含み、関数の使い方がやや難しいことと、分析の中でSQLやpythonを行き来するのが大変なため、簡単なFDsの検知スクリプトを作成しました。
簡単なデータ例
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
-------------|---------------
さまざまなデータ品質の逸脱を検知するツールやアルゴリズムがありますが、現実的には一番よく使う手法かと思います。