šŸ“˜ Pertemuan 6 - Pembersihan dan Transformasi Data

šŸŽÆ Tujuan Pembelajaran

  1. Memahami pentingnya data cleaning
  2. Mengidentifikasi dan menangani missing values
  3. Mendeteksi dan menangani data duplikat
  4. Melakukan normalisasi dan standarisasi
  5. Menerapkan pipeline cleaning pada dataset nyata

🧩 1. Mengapa Data Cleaning Penting?

"Garbage In, Garbage Out" - Data buruk = Analisis buruk!

Data mentah sering mengandung:

  • āŒ Missing Values - Data kosong/NULL
  • āŒ Duplicate Data - Data ganda
  • āŒ Inconsistent Format - Format berbeda
  • āŒ Outliers - Nilai ekstrem
  • āŒ Invalid Data - Data di luar range

Dampak Data Kotor:

  • Bias dalam analisis
  • Model ML tidak akurat
  • Waste resources
  • Keputusan bisnis yang salah

šŸ“¦ 2. Import Library dan Dataset

# Import library
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import MinMaxScaler, StandardScaler

# Dataset Titanic
url = "https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv"
df = pd.read_csv(url)

print("Dataset Titanic")
print(df.head())
print(f"\nShape: {df.shape}")
print(f"Total: {len(df):,} baris")

🚨 3. Menangani Missing Values

Deteksi Missing Values

# Cek missing values
print("\nMISSING VALUES CHECK")
print("="*50)

missing = df.isnull().sum()
missing_pct = (df.isnull().sum() / len(df) * 100).round(2)

missing_df = pd.DataFrame({
    'Missing': missing,
    'Percentage': missing_pct
})
missing_df = missing_df[missing_df['Missing'] > 0].sort_values('Missing', ascending=False)
print(missing_df)

# Visualisasi
plt.figure(figsize=(10, 6))
missing_df['Percentage'].plot(kind='barh', color='crimson')
plt.title('Missing Values per Kolom (%)', fontweight='bold')
plt.xlabel('Percentage')
plt.grid(axis='x', alpha=0.3)
plt.tight_layout()
plt.show()

Strategi Menangani Missing Values

Strategi Kapan Digunakan Keuntungan
Drop Rows Missing < 5% Sederhana, cepat
Drop Columns Missing > 70% Hapus kolom tidak berguna
Fill Mean/Median Data numerik Preserve data size
Fill Mode Data kategorikal Logis untuk kategori
# Implementasi cleaning
df_clean = df.copy()

# 1. Drop kolom dengan >70% missing
threshold = 0.7 * len(df)
df_clean = df_clean.dropna(thresh=threshold, axis=1)

# 2. Fill Age dengan median
df_clean['Age'].fillna(df_clean['Age'].median(), inplace=True)

# 3. Fill Embarked dengan mode
df_clean['Embarked'].fillna(df_clean['Embarked'].mode()[0], inplace=True)

# 4. Drop baris dengan missing
df_clean = df_clean.dropna()

print(f"\nāœ… Cleaning selesai!")
print(f"Sebelum: {df.shape}")
print(f"Sesudah: {df_clean.shape}")
print(f"Data hilang: {df.shape[0] - df_clean.shape[0]} baris")

šŸ” 4. Menghapus Duplikat

# Cek duplikat
duplicates = df_clean.duplicated().sum()
print(f"\nDuplikat: {duplicates} baris")

if duplicates > 0:
    df_clean = df_clean.drop_duplicates()
    print(f"āœ… {duplicates} duplikat dihapus")
else:
    print("āœ“ Tidak ada duplikat")

šŸ”¢ 5. Normalisasi & Standarisasi

Perbedaan Normalisasi vs Standarisasi

Aspek Normalisasi Standarisasi
Formula (X - min) / (max - min) (X - μ) / σ
Range [0, 1] Tidak terbatas
Kapan Data merata Data normal
Outlier Sangat sensitif Kurang sensitif
# Normalisasi dan Standarisasi
numeric_cols = ['Age', 'Fare']

# Normalisasi (0-1)
scaler_norm = MinMaxScaler()
df_clean[['Age_norm', 'Fare_norm']] = scaler_norm.fit_transform(df_clean[numeric_cols])

# Standarisasi (mean=0, std=1)
scaler_std = StandardScaler()
df_clean[['Age_std', 'Fare_std']] = scaler_std.fit_transform(df_clean[numeric_cols])

# Perbandingan distribusi
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('Original vs Normalized vs Standardized', fontsize=16, fontweight='bold')

