Data Cleanup : Removing Duplicates

Data Cleanup : Removing Duplicates

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:

  1. Exact Duplicates:
    • Record yang benar-benar identik di semua kolom
    • Contoh: Data pasien yang terinput dua kali karena kesalahan sistem
  2. 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

  1. Analisis Statistik:
    • Estimasi parameter menjadi bias
    • Confidence interval tidak akurat
  2. Machine Learning:
    • Model menjadi overfit
    • Pembobotan sampel tidak seimbang
  3. Operasional Bisnis:
    • Inefisiensi penyimpanan data
    • Laporan tidak akurat

Deteksi Duplikat dengan Python

1 Menggunakan Pandas

python
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

python
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

python
df_no_dup = df.drop_duplicates()
print("Data tanpa duplikat:")
print(df_no_dup)

b. Menyimpan Pertama/Terakhir

python
# Keep first occurrence
df_first = df.drop_duplicates(keep='first')

# Keep last occurrence
df_last = df.drop_duplicates(keep='last')

c. Menghapus Berdasarkan Kolom

python
# Hapus berdasarkan kolom ID saja
df_no_id_dup = df.drop_duplicates(subset=['ID'])

2 Agregasi Data Duplikat

python
# 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

python
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

python
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

python
# 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

python
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

  1. Langkah-langkah Dedup yang Direkomendasikan:
    python
    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
  2. Pencegahan Duplikat:
    python
    # 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
  3. Dokumentasi Proses:
    python
    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

python
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

python
# 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)

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *