Konsep Dasar Duplikasi Data
1 Definisi dan Jenis Duplikat
Duplikat data terjadi ketika terdapat record yang identik atau hampir sama dalam dataset. Terdapat dua jenis utama:
- Exact Duplicates:
- Record yang benar-benar identik di semua kolom
- Contoh: Data pasien yang terinput dua kali karena kesalahan sistem
- Partial Duplicates:
- Record yang identik hanya pada beberapa kolom kunci
- Contoh: Pasien dengan nama dan alamat sama, tapi tanggal konsultasi berbeda
2 Penyebab Duplikasi Data
- Kesalahan input manual
- Proses ETL yang tidak optimal
- Penggabungan dataset dari berbagai sumber
- Masalah sistem integrasi database
Dampak Duplikasi Data
- Analisis Statistik:
- Estimasi parameter menjadi bias
- Confidence interval tidak akurat
- Machine Learning:
- Model menjadi overfit
- Pembobotan sampel tidak seimbang
- Operasional Bisnis:
- Inefisiensi penyimpanan data
- Laporan tidak akurat
Deteksi Duplikat dengan Python
1 Menggunakan Pandas
import pandas as pd # Contoh dataset data = { 'ID': [1, 2, 3, 4, 2, 5, 3], 'Nama': ['Andi', 'Budi', 'Cici', 'Dedi', 'Budi', 'Eva', 'Cici'], 'Usia': [25, 30, 22, 35, 30, 28, 22], 'Kota': ['Jakarta', 'Bandung', 'Surabaya', 'Medan', 'Bandung', 'Bali', 'Surabaya'] } df = pd.DataFrame(data) # Cek duplikat seluruh row print("Duplikat penuh:") print(df[df.duplicated(keep=False)]) # Cek duplikat berdasarkan kolom tertentu print("\nDuplikat berdasarkan ID:") print(df[df.duplicated(subset=['ID'], keep=False)])
Output:
Duplikat penuh: ID Nama Usia Kota 1 2 Budi 30 Bandung 2 3 Cici 22 Surabaya 4 2 Budi 30 Bandung 6 3 Cici 22 Surabaya Duplikat berdasarkan ID: ID Nama Usia Kota 1 2 Budi 30 Bandung 2 3 Cici 22 Surabaya 4 2 Budi 30 Bandung 6 3 Cici 22 Surabaya
2 Visualisasi Duplikat
import matplotlib.pyplot as plt import seaborn as sns # Hitung jumlah duplikat dup_counts = df.groupby(df.columns.tolist()).size().reset_index(name='counts') dup_counts = dup_counts[dup_counts['counts'] > 1] plt.figure(figsize=(10,4)) sns.barplot(x='Nama', y='counts', data=dup_counts) plt.title('Distribusi Record Duplikat') plt.show()
Teknik Penanganan Duplikat
1 Penghapusan Duplikat
a. Menghapus Semua Duplikat
df_no_dup = df.drop_duplicates() print("Data tanpa duplikat:") print(df_no_dup)
b. Menyimpan Pertama/Terakhir
# Keep first occurrence df_first = df.drop_duplicates(keep='first') # Keep last occurrence df_last = df.drop_duplicates(keep='last')
c. Menghapus Berdasarkan Kolom
# Hapus berdasarkan kolom ID saja df_no_id_dup = df.drop_duplicates(subset=['ID'])
2 Agregasi Data Duplikat
# Contoh: Rata-rata usia untuk nama yang sama df_agg = df.groupby('Nama').agg({ 'Usia': 'mean', 'Kota': lambda x: ', '.join(set(x)) }).reset_index() print("\nData setelah agregasi:") print(df_agg)
3 Penanganan Duplikat Kompleks
a. Fuzzy Matching
from fuzzywuzzy import fuzz # Contoh deteksi nama mirip nama_list = ['Andi', 'Andi Wijaya', 'Budi', 'Budiman', 'Cici'] for i in range(len(nama_list)): for j in range(i+1, len(nama_list)): similarity = fuzz.ratio(nama_list[i], nama_list[j]) if similarity > 70: # Threshold kemiripan print(f"Kemiripan tinggi: {nama_list[i]} vs {nama_list[j]} - {similarity}%")
b. Record Linkage
import recordlinkage indexer = recordlinkage.Index() indexer.block('Kota') pairs = indexer.index(df) compare = recordlinkage.Compare() compare.string('Nama', 'Nama', method='jarowinkler') compare.exact('Usia', 'Usia') features = compare.compute(pairs, df) matches = features[features.sum(axis=1) > 2] # Threshold matching
Validasi Hasil Deduplikasi
1 Metrik Evaluasi
# Hitung persentase duplikat yang dihapus original_rows = len(df) cleaned_rows = len(df_no_dup) dup_percent = (original_rows - cleaned_rows) / original_rows * 100 print(f"Persentase duplikat dihapus: {dup_percent:.2f}%") # Cek distribusi setelah dedup print("\nDistribusi usia sebelum dan sesudah:") print(pd.DataFrame({ 'Sebelum': df['Usia'].value_counts(), 'Sesudah': df_no_dup['Usia'].value_counts() }).fillna(0))
2 Visualisasi Validasi
plt.figure(figsize=(12,5)) plt.subplot(1,2,1) sns.boxplot(data=pd.DataFrame({ 'Sebelum': df['Usia'], 'Sesudah': df_no_dup['Usia'] })) plt.title('Perbandingan Distribusi Usia') plt.subplot(1,2,2) df['is_dup'] = df.duplicated(keep=False) sns.scatterplot(data=df, x='Usia', y='ID', hue='is_dup') plt.title('Identifikasi Duplikat') plt.tight_layout() plt.show()
Best Practices Deduplikasi
- Langkah-langkah Dedup yang Direkomendasikan:
def comprehensive_dedupe(df, key_columns): # Langkah 1: Exact matching df_clean = df.drop_duplicates(subset=key_columns) # Langkah 2: Fuzzy matching untuk teks if 'nama' in df.columns: df_clean['nama_clean'] = df_clean['nama'].str.lower().str.strip() dup_mask = df_clean.duplicated(subset=['nama_clean'], keep=False) df_dup = df_clean[dup_mask] # Proses manual review untuk fuzzy duplicates print("Review duplikat potensial:") display(df_dup.sort_values('nama_clean')) # Langkah 3: Validasi print(f"Duplikat dihapus: {len(df)-len(df_clean)} records") return df_clean
- Pencegahan Duplikat:
# Validasi input baru def validate_new_entry(new_data, existing_df, key_columns): merged = pd.merge(new_data, existing_df, on=key_columns, how='left', indicator=True) duplicates = merged[merged['_merge'] == 'both'] if not duplicates.empty: print("Peringatan: Data duplikat terdeteksi") display(duplicates) return False return True
- Dokumentasi Proses:
def document_dedupe(df_before, df_after, key_columns): report = { 'original_records': len(df_before), 'cleaned_records': len(df_after), 'duplicates_removed': len(df_before) - len(df_after), 'key_columns': key_columns, 'execution_date': pd.Timestamp.now(), 'duplicate_examples': df_before[df_before.duplicated(keep=False)].head(2).to_dict() } return report
Teknik Lanjutan
1 Deduplikasi Berbasis Machine Learning
from sklearn.neighbors import NearestNeighbors import numpy as np # Contoh: Deteksi duplikat berdasarkan kemiripan vektor fitur X = df[['Usia', 'ID']].values nbrs = NearestNeighbors(n_neighbors=2).fit(X) distances, indices = nbrs.kneighbors(X) # Tentukan threshold dup_threshold = 1.0 potential_dups = distances[:,1] < dup_threshold print("Potensi duplikat berbasis kemiripan:") print(df[potential_dups])
2 Deduplikasi Data Time Series
# Contoh data time series ts_data = pd.DataFrame({ 'timestamp': pd.date_range('2023-01-01', periods=10).append(pd.date_range('2023-01-01', periods=2)), 'value': np.random.randn(12) }) # Dedup dengan mempertahankan nilai terakhir ts_clean = ts_data.sort_values('timestamp').drop_duplicates( subset=['timestamp'], keep='last' ) print("\nData time series setelah dedup:") print(ts_clean)