Skip to main content

Persiapan Data: Feature Encoding

Salah satu persyaratan penting dalam Machine Learning adalah memastikan data yang diberikan kepada model memiliki format yang dapat diproses oleh algoritma.

Banyak algoritma Machine Learning pada Scikit-Learn bekerja dengan data numerik. Sementara itu, dataset dunia nyata sering memiliki data berbentuk teks atau kategori seperti:

Make
Color
Fuel Type
Gender
City
Category

Data tersebut perlu dikonversi menjadi representasi numerik sebelum digunakan oleh model.

Proses mengubah data kategorikal menjadi bentuk numerik disebut feature encoding.

Apa Itu Feature Encoding?

Feature encoding adalah proses mengubah data kategorikal menjadi representasi numerik yang dapat digunakan oleh algoritma Machine Learning.

Contoh data awal:

MakeColorDoors
ToyotaBlue4
HondaRed4
BMWBlack2
ToyotaRed4

Kolom:

Make
Color

berisi data kategorikal berbentuk teks.

Model Machine Learning tidak dapat begitu saja memperlakukan:

Toyota
Honda
BMW

sebagai nilai numerik.

Karena itu, data perlu di-encode.

Scikit Learn

Mengapa Data Harus Berbentuk Numerik?

Banyak algoritma Machine Learning melakukan perhitungan matematis terhadap data.

Misalnya:

x₁ + x₂
x₁ - x₂
x₁ × x₂
distance(x₁, x₂)

Jika sebuah fitur berisi:

Toyota
Honda
BMW

tidak ada operasi matematika langsung yang bermakna seperti:

Toyota + Honda

Karena itu, kategori perlu direpresentasikan dalam bentuk numerik.

Namun, proses konversi harus dilakukan dengan hati-hati.

Kita tidak boleh sembarangan mengubah:

Toyota → 1
Honda → 2
BMW → 3

karena angka tersebut dapat memberikan kesan bahwa:

BMW > Honda > Toyota

atau terdapat jarak numerik tertentu antar kategori.

Padahal kategori tersebut tidak memiliki urutan seperti itu.

Contoh Dataset Car Sales

Misalnya kita memiliki dataset penjualan mobil:

MakeColourDoorsOdometer (KM)Price
ToyotaBlue41500004000
HondaRed41200005000
BMWBlack28000012000
ToyotaWhite41000007000

Misalnya:

Make
Colour

merupakan categorical features.

Sedangkan:

Odometer (KM)

merupakan numerical feature.

Kolom:

Price

dapat digunakan sebagai target jika tujuan kita adalah memprediksi harga mobil.

Memeriksa Tipe Data

Sebelum melakukan encoding, kita dapat memeriksa tipe data menggunakan Pandas:

car_sales.dtypes

Contoh hasil:

Make object
Colour object
Doors int64
Odometer (KM) int64
Price int64

Dari hasil tersebut kita dapat melihat bahwa:

Make → object
Colour → object

merupakan data kategorikal berbentuk teks.

Sedangkan:

Doors
Odometer (KM)
Price

merupakan data numerik.

Masalah Ketika Data Teks Langsung Digunakan

Misalnya kita membuat:

X = car_sales.drop("Price", axis=1)
y = car_sales["Price"]

Kemudian mencoba melatih:

from sklearn.ensemble import RandomForestRegressor

model = RandomForestRegressor()

model.fit(X, y)

Jika X masih memiliki kolom teks seperti:

Make
Colour

model dapat menghasilkan error karena data kategorikal tersebut belum dikonversi ke representasi yang dapat diproses.

Contoh error dapat berupa:

ValueError: could not convert string to float

Masalahnya bukan pada Random Forest secara khusus, tetapi pada representasi data yang diberikan kepada estimator.

Solusi: Feature Encoding

Salah satu solusi yang umum digunakan adalah:

Categorical Data


Feature Encoding


Numerical Data


Machine Learning Model

Salah satu teknik encoding yang paling umum adalah One-Hot Encoding.

Apa Itu One-Hot Encoding?

One-Hot Encoding mengubah setiap kategori menjadi kolom biner.

Misalnya terdapat:

