Pemeriksaan kualitas data bergerak dari kesan ke angka ketika setiap aspeknya didefinisikan secara kuantitatif, karena angka dapat dibandingkan dengan ambang batas dan dihitung ulang oleh mesin. Topik ini membahas empat dimensi kualitas data yang paling sering diukur pada pipeline, yaitu kelengkapan, validitas, kesegaran, dan konsistensi, beserta definisi kuantitatif sederhananya. Satu berkas CSV kecil dengan masalah yang ditanamkan secara sengaja diperiksa oleh skrip Python, dan skor setiap dimensi dicetak sebagai keluaran nyata yang dapat dihitung ulang.
Empat dimensi kualitas data#
Dimensi kualitas data (data quality dimension) adalah aspek yang diukur secara terpisah untuk menilai kesesuaian data dengan tujuan pemakaiannya. Empat dimensi berikut dipilih karena masing-masing dapat dinyatakan sebagai proporsi yang dihitung langsung dari data. Definisinya sengaja dibuat sederhana, sehingga skrip apa pun dapat menghitungnya tanpa alat khusus.
Kelengkapan (completeness) mengukur banyaknya nilai wajib yang kosong, dan ukurannya berupa proporsi sel terisi terhadap seluruh sel wajib pada tabel. Validitas (validity) mengukur kesesuaian nilai yang ada dengan format dan rentang yang ditetapkan, misalnya jumlah barang yang tidak boleh nol, dan ukurannya berupa proporsi baris yang lolos seluruh aturan nilai. Kesegaran (freshness) mengukur umur data, yaitu selisih antara tanggal data dan tanggal pemakaiannya, dan ukurannya berupa proporsi baris yang berumur di bawah batas. Konsistensi (consistency) mengukur kesesuaian nilai antartabel, misalnya id_pelanggan pada tabel pesanan yang harus ada di tabel pelanggan, dan ukurannya berupa proporsi rujukan yang ditemukan pada tabel acuannya.
Tabel berikut merangkum definisi kuantitatif keempatnya.
| Dimensi | Pertanyaan inti | Definisi kuantitatif |
|---|---|---|
| Kelengkapan | apakah nilai wajib ada | sel terisi dibagi seluruh sel wajib |
| Validitas | apakah nilai sesuai aturan | baris lolos dibagi baris bernilai |
| Kesegaran | apakah data cukup baru | baris segar dibagi baris bertanggal |
| Konsistensi | apakah antartabel cocok | rujukan ditemukan dibagi rujukan diperiksa |
Data contoh dengan masalah yang ditanamkan#
Contoh pemeriksaan menggunakan dua berkas CSV kecil, yaitu pesanan.csv sebagai tabel utama dan pelanggan.csv sebagai tabel acuan konsistensi. Lima masalah ditanamkan pada pesanan.csv. Kelimanya berupa satu baris yang seluruh selnya kosong, satu id_pelanggan yang kosong, satu jumlah_item bernilai 0 di luar rentang, satu tanggal yang terlalu tua, dan satu id_pelanggan yang tidak ada di tabel acuan. Isi kedua berkasnya sebagai berikut.
id_pesanan,tanggal_pesanan,id_pelanggan,jumlah_item
P101,2026-10-30,C01,2
P102,2026-10-31,C02,1
P103,2026-11-01,,3
,,,
P104,2026-09-10,C01,5
P105,2026-11-01,C99,0id_pelanggan,nama,kota
C01,Ali,Jakarta
C02,Budi,Bandung
C03,Citra,Surabayapelanggan.csv tidak membawa masalah, sehingga seluruh pelanggaran berada di sisi pesanan.csv. Pada pekerjaan sungguhan, tabel acuan biasanya berupa tabel dimensi yang sudah dibersihkan, dan pemeriksaan konsistensi menggantikan kunci asing yang tidak ditegakkan mesin basis data. Konsep yang sama berlaku untuk tabel apa pun yang saling merujuk.
Skor per dimensi dengan skrip Python#
Skrip berikut menghitung skor keempat dimensi sekaligus mencetak daftar pelanggaran per baris. Tanggal pembanding kesegaran berupa literal 2026-11-02 agar keluarannya deterministik, sedangkan pada pipeline sungguhan tanggal itu diambil dari waktu run. Skor dinyatakan sebagai proporsi, dan daftar pelanggaran menyebut barisnya, sehingga setiap angka dapat dilacak sumbernya.
"""Pemeriksaan empat dimensi kualitas data pada pesanan.csv.
Setiap dimensi dinyatakan sebagai proporsi sederhana:
- kelengkapan = sel terisi / seluruh sel wajib
- validitas = baris lolos aturan / baris bernilai
- kesegaran = baris segar / baris bertanggal
- konsistensi = rujukan ditemukan / rujukan diperiksa
"""
import csv
from datetime import date
HARI_INI = date(2026, 11, 2) # tanggal literal agar keluaran deterministik
JENDELA_HARI = 30 # batas umur baris, dalam hari
RENTANG_ITEM = (1, 100) # rentang nilai jumlah_item yang valid
KOLOM_WAJIB = ("id_pesanan", "tanggal_pesanan", "id_pelanggan", "jumlah_item")
def baca_csv(path):
with open(path, newline="", encoding="utf-8") as berkas:
return list(csv.DictReader(berkas))
def periksa(barisan, kunci_pelanggan):
"""Hitung skor keempat dimensi dan kumpulkan pelanggarannya."""
pelanggaran = []
# kelengkapan: proporsi sel wajib yang terisi
total_sel = len(barisan) * len(KOLOM_WAJIB)
sel_kosong = 0
for nomor, baris in enumerate(barisan, start=1):
label = baris["id_pesanan"] or f"baris-{nomor}"
for kolom in KOLOM_WAJIB:
if baris[kolom].strip() == "":
sel_kosong += 1
pelanggaran.append(f"kelengkapan {label:<9} {kolom} kosong")
skor_kelengkapan = (total_sel - sel_kosong) / total_sel
# validitas: baris bernilai yang memenuhi rentang dan format
bernilai = 0
valid = 0
for baris in barisan:
if baris["jumlah_item"].strip() == "":
continue
bernilai += 1
jumlah = int(baris["jumlah_item"])
date.fromisoformat(baris["tanggal_pesanan"]) # error bila format rusak
if RENTANG_ITEM[0] <= jumlah <= RENTANG_ITEM[1]:
valid += 1
else:
pelanggaran.append(
f"validitas {baris['id_pesanan']:<9} jumlah_item {jumlah} "
f"di luar rentang {RENTANG_ITEM[0]}-{RENTANG_ITEM[1]}"
)
skor_validitas = valid / bernilai
# kesegaran: baris bertanggal yang berumur di bawah batas
bertanggal = 0
segar = 0
for baris in barisan:
if baris["tanggal_pesanan"].strip() == "":
continue
bertanggal += 1
tanggal = date.fromisoformat(baris["tanggal_pesanan"])
umur = (HARI_INI - tanggal).days
if umur <= JENDELA_HARI:
segar += 1
else:
pelanggaran.append(
f"kesegaran {baris['id_pesanan']:<9} tanggal_pesanan "
f"{tanggal.isoformat()} berumur {umur} hari"
)
skor_kesegaran = segar / bertanggal
# konsistensi: id_pelanggan yang ditemukan di tabel acuan
dirujuk = 0
cocok = 0
for baris in barisan:
if baris["id_pelanggan"].strip() == "":
continue
dirujuk += 1
if baris["id_pelanggan"] in kunci_pelanggan:
cocok += 1
else:
pelanggaran.append(
f"konsistensi {baris['id_pesanan']:<9} id_pelanggan "
f"{baris['id_pelanggan']} tidak ada di pelanggan.csv"
)
skor_konsistensi = cocok / dirujuk
skor = {
"kelengkapan": (total_sel - sel_kosong, total_sel, skor_kelengkapan),
"validitas": (valid, bernilai, skor_validitas),
"kesegaran": (segar, bertanggal, skor_kesegaran),
"konsistensi": (cocok, dirujuk, skor_konsistensi),
}
return skor, pelanggaran
if __name__ == "__main__":
pesanan = baca_csv("pesanan.csv")
pelanggan = baca_csv("pelanggan.csv")
kunci = {baris["id_pelanggan"] for baris in pelanggan}
skor, pelanggaran = periksa(pesanan, kunci)
print(f"berkas diperiksa : pesanan.csv ({len(pesanan)} baris), "
f"acuan pelanggan.csv ({len(pelanggan)} baris)")
print(f"kelengkapan : {skor['kelengkapan'][0]}/{skor['kelengkapan'][1]} "
f"sel terisi = {skor['kelengkapan'][2]:.1%}")
print(f"validitas : {skor['validitas'][0]}/{skor['validitas'][1]} "
f"baris memenuhi aturan = {skor['validitas'][2]:.1%}")
print(f"kesegaran : {skor['kesegaran'][0]}/{skor['kesegaran'][1]} "
f"baris berumur <= {JENDELA_HARI} hari = {skor['kesegaran'][2]:.1%}")
print(f"konsistensi : {skor['konsistensi'][0]}/{skor['konsistensi'][1]} "
f"rujukan ada di pelanggan.csv = {skor['konsistensi'][2]:.1%}")
print()
print("pelanggaran yang ditemukan:")
for satu in pelanggaran:
print(satu)berkas diperiksa : pesanan.csv (6 baris), acuan pelanggan.csv (3 baris)
kelengkapan : 19/24 sel terisi = 79.2%
validitas : 4/5 baris memenuhi aturan = 80.0%
kesegaran : 4/5 baris berumur <= 30 hari = 80.0%
konsistensi : 3/4 rujukan ada di pelanggan.csv = 75.0%
pelanggaran yang ditemukan:
kelengkapan P103 id_pelanggan kosong
kelengkapan baris-4 id_pesanan kosong
kelengkapan baris-4 tanggal_pesanan kosong
kelengkapan baris-4 id_pelanggan kosong
kelengkapan baris-4 jumlah_item kosong
validitas P105 jumlah_item 0 di luar rentang 1-100
kesegaran P104 tanggal_pesanan 2026-09-10 berumur 53 hari
konsistensi P105 id_pelanggan C99 tidak ada di pelanggan.csvKeluaran memperlihatkan empat skor dari berkas yang sama, dan setiap skor disusutkan oleh pelanggaran yang berbeda. Kelengkapan turun karena lima sel kosong, dua di antaranya berasal dari satu baris yang seluruhnya kosong. Validitas dan kesegaran masing-masing kehilangan satu baris, sedangkan konsistensi menjadi skor terendah karena satu dari empat rujukan tidak ditemukan. Tidak ada dimensi yang menggantikan dimensi lain, sehingga keempatnya perlu dihitung secara bersamaan.
Menindaklanjuti skor#
Skor berguna setelah disandingkan dengan ambang batas yang ditetapkan per tabel. Tabel transaksi dapat mewajibkan kelengkapan 100%, sedangkan tabel log kejadian dapat menoleransi sel kosong sampai 5%. Ambang batas itu juga menentukan tindak lanjutnya, yaitu pipeline berhenti, baris dikarantina, atau skor dicatat sebagai log untuk ditinjau berkala.
Posisi pemeriksaan tiap dimensi juga berbeda di dalam pipeline. Kelengkapan dan validitas paling murah diperiksa segera setelah data masuk, sebelum nilai cacat dipakai oleh transformasi apa pun. Kesegaran biasanya diperiksa di awal run untuk memutuskan apakah sumber sudah siap, sedangkan konsistensi diperiksa setelah tabel yang dirujuk tersedia. Pemeriksaan yang ditempatkan sedini mungkin menekan biaya perbaikan, karena cacat yang terdeteksi dekat sumbernya belum sempat menular ke tabel turunan.
Kesalahan umum#
- Menghitung validitas atas sel yang kosong. Penyebabnya, pemeriksa rentang diterapkan pada seluruh baris tanpa memisahkan sel kosong. Akibatnya, satu baris cacat terhitung dua kali pada dua dimensi dan skor validitas menjadi menyesatkan. Perbaikannya, sel kosong dihitung pada dimensi kelengkapan, sedangkan aturan validitas hanya dinilai pada baris yang nilainya ada.
- Membandingkan kesegaran dengan tanggal sistem saat skrip ditulis. Penyebabnya, pembanding tanggal mengambil tanggal hari ini secara implisit. Akibatnya, keluaran skrip berubah setiap hari dan tidak dapat dipakai sebagai pemeriksaan otomatis. Perbaikannya, tanggal pembanding dinyatakan eksplisit sebagai parameter run, sebagaimana literal
HARI_INIpada skrip contoh. - Menurunkan ambang batas sampai semua skor lulus. Penyebabnya, ambang batas diturunkan agar pipeline tidak lagi berhenti. Akibatnya, data cacat mengalir ke laporan dan ambang batas kehilangan maknanya. Perbaikannya, ambang batas disetel menurut risiko tabel, lalu baris yang gagal disalurkan ke karantina sebagaimana dibahas pada topik pengujian pipeline.
Ringkasan#
- Empat dimensi kualitas yang dapat dihitung langsung dari data adalah kelengkapan, validitas, kesegaran, dan konsistensi, masing-masing dinyatakan sebagai proporsi.
- Skor per dimensi memerlukan aturan yang eksplisit, yaitu kolom wajib, rentang nilai, jendela kesegaran, dan tabel acuan.
- Skor berguna setelah disandingkan dengan ambang batas per tabel, dan setiap pelanggaran dicatat per baris agar dapat ditindaklanjuti.
Referensi#
- What is data quality? — IBM — Halaman resmi IBM yang mendefinisikan kualitas data beserta daftar dimensinya.
- Data quality — Wikipedia — Ringkasan konsep dan dimensi kualitas data yang lazim dipakai di industri.
- Documentation — Great Expectations — Dokumentasi Great Expectations, library yang menyatakan aturan kualitas sebagai ekspektasi terukur.