Belajar Machine Learning - Categorical Data & Encoding Lanjutan
Episode 15 of 25

Belajar Machine Learning - Categorical Data & Encoding Lanjutan

Menguasai encoding kategori melampaui one-hot: target encoding, ordinal, dan frequency encoding, menangani high-cardinality yang meledakkan dimensi, serta workflow feature engineering ala kompetisi Kaggle untuk data tabular yang aman dari leakage.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Di episode 4 kita mengenal encoding dasar: One-Hot untuk nominal, Label untuk ordinal. Episode ini kita bongkar masalah yang tidak pernah dibahas di sana: apa yang terjadi saat kategori berjumlah ratusan ribu?

Bayangkan kolom kode_pos dengan 50.000 nilai unik, atau product_id dengan 1 juta SKU. One-Hot encoding akan meledakkan dimensi menjadi ratusan ribu kolom — lambat, rawan overfit, dan hampir tidak berguna. Untuk data tabular kompetisi seperti Kaggle, encoding lanjutan inilah yang membedakan solusi bagus dari yang biasa-biasa saja.

Kapan One-Hot Gagal

One-Hot ideal untuk 2-10 kategori bernilai nominal. Masalah muncul di high-cardinality:

Jumlah kategoriOne-HotMasalah
3-10IdealTidak ada
10-50Mulai beratDimensi membesar
100-1.000Sangat beratSparse, overfit
10.000+MustahilMeledak, tidak praktis

Selain dimensi, ada masalah kedua: kategori yang jarang muncul (misal 5 kemunculan dari 1 juta baris) — satu-hot untuk kategori langka hampir tidak memberi sinyal, hanya menambah noise.

Frequency Encoding

Frequency encoding menggantikan setiap kategori dengan frekuensi kemunculannya: kategori yang sering muncul diberi nilai tinggi, yang langka rendah.

Frequency encoding
freq = df["kota"].value_counts(normalize=True)
df["kota_freq"] = df["kota"].map(freq)

Keunggulan: satu kolom untuk kategori berapa pun banyaknya, dan langsung menangkap "popularitas". Kelemahan: dua kategori berbeda dengan frekuensi sama dianggap identik — informasi terkompresi berlebihan.

Ordinal Encoding

Untuk kategori yang memiliki urutan alami (rendah/sedang/tinggi, junior/mid/senior), ordinal encoding memberi angka sesuai urutan:

Ordinal encoding
from sklearn.preprocessing import OrdinalEncoder
 
tingkat = [["junior", "mid", "senior"]]
enc = OrdinalEncoder(categories=tingkat)
X_encoded = enc.fit_transform(df[["level"]])

Yang penting: jangan memakai ini untuk kategori nominal — memberi angka "acak" pada kota akan membuat model mengasumsikan urutan yang tidak ada.

Target Encoding

Target encoding mengganti kategori dengan nilai rata-rata target untuk kategori tersebut. Contoh: untuk kolom kota, setiap nilai kota diganti dengan rata-rata harga rumah di kota itu.

Target encoding manual
means = df.groupby("kota")["harga"].mean()
df["kota_target"] = df["kota"].map(means)

Kekuatannya besar — kolom kota_target mengandung sinyal prediktif langsung. Tapi inilah encoding paling berbahaya jika salah: karena nilai fitur dihitung dari target, ia sangat mudah bocor.

Warning

Target encoding menghitung statistik dari target. Jika dihitung dari seluruh data termasuk test set, model "melihat" jawaban test saat training — leakage. Solusi wajib: gunakan TargetEncoder dari category_encoders dengan cv-fold, atau tambahkan smoothing agar kategori langka ditarik ke rata-rata global.

Cara yang aman memakai library khusus:

Target encoding dengan smoothing
from category_encoders import TargetEncoder
 
enc = TargetEncoder(cols=["kota"], smoothing=20)
X_enc = enc.fit_transform(X_train, y_train)   # fit dengan y!
X_test_enc = enc.transform(X_test)            # transform saja

Perhatikan: fit_transform menerima y_train karena itulah sumber informasinya — dan library ini menangani smoothing serta fold internal untuk mengurangi overfitting.

Dampak Encoding terhadap Jenis Model

Pilihan encoding sebaiknya menyesuaikan model:

ModelEncoding terbaik
Linear (regresi/logistic)Frequency, target (dengan hati-hati), binning
kNN / distance-basedSemua harus discale; hindari one-hot dimensi besar
Tree-basedBisa makan raw categorical (CatBoost), ordinal, frequency

Menariknya, CatBoost punya dukungan kategori native: ia melakukan target encoding internal dengan mekanisme anti-leakage bawaan:

CatBoost native categorical
from catboost import CatBoostClassifier
 
model = CatBoostClassifier(cat_features=["kota", "produk"], iterations=500)
model.fit(X_train, y_train)

Kalian tinggal mendeklarasikan kolom mana yang kategorikal (cat_features) — CatBoost menangani encoding-nya sendiri. Ini alasan mengapa CatBoost menjadi pilihan serius untuk dataset dengan banyak kolom kategorikal.

Workflow ala Kaggle

Praktik yang terbukti di kompetisi tabular:

  1. Understand data: identifikasi cardinality dan tipe tiap kolom.
  2. Baseline cepat: random forest / LightGBM dengan raw features untuk patokan.
  3. Eksperimen encoding: satu alur untuk baseline, satu lagi dengan encoding lanjutan.
  4. Evaluasi dengan CV yang sama: bandingkan adil (episode 10).
  5. Pilih yang menang: jangan terlalu banyak fitur — tiap fitur baru harus terbukti menaikkan skor CV.
Bandingkan skema encoding
from sklearn.model_selection import cross_val_score
import lightgbm as lgb
 
def cv_score(X, y, cat_cols=None):
    model = lgb.LGBMClassifier(random_state=42)
    return cross_val_score(model, X, y, cv=5, scoring="roc_auc").mean()
 
# Skema A: one-hot
X_a = pd.get_dummies(df[["kota", "produk"]])
print(f"One-Hot:        {cv_score(X_a, y):.4f}")
 
# Skema B: frequency + ordinal
df["kota_freq"] = df["kota"].map(df["kota"].value_counts(normalize=True))
df["produk_freq"] = df["produk"].map(df["produk"].value_counts(normalize=True))
X_b = df[["kota_freq", "produk_freq"]]
print(f"Frequency:      {cv_score(X_b, y):.4f}")

Angka CV inilah yang menjadi juri — bukan intuisi.

Common Pitfalls

  • Target encoding tanpa smoothing/CV — overfit dan leakage.
  • One-Hot untuk high-cardinality — dimensi meledak, model lemah.
  • Ordinal encoding untuk nominal — memaksa urutan yang tidak ada.
  • Menggabungkan handle_unknown yang tidak konsisten — kategori test yang tidak ada di train harus punya nilai default.
  • Tidak membandingkan skema encoding dengan CV yang sama — keputusan jadi tidak adil.

Penutup

Pada episode 15 ini, kalian telah menguasai encoding lanjutan untuk data kategorikal.

Inti yang harus dibawa pulang:

  • One-Hot gagal di high-cardinality; gunakan frequency, ordinal, atau target encoding.
  • Target encoding kuat tapi rawan leakage — wajib smoothing/CV.
  • CatBoost menangani kategori secara native.
  • Selalu bandingkan skema encoding dengan CV yang adil.

Di episode 16 selanjutnya kita masuk dimensi baru: model security & adversarial ML — data poisoning, adversarial examples, membership inference, plus strategi mitigasi, sanitasi data, dan monitoring model di produksi. Sampai jumpa di episode 16!