Color
-----
Red
Blue
Green

One-Hot Encoding dapat menghasilkan:

Color_RedColor_BlueColor_Green
100
010
001

Setiap baris hanya memiliki nilai 1 pada kategori yang sesuai.

Mengapa Menggunakan 0 dan 1?

Nilai:

1

menunjukkan bahwa kategori tersebut aktif atau dimiliki oleh sebuah sampel.

Sedangkan:

0

menunjukkan bahwa kategori tersebut tidak aktif.

Contohnya:

Color = Red

menjadi:

Color_Red = 1
Color_Blue = 0
Color_Green = 0

OneHotEncoder dari Scikit-Learn

Scikit-Learn menyediakan class:

OneHotEncoder

yang berada pada module:

sklearn.preprocessing

Import:

from sklearn.preprocessing import OneHotEncoder

Kemudian:

one_hot = OneHotEncoder()

Menggunakan ColumnTransformer

Kita biasanya tidak hanya memiliki data kategorikal.

Dataset dapat memiliki kombinasi:

Categorical Features
+
Numerical Features

Misalnya:

Make → categorical
Colour → categorical
Doors → categorical
Odometer → numerical

Kita ingin melakukan encoding hanya pada kolom kategorikal.

Untuk itu kita dapat menggunakan:

ColumnTransformer

Import:

from sklearn.compose import ColumnTransformer

Menentukan Kolom Kategorikal

Misalnya:

categorical_features = [
"Make",
"Colour",
"Doors"
]

Kolom tersebut akan diproses menggunakan One-Hot Encoding.

Sedangkan kolom numerik lainnya dapat dibiarkan.

Membuat OneHotEncoder

from sklearn.preprocessing import OneHotEncoder

one_hot = OneHotEncoder(
handle_unknown="ignore"
)

Parameter:

handle_unknown="ignore"

berguna ketika terdapat kategori pada data baru yang tidak ditemukan saat encoder melakukan fitting.

Contohnya:

Training:
Toyota
Honda
BMW

Data baru:
Toyota
Honda
Tesla

Jika Tesla belum pernah ditemukan saat training, handle_unknown="ignore" membantu encoder menangani kategori tersebut tanpa menghasilkan error karena kategori baru.

Membuat ColumnTransformer

Contoh:

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder

categorical_features = [
"Make",
"Colour",
"Doors"
]

one_hot = OneHotEncoder(
handle_unknown="ignore"
)

transformer = ColumnTransformer(
transformers=[
(
"one_hot",
one_hot,
categorical_features
)
],
remainder="passthrough"
)

Memahami remainder="passthrough"

Parameter:

remainder="passthrough"

berarti kolom yang tidak disebutkan dalam transformer akan tetap diteruskan tanpa transformasi dari transformer tersebut.

Misalnya:

Make
Colour
Doors
Odometer (KM)

Kita hanya menentukan:

Make
Colour
Doors

sebagai categorical features.

Maka:

Make → One-Hot Encoding
Colour → One-Hot Encoding
Doors → One-Hot Encoding
Odometer (KM) → tetap diteruskan

Melakukan Transformasi

Setelah transformer dibuat:

X_transformed = transformer.fit_transform(X)

Proses tersebut melakukan dua hal:

fit

Mempelajari kategori

transform

Mengubah data menjadi representasi numerik

Memahami fit_transform

Method:

fit_transform()

merupakan kombinasi:

fit()

dan:

transform()

Secara konseptual:

fit

└── Belajar parameter/kategori dari data

transform

└── Mengubah data menggunakan hasil fit

Untuk data training, kita biasanya menggunakan:

fit_transform()

Sedangkan untuk data baru atau test set:

transform()

Perbedaan ini penting untuk mencegah data leakage.

Melihat Hasil Transformasi

Setelah:

X_transformed = transformer.fit_transform(X)

kita dapat memeriksa:

print(X_transformed)

Output dapat berupa array atau sparse matrix tergantung konfigurasi encoder dan data.

Contoh output:

