Transformasi Data:
Scaling, Normalisasi & Feature Engineering
Data yang sudah bersih belum tentu siap dianalisis atau dimasukkan ke model. Transformasi mengubah bentuk dan skala data agar algoritma bisa belajar lebih baik, distribusi lebih sesuai asumsi, dan fitur baru yang informatif bisa diciptakan.
1. Mengapa Data Perlu Ditransformasi?
Bayangkan lomba lari di mana sebagian peserta berlari dalam meter dan sebagian lain dalam kilometer. Peserta yang berlari "5000" (meter) terlihat jauh lebih jauh dari yang berlari "5" (kilometer) — padahal jaraknya sama.
Begitu pula di machine learning: fitur tinggi badan (150–185 cm) dan gaji (3.000.000–20.000.000 rupiah) memiliki skala sangat berbeda. Algoritma seperti KNN atau regresi akan "berpikir" gaji jauh lebih penting hanya karena nilainya lebih besar — bukan karena kontribusinya pada model. Transformasi menyetarakan lapangan bermain.
2. Scaling dan Normalisasi Fitur
Dua metode scaling paling umum: Min-Max Scaling (Normalisasi) dan Standard Scaling (Standardisasi). Keduanya berbeda tujuan dan karakteristik.
Ilustrasi Visual: Efek Scaling pada Data
⚠️ Gaji mendominasi karena nilainya jutaan — algoritma jarak (KNN, K-Means) akan bias!
SETELAH MIN-MAX SCALING (semua [0, 1])✓ Semua fitur berkontribusi setara — algoritma bisa belajar dengan adil!
3. Transformasi Log untuk Distribusi Miring
Data seperti pendapatan, harga properti, atau jumlah pengunjung web sering memiliki distribusi sangat skewed kanan (ekor panjang ke kanan). Transformasi log mengubah distribusi ini menjadi lebih simetris.
Skala Richter gempa bumi adalah skala logaritmik: gempa magnitudo 7 bukan "dua kali lebih kuat" dari magnitudo 6 — tapi 10 kali lebih kuat. Skala log mengompresi rentang nilai yang sangat lebar menjadi skala yang bisa dipahami dan dianalisis.
Sama halnya dengan gaji: perbedaan antara Rp 3 juta dan Rp 6 juta terasa sangat besar bagi pekerja, sementara perbedaan antara Rp 500 juta dan Rp 503 juta terasa tidak signifikan — meski selisihnya sama secara absolut. Log transform merefleksikan persepsi relatif ini.
Nilai besar mendominasi sepenuhnya!
Perbedaan lebih proporsional dan wajar!
np.log(x): tidak bisa menangani nilai 0 (log(0) = -∞). Gunakan saat data dijamin > 0.
np.log1p(x) = log(1+x): aman untuk data yang mengandung 0. Lebih umum digunakan untuk data count dan frekuensi. Ini pilihan yang lebih aman secara default.
4. Kapan Menggunakan Metode Transformasi Mana?
Saat menggunakan scaling dalam machine learning, scaler harus di-fit hanya pada data training, kemudian hasilnya digunakan untuk men-transform data test.
Jika scaler di-fit pada seluruh dataset (termasuk test), terjadi data leakage — model "melihat" informasi dari data test saat training, membuat evaluasi model tidak valid.
5. Feature Engineering: Menciptakan Fitur Baru
Feature engineering adalah seni menciptakan variabel baru yang lebih informatif dari fitur yang sudah ada. Sering kali model sederhana dengan fitur rekayasa yang baik mengalahkan model kompleks dengan fitur mentah.
6. Agregasi dan GroupBy
Agregasi mengubah data granular (per baris) menjadi ringkasan per kelompok. Ini penting untuk analisis deskriptif, pembuatan fitur kontekstual, dan laporan.
Demo Interaktif: Kalkulator Scaling
Masukkan data numerik (pisahkan dengan koma) untuk melihat hasil Min-Max dan Z-Score secara langsung:
7. Praktik Python: Pipeline Transformasi Lengkap
7.1 Scaling dengan Scikit-learn
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler
np.random.seed(42)
df = pd.DataFrame({
'tinggi_cm' : np.random.normal(168, 8, 10),
'berat_kg' : np.random.normal(65, 12, 10),
'gaji_juta' : np.random.exponential(5, 10) + 3 # skewed kanan
})
print("=== DATA ASLI ===")
print(df.round(2).to_string())
# ── Min-Max Scaling ───────────────────────────────
scaler_mm = MinMaxScaler()
df_mm = pd.DataFrame(
scaler_mm.fit_transform(df),
columns=[c + '_mm' for c in df.columns]
)
# ── Standard Scaling ──────────────────────────────
scaler_std = StandardScaler()
df_std = pd.DataFrame(
scaler_std.fit_transform(df),
columns=[c + '_std' for c in df.columns]
)
print("\n=== STATISTIK SETELAH SCALING ===")
print("\nMin-Max (semua harus [0,1]):")
print(df_mm.describe().loc[['min','max']].round(3))
print("\nStandard (mean≈0, std≈1):")
print(df_std.describe().loc[['mean','std']].round(3))
=== STATISTIK SETELAH SCALING ===
Min-Max (semua harus [0,1]):
tinggi_cm_mm berat_kg_mm gaji_juta_mm
min 0.0 0.0 0.0
max 1.0 1.0 1.0 ✓ rentang [0,1]
Standard (mean≈0, std≈1):
tinggi_cm_std berat_kg_std gaji_juta_std
mean -0.0 -0.0 0.00
std 1.0 1.0 1.00 ✓ mean=0, std=1
7.2 Feature Engineering Lengkap
# Dataset transaksi e-commerce
df_tx = pd.DataFrame({
'user_id' : ['U01','U02','U01','U03','U02','U01'],
'waktu' : pd.to_datetime([
'2024-10-01 08:30','2024-10-01 14:00','2024-10-06 21:30',
'2024-10-07 10:00','2024-10-07 16:00','2024-10-08 09:00'
]),
'jumlah' : [45000,120000,8000,350000,67000,15000],
'item_count': [2,5,1,8,3,1]
})
# ── Feature dari datetime ─────────────────────────
df_tx['jam'] = df_tx['waktu'].dt.hour
df_tx['hari_minggu'] = df_tx['waktu'].dt.day_name()
df_tx['is_weekend'] = df_tx['waktu'].dt.dayofweek >= 5
df_tx['sesi'] = df_tx['jam'].apply(lambda h:
'pagi' if h < 12 else 'siang' if h < 17 else 'malam')
# ── Feature interaksi & turunan ───────────────────
df_tx['avg_per_item'] = df_tx['jumlah'] / df_tx['item_count']
df_tx['log_jumlah'] = np.log1p(df_tx['jumlah'])
df_tx['is_besar'] = df_tx['jumlah'] > 100000
# ── Agregasi per user (fitur kontekstual) ─────────
user_stats = df_tx.groupby('user_id')['jumlah'].agg(
total_belanja='sum', rata_belanja='mean', frekuensi='count'
).reset_index()
df_tx = df_tx.merge(user_stats, on='user_id')
df_tx['pct_dari_total'] = (df_tx['jumlah'] / df_tx['total_belanja'] * 100).round(1)
print("=== FITUR BARU ===")
print(df_tx[['user_id','jumlah','sesi','is_weekend',
'log_jumlah','avg_per_item','pct_dari_total']].round(2))
print("\n=== RINGKASAN PER USER ===")
print(user_stats)
=== FITUR BARU ===
user_id jumlah sesi is_weekend log_jumlah avg_per_item pct_dari_total
0 U01 45000 pagi False 10.71 22500.0 66.1
1 U02 120000 siang False 11.70 24000.0 64.2
2 U01 8000 malam True 8.99 8000.0 11.7
3 U03 350000 pagi True 12.77 43750.0 100.0
4 U02 67000 siang True 11.11 22333.3 35.8
5 U01 15000 pagi False 9.62 15000.0 22.1
=== RINGKASAN PER USER ===
user_id total_belanja rata_belanja frekuensi
0 U01 68000 22666.7 3
1 U02 187000 93500.0 2
2 U03 350000 350000.0 1
Uji Pemahaman Sesi 10
- Transformasi diperlukan karena algoritma berbasis jarak/gradien sensitif terhadap perbedaan skala fitur — tanpa scaling, fitur dengan nilai besar mendominasi
- Min-Max Scaling: memetakan ke [0,1]; cocok untuk NN dan image; sensitif outlier; formula: (x−min)/(max−min)
- Standard Scaling: mean=0, std=1 (z-score); lebih robust outlier; cocok untuk PCA, SVM, regresi; formula: (x−μ)/σ
- Transformasi Log: mengompres distribusi skewed kanan (pendapatan, harga); gunakan log1p() untuk data yang mengandung nol
- Aturan emas ML: fit scaler hanya pada train set, transform pada train dan test — hindari data leakage!
- RobustScaler: alternatif saat data penuh outlier — menggunakan IQR sebagai acuan, bukan mean/std
- Feature engineering: ekstraksi datetime, interaksi fitur, binning numerik ke kategori, flag/indikator biner, agregasi per grup
- Agregasi dengan groupby().agg() menghasilkan fitur kontekstual: total per user, rata-rata kelas, persentase kontribusi
- Python: MinMaxScaler, StandardScaler, RobustScaler dari sklearn.preprocessing; np.log1p(), pd.cut() untuk binning