# Original
axes[0, 0].hist(df_clean['Age'], bins=30, color='blue', alpha=0.7, edgecolor='black')
axes[0, 0].set_title('Age - Original')
axes[0, 1].hist(df_clean['Fare'], bins=30, color='blue', alpha=0.7, edgecolor='black')
axes[0, 1].set_title('Fare - Original')

# Normalized
axes[1, 0].hist(df_clean['Age_norm'], bins=30, color='green', alpha=0.7, edgecolor='black')
axes[1, 0].set_title('Age - Normalized')
axes[1, 1].hist(df_clean['Fare_norm'], bins=30, color='green', alpha=0.7, edgecolor='black')
axes[1, 1].set_title('Fare - Normalized')

plt.tight_layout()
plt.show()

# Statistik
for col in ['Age', 'Fare']:
    print(f"\n{col}:")
    print(f"  Original: Mean={df_clean[col].mean():.2f}, Std={df_clean[col].std():.2f}")
    print(f"  Normalized: Mean={df_clean[col+'_norm'].mean():.2f}, Std={df_clean[col+'_norm'].std():.2f}")
    print(f"  Standardized: Mean={df_clean[col+'_std'].mean():.2f}, Std={df_clean[col+'_std'].std():.2f}")

šŸ“Š 6. Studi Kasus - Pipeline Cleaning Titanic

🚢 Complete Data Cleaning Pipeline

Pipeline lengkap untuk membersihkan Titanic dataset

# PIPELINE LENGKAP
print("="*60)
print("DATA CLEANING PIPELINE - TITANIC")
print("="*60)

# 1. Load
df = pd.read_csv(url)
print(f"\n1ļøāƒ£ Load: {df.shape}")

# 2. Drop kolom tidak penting
drop_cols = ['PassengerId', 'Name', 'Ticket', 'Cabin']
df = df.drop(columns=drop_cols)
print(f"2ļøāƒ£ Drop kolom: {df.shape}")

# 3. Handle missing
df['Age'] = df.groupby('Pclass')['Age'].transform(lambda x: x.fillna(x.median()))
df['Embarked'].fillna(df['Embarked'].mode()[0], inplace=True)
df['Fare'] = df.groupby('Pclass')['Fare'].transform(lambda x: x.fillna(x.median()))
print(f"3ļøāƒ£ Fill missing: {df.isnull().sum().sum()} tersisa")

# 4. Remove duplicates
df = df.drop_duplicates()
print(f"4ļøāƒ£ Remove duplicates: {df.shape}")

# 5. Feature engineering
df['Family_Size'] = df['SibSp'] + df['Parch'] + 1
df['Is_Alone'] = (df['Family_Size'] == 1).astype(int)
print(f"5ļøāƒ£ Features added: Family_Size, Is_Alone")

# 6. Normalize
scaler = MinMaxScaler()
df[['Age_scaled', 'Fare_scaled']] = scaler.fit_transform(df[['Age', 'Fare']])
print(f"6ļøāƒ£ Normalized: Age, Fare")

print(f"\nāœ… Pipeline complete: {df.shape}")
print(f"Missing values: {df.isnull().sum().sum()}")

# Simpan
df.to_csv('titanic_cleaned.csv', index=False)
print("\nšŸ’¾ Saved: titanic_cleaned.csv")

šŸ’” Best Practices Data Cleaning:

  • Understand your data first - eksplorasi dulu
  • Document everything - catat semua keputusan
  • Keep original data - backup data asli
  • Be consistent - strategi yang konsisten
  • Validate results - check dengan visualisasi
  • Domain knowledge matters - pahami konteks

🧩 7. Latihan Mandiri

Latihan 1: Pipeline Cleaning

  1. Download dataset dari Kaggle
  2. Identifikasi semua masalah data
  3. Buat pipeline cleaning lengkap
  4. Dokumentasikan setiap langkah
  5. Visualisasikan before-after

Latihan 2: Missing Values

  1. Buat dataset dengan missing values
  2. Implementasi 3 strategi berbeda
  3. Bandingkan hasilnya
  4. Tentukan strategi terbaik

āœļø Kesimpulan

Pada pertemuan ini, mahasiswa telah mempelajari:

  • āœ… Pentingnya data cleaning
  • āœ… Teknik handling missing values
  • āœ… Mendeteksi dan hapus duplikat
  • āœ… Normalisasi vs standarisasi
  • āœ… Pipeline cleaning lengkap
  • āœ… Best practices cleaning

Pertemuan selanjutnya: Studi Kasus dengan dataset nyata