array([[0.00000e+00, 1.00000e+00, 0.00000e+00, ..., 1.00000e+00,
0.00000e+00, 3.54310e+04],
[1.00000e+00, 0.00000e+00, 0.00000e+00, ..., 0.00000e+00,
1.00000e+00, 1.92714e+05],
[0.00000e+00, 1.00000e+00, 0.00000e+00, ..., 1.00000e+00,
0.00000e+00, 8.47140e+04],
...,
[0.00000e+00, 0.00000e+00, 1.00000e+00, ..., 1.00000e+00,
0.00000e+00, 6.66040e+04],
[0.00000e+00, 1.00000e+00, 0.00000e+00, ..., 1.00000e+00,
0.00000e+00, 2.15883e+05],
[0.00000e+00, 0.00000e+00, 0.00000e+00, ..., 1.00000e+00,
0.00000e+00, 2.48360e+05]], shape=(1000, 13))

Jangan kaget jika hasilnya tidak terlihat seperti DataFrame biasa.

tip

Agar hasil transformed lebih rapi untuk dilihat, kita dapat memasukan nilainya ke dalam DataFrame:

pd.DataFrame(transformer_X)

Sparse Matrix

One-Hot Encoding dapat menghasilkan sparse matrix.

Sparse matrix digunakan ketika sebagian besar nilai adalah 0.

Misalnya:

RedBlueGreenBlackWhite
10000
01000
00010
00001

Sebagian besar nilai adalah:

0

Daripada menyimpan semua nilai 0 secara penuh, sparse representation dapat menghemat memori pada dataset tertentu.

Melihat Nama Feature Setelah Encoding

Pada versi Scikit-Learn yang mendukungnya, kita dapat menggunakan:

feature_names = transformer.get_feature_names_out()

print(feature_names)

Contoh hasil dapat terlihat seperti:

[
"one_hot__Make_BMW",
"one_hot__Make_Honda",
"one_hot__Make_Toyota",
"one_hot__Colour_Black",
"one_hot__Colour_Blue",
"one_hot__Colour_Red",
"one_hot__Doors_2",
"one_hot__Doors_4",
"remainder__Odometer (KM)"
]

Nama sebenarnya bergantung pada dataset dan konfigurasi transformer.

Mengubah Hasil Kembali Menjadi DataFrame

Untuk kebutuhan eksplorasi, hasil transformasi dapat dikonversi menjadi DataFrame.

Contoh:

import pandas as pd

X_transformed_df = pd.DataFrame(
X_transformed.toarray(),
columns=transformer.get_feature_names_out()
)

X_transformed_df.head()

Namun, perlu diperhatikan bahwa .toarray() mengubah sparse matrix menjadi dense array.

Untuk dataset dengan jumlah kategori yang sangat besar, hal tersebut dapat menggunakan memori yang jauh lebih besar.

Bagaimana dengan Kolom Doors?

Misalnya:

Doors
-----
2
3
4
5

Secara teknis angka tersebut sudah merupakan numerical data.

Namun, kita perlu mempertimbangkan makna fitur tersebut.

Jika angka:

2
3
4
5

hanya menunjukkan kategori jumlah pintu, kita dapat memperlakukannya sebagai categorical feature.

Contohnya:

Doors_2
Doors_3
Doors_4
Doors_5

Hal ini berbeda dengan fitur seperti:

Odometer

yang memiliki makna kuantitatif.

Categorical vs Numerical

Perhatikan perbedaan berikut:

FeatureTipeMakna
MakeCategoricalMerek mobil
ColourCategoricalWarna
DoorsBisa categoricalJumlah pintu
OdometerNumericalJarak tempuh
PriceNumericalHarga

Jadi, tipe data Python tidak selalu menentukan bagaimana sebuah fitur harus diperlakukan dalam Machine Learning.

Contohnya:

Doors = 4

secara Python adalah integer, tetapi secara konseptual dapat diperlakukan sebagai kategori.

Alternatif dengan Pandas get_dummies()

Selain menggunakan Scikit-Learn, Pandas menyediakan:

pd.get_dummies()

Contoh:

import pandas as pd

dummies = pd.get_dummies(
car_sales[
["Make", "Colour", "Doors"]
]
)

Fungsi tersebut akan membuat kolom dummy berdasarkan kategori yang ditemukan.

