Measuring data quality
Completeness, consistency, currency and label quality: the figures to collect before any model, and the checks that produce them.
The six dimensions
| Dimension | Question | Measure |
|---|---|---|
| Completeness | Are values missing? | Share of missing values per column |
| Uniqueness | Are there duplicates? | Share of duplicate rows |
| Validity | Do values fit the format? | Share of rule violations |
| Consistency | Do fields contradict? | Share of violated rules |
| Currency | How old is the data? | Distribution of age |
| Correctness | Are the labels right? | Agreement of two annotators |
The last row is the most expensive and the most important.
A check run
import pandas as pd, numpy as np
def data_report(df, key=None):
n = len(df)
print(f"rows: {n}")
missing = df.isna().mean().sort_values(ascending=False)
print("\nmissing values, top 5:")
print((missing[missing > 0].head() * 100).round(1))
if key:
dup = df.duplicated(subset=key).sum()
print(f"\nduplicates by key: {dup} ({dup/n:.2%})")
full_dup = df.duplicated().sum()
print(f"fully duplicated rows: {full_dup} ({full_dup/n:.2%})")
for col in df.select_dtypes("object"):
# Constant columns contribute nothing and only cost compute.
if df[col].nunique() <= 1:
print(f"WARNING constant column: {col}")
# Very many distinct values suggest an identifier, which as a
# feature would be leakage.
if df[col].nunique() > 0.9 * n:
print(f"WARNING near-unique column: {col}")- Run before every training, not only once at the start.
- Version the results so degradation is noticed.
- Add business rules: end date after start date, line items sum to subtotal, amount not negative.
Agreement between annotators
| κ | Reading | Consequence |
|---|---|---|
| below 0.40 | weak | The guideline is unusable, rewrite it |
| 0.40 to 0.60 | moderate | Clarify borderline cases, add examples |
| 0.60 to 0.80 | good | Usable |
| above 0.80 | very good | The task is well defined |
A κ of 0.55 with three classes means in practice: two experts disagree on about
one case in four. A model cannot reach 90 percent on such a task, because there is
no 90 percent truth.
Computing the ceiling
Practical consequence: before investing time in a better model, estimate ε.
Re-annotating 300 cases costs a day and answers whether the target 95 percent is
reachable at all.
Finding duplicates properly
Exact duplicates are the easy case. The problematic ones are near duplicates: the same document with a different header, the same transaction with a different id.
- For text: MinHash over word shingles, threshold at a Jaccard similarity around 0.8.
- For images: perceptual hashes, Hamming distance below 6 counts as a duplicate.
- For tables: check equal combinations of the business key fields, not the technical id.
- Count and report duplicates rather than silently removing them. Their frequency is itself a finding about the process.
Related courses and sources
Jupyter
Notebooks where text, code and result sit side by side. The usual tool for recording a calculation so that others can follow it.
For your first calculations; keeps text, code and result traceable in one place.
Kaggle datasets
Real, untidy data to practise on. That is exactly what makes them valuable, because tidied examples hide the actual work.
For practising on untidy data, because tidied examples hide the actual work.
Kaggle Learn
Short units with runnable notebooks, from Python through pandas to a first model. No installation, straight in the browser.
For the very first steps with no installation, straight in the browser.