Contoh Hasil get_dummies()

Misalnya:

Make
----
Toyota
Honda
BMW

dapat berubah menjadi:

Make_BMWMake_HondaMake_Toyota
001
010
100

Kolom kategorikal berubah menjadi representasi biner.

Membandingkan OneHotEncoder dan get_dummies()

MetodeLibraryCocok untuk
OneHotEncoderScikit-LearnWorkflow Machine Learning
pd.get_dummies()PandasEksplorasi dan preprocessing sederhana

Keduanya dapat menghasilkan representasi one-hot, tetapi penggunaannya berbeda.

Untuk workflow Machine Learning yang membutuhkan pipeline preprocessing, OneHotEncoder biasanya lebih cocok karena dapat digabungkan dengan:

ColumnTransformer
+
Pipeline
+
GridSearchCV

Masalah dengan Encoding Sebelum Train-Test Split

Kesalahan yang perlu dihindari adalah melakukan fitting encoder pada seluruh dataset sebelum train-test split.

Contohnya:

Seluruh Dataset


fit encoder


Train-Test Split

Cara tersebut dapat membuat informasi dari test set ikut digunakan dalam proses preprocessing.

Pendekatan yang lebih aman adalah:

Dataset


Train-Test Split

├─────────────┐
│ │
Training Test
│ │
▼ │
fit encoder │
│ │
transform │
│ │
└──────┐ │
│ │
▼ ▼
Model transform
test

Dengan demikian encoder belajar kategori dari training data.

Menggunakan Pipeline

Untuk workflow yang lebih aman, kita dapat menggabungkan preprocessing dan model menggunakan Pipeline.

Contoh sederhana:

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestRegressor

categorical_features = [
"Make",
"Colour",
"Doors"
]

one_hot = OneHotEncoder(
handle_unknown="ignore"
)

preprocessor = ColumnTransformer(
transformers=[
(
"one_hot",
one_hot,
categorical_features
)
],
remainder="passthrough"
)

model = RandomForestRegressor(
random_state=42
)

pipeline = Pipeline(
steps=[
("preprocessor", preprocessor),
("model", model)
]
)

Dengan Pipeline:

Data


Preprocessor

├── One-Hot Encoding

└── Numerical Features


Random Forest


Prediction

Pipeline juga membantu menjaga preprocessing tetap konsisten ketika digunakan pada training dan data baru.

Membagi Data Sebelum Fitting Pipeline

Setelah Pipeline dibuat, kita dapat melakukan train-test split:

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)

Kemudian:

pipeline.fit(X_train, y_train)

Untuk melakukan prediksi:

y_preds = pipeline.predict(X_test)

Dan evaluasi:

score = pipeline.score(X_test, y_test)

print(score)

Dengan cara ini, preprocessing dipelajari dari training data melalui Pipeline.

Workflow Lengkap

Berikut workflow feature encoding yang lebih aman:

Raw Dataset


Pisahkan X dan y


Train-Test Split

├─────────────────┐
│ │
X_train X_test
│ │
▼ │
Preprocessing │
│ │
├── One-Hot │
└── Passthrough │
│ │
▼ │
Model │
│ │
▼ │
Prediction ◄──────────┘


Evaluation

Contoh Lengkap dengan Car Sales

Berikut contoh workflow yang menggabungkan beberapa konsep:

import pandas as pd

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor

# Membaca dataset
car_sales = pd.read_csv("car-sales-extended.csv")

# Memisahkan features dan target
X = car_sales.drop("Price", axis=1)
y = car_sales["Price"]

# Menentukan kolom kategorikal
categorical_features = [
"Make",
"Colour",
"Doors"
]

# Membuat encoder
one_hot = OneHotEncoder(
handle_unknown="ignore"
)

# Membuat preprocessor
preprocessor = ColumnTransformer(
transformers=[
(
"one_hot",
one_hot,
categorical_features
)
],
remainder="passthrough"
)

# Membuat model
model = RandomForestRegressor(
random_state=42
)

# Membuat pipeline
pipeline = Pipeline(
steps=[
("preprocessor", preprocessor),
("model", model)
]
)

# Membagi data
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)

# Training
pipeline.fit(X_train, y_train)

# Prediksi
y_preds = pipeline.predict(X_test)

# Evaluasi
score = pipeline.score(X_test, y_test)

print("Model score:", score)

Mengapa Pipeline Sangat Berguna?

Tanpa Pipeline, kita mungkin harus mengatur banyak langkah secara manual:

Fit encoder

Transform training

Transform test

Fit model

Predict

Dengan Pipeline:

pipeline.fit(X_train, y_train)

dan:

pipeline.predict(X_test)

Scikit-Learn menangani urutan preprocessing dan model sesuai langkah yang telah kita definisikan.

Pipeline juga sangat berguna ketika nanti kita menggunakan:

Cross-validation
Hyperparameter tuning
GridSearchCV
RandomizedSearchCV

Kesalahan Umum

Kesalahan 1 - Langsung Memberikan String ke Model

Contoh:

model.fit(X, y)

sementara X masih memiliki:

Make
Colour

berupa string.

Solusi:

Lakukan encoding terlebih dahulu.

Kesalahan 2 - Mengubah Kategori Menjadi Angka Secara Sembarangan

Contoh:

Toyota → 1
Honda → 2
BMW → 3

Cara tersebut dapat memperkenalkan hubungan numerik yang sebenarnya tidak ada.

Untuk kategori nominal, One-Hot Encoding sering lebih sesuai.

Kesalahan 3 - Fit Encoder pada Seluruh Dataset

Jangan melakukan:

encoder.fit(X)

sebelum train-test split jika encoder tersebut mempelajari informasi dari seluruh dataset.

Lebih aman menggunakan:

Training → fit
Test → transform

atau menggunakan Pipeline.

Kesalahan 4 - Tidak Menangani Kategori Baru

Data baru dapat memiliki kategori yang tidak muncul pada training.

Contohnya:

Training:
Toyota
Honda
BMW

Production:
Toyota
Honda
Tesla

Penggunaan:

handle_unknown="ignore"

dapat membantu menangani kondisi tersebut.

Checklist Feature Encoding

Sebelum menjalankan model, periksa:

  • Sudah mengetahui fitur mana yang kategorikal.
  • Sudah mengetahui fitur mana yang numerik.
  • Data kategorikal sudah di-encode.
  • Tidak melakukan encoding secara sembarangan.
  • OneHotEncoder menggunakan konfigurasi yang sesuai.
  • handle_unknown="ignore" dipertimbangkan untuk data baru.
  • Preprocessing tidak menyebabkan data leakage.
  • Train dan test diproses secara konsisten.
  • Pipeline digunakan ketika workflow semakin kompleks.

Ringkasan

Machine Learning sering membutuhkan data dalam bentuk numerik.

Jika dataset memiliki:

Make
Colour
Fuel Type
Category

data tersebut perlu diproses sebelum diberikan kepada model.

Salah satu pendekatan yang umum adalah:

Categorical Data


OneHotEncoder


0 dan 1


Machine Learning Model

Dalam Scikit-Learn, kombinasi:

OneHotEncoder

dan:

ColumnTransformer

memungkinkan kita melakukan encoding hanya pada kolom tertentu sementara fitur numerik tetap dipertahankan.

Untuk workflow Machine Learning yang lebih aman, kita dapat menggunakan:

ColumnTransformer
+
Pipeline
+
Machine Learning Model

Dengan pendekatan tersebut, preprocessing dapat diterapkan secara konsisten dan risiko data leakage dapat dikurangi.

Cheat Sheet

KebutuhanKode
Import OneHotEncoderfrom sklearn.preprocessing import OneHotEncoder
Membuat encoderOneHotEncoder(handle_unknown="ignore")
Import ColumnTransformerfrom sklearn.compose import ColumnTransformer
Menentukan kolom kategoricategorical_features = ["Make", "Colour", "Doors"]
Membuat transformerColumnTransformer(...)
Transform datatransformer.fit_transform(X)
Melihat nama fiturtransformer.get_feature_names_out()
Pandas dummy encodingpd.get_dummies(data)
Membuat PipelinePipeline(steps=[...])