Scaling dan Normalisasi Fitur: Kapan Wajib dan Kapan Mubazir
TL;DR
Scaling fitur adalah proses nyamain rentang nilai antar kolom numerik biar nggak ada kolom yang mendominasi cuma gara-gara angkanya besar. Model yang ngitung jarak atau pakai gradient descent (KNN, SVM, regresi logistik, jaringan saraf, PCA) wajib pakai scaling. Model berbasis pohon kayak random forest dan gradient boosting nggak butuh sama sekali. Selalu fit scaler cuma di data training, terus transform data test pakai parameter yang sama.
Scaling fitur adalah proses nyamain rentang nilai antar kolom numerik. Tujuannya biar kolom dengan angka besar nggak otomatis dianggap lebih penting sama model.
Kolom umur_pelanggan isinya 18 sampai 70. Kolom total_belanja isinya 15.000 sampai 4.800.000. Buat model yang ngitung jarak, selisih satu rupiah dan selisih satu tahun umur diperlakukan sama besarnya. Hasilnya, kolom belanja nyetir semuanya.
Tapi ini nggak berlaku buat semua model. Random forest nggak peduli sama sekali. Nerapin scaling di situ cuma nambah langkah tanpa efek.
Aku pakai dataset toko_berkah di sini, 8.400 transaksi UMKM dengan kolom umur pelanggan, total belanja, jarak antar ke toko, dan jumlah item.
Kenapa scaling penting buat sebagian model?
Ada dua alasan teknis yang bikin skala jadi masalah.
Model berbasis jarak. KNN, SVM dengan kernel RBF, dan K-Means ngitung jarak antar titik data. Rumus jarak Euclidean jumlahin selisih kuadrat tiap kolom. Kolom dengan rentang jutaan bakal nutupin kontribusi kolom dengan rentang puluhan.
Model yang dilatih pakai gradient descent. Regresi logistik, regresi ridge, dan jaringan saraf nyari bobot lewat iterasi. Kalau skala antar kolom timpang, permukaan optimasinya jadi memanjang dan proses konvergensinya lambat. Kadang malah nggak ketemu titik optimalnya dalam batas iterasi.
Berikut pengaruh nyatanya di dataset toko_berkah. Aku latih model klasifikasi pelanggan langganan pakai KNN dengan k=5.
| Perlakuan | Akurasi | F1-score |
|---|---|---|
| Tanpa scaling | 0,612 | 0,548 |
| MinMaxScaler | 0,809 | 0,776 |
| StandardScaler | 0,824 | 0,791 |
Akurasi naik 21 poin cuma dari satu langkah preprocessing. Modelnya sama persis, datanya sama persis.
Apa bedanya scaling, normalisasi, dan standardisasi?
Tiga istilah ini sering ketuker. Definisi yang dipakai di scikit-learn:
Standardisasi ngurangin rata-rata lalu bagi standar deviasi. Hasilnya rata-rata 0 dan standar deviasi 1. Nggak ada batas atas atau bawah.
Normalisasi min-max mindahin nilai ke rentang tetap, biasanya 0 sampai 1. Nilai terkecil jadi 0, terbesar jadi 1.
Normalisasi vektor (kelas Normalizer di scikit-learn) bekerja per baris, bukan per kolom. Tiap baris dibikin punya panjang vektor 1. Ini beda tujuan, biasanya buat data teks.
Yang paling sering kamu butuhin dua yang pertama.
Kapan pakai StandardScaler?
StandardScaler pilihan default buat sebagian besar kasus. Rumusnya sederhana: tiap nilai dikurangi rata-rata kolomnya, terus dibagi standar deviasi kolom itu.
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
df = pd.read_csv("toko_berkah.csv")
fitur = ["umur_pelanggan", "total_belanja", "jarak_km", "jumlah_item"]
X_train, X_test, y_train, y_test = train_test_split(
df[fitur], df["langganan"], test_size=0.2, random_state=42
)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
print(scaler.mean_)
print(scaler.scale_)
Perhatiin bedanya fit_transform di data training dan transform doang di data test. Ini bukan gaya penulisan, ini aturan.
Scaler nyimpen rata-rata dan standar deviasi dari data training di atribut mean_ dan scale_. Data test dipetakan pakai angka yang sama. Kalau kamu fit ulang di data test, informasi dari data test bocor ke proses persiapan model.
StandardScaler cocok buat kolom yang sebarannya kurang lebih simetris. Dia nggak bikin data jadi normal, cuma mindahin pusat dan skalanya.
Kapan pakai MinMaxScaler?
MinMaxScaler mindahin semua nilai ke rentang 0 sampai 1. Nilai terkecil di data training jadi 0, terbesar jadi 1, sisanya di antaranya.
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
Ini pilihan yang tepat kalau algoritma kamu butuh input di rentang tertentu. Jaringan saraf dengan fungsi aktivasi sigmoid contohnya, atau pemrosesan gambar yang nilainya harus 0 sampai 1.
Kelemahannya: MinMaxScaler sensitif banget sama outlier. Satu transaksi Rp 48 juta di antara ribuan transaksi puluhan ribu bakal narik semua nilai normal ke deket nol.
Contoh di kolom total_belanja dataset toko_berkah:
| Nilai asli | Setelah MinMax | Setelah Standard |
|---|---|---|
| Rp 15.000 | 0,000 | -0,71 |
| Rp 87.400 | 0,015 | -0,08 |
| Rp 240.000 | 0,047 | 1,25 |
| Rp 4.800.000 | 1,000 | 40,84 |
Lihat kolom tengah. Tiga nilai pertama numpuk di bawah 0,05, padahal selisihnya 16 kali lipat. Semua informasi tergencet gara-gara satu nilai ekstrem.
Yang perlu kamu perhatiin juga: nilai di data test bisa keluar dari rentang 0 sampai 1 kalau ada yang lebih besar dari nilai maksimum training. Itu wajar, jangan dipaksa dipotong.
Kapan pakai RobustScaler?
RobustScaler pakai median dan interquartile range, bukan rata-rata dan standar deviasi. Karena median nggak gampang goyah sama nilai ekstrem, hasilnya jauh lebih tahan outlier.
from sklearn.preprocessing import RobustScaler
scaler = RobustScaler(quantile_range=(25.0, 75.0))
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
Ini pilihan bagus buat data transaksi ritel Indonesia. Distribusi belanja UMKM hampir selalu miring ke kanan, dengan ekor panjang dari beberapa pembelian grosir.
Perbandingan singkat ketiganya ada di contoh visual resmi scikit-learn. Ada plot yang nunjukin bentuk sebaran setelah tiap scaler diterapin.
Model mana yang butuh scaling?
| Model | Butuh scaling? | Kenapa |
|---|---|---|
| KNN | Wajib | Ngitung jarak antar titik |
| SVM (kernel RBF) | Wajib | Kernel berbasis jarak |
| K-Means | Wajib | Ngitung jarak ke pusat klaster |
| PCA | Wajib | Nyari arah dengan varians terbesar |
| Regresi logistik | Sangat disarankan | Konvergensi gradient descent |
| Ridge dan Lasso | Wajib | Penalti dihitung dari besar koefisien |
| Jaringan saraf | Wajib | Stabilitas pelatihan |
| Regresi linear biasa | Nggak perlu | Koefisien menyesuaikan sendiri |
| Decision tree | Nggak perlu | Split berdasarkan urutan nilai |
| Random forest | Nggak perlu | Sama seperti decision tree |
| Gradient boosting, XGBoost | Nggak perlu | Sama seperti decision tree |
| Naive Bayes | Nggak perlu | Kerja per kolom secara terpisah |
Baris Ridge dan Lasso sering dilewatin. Kedua model itu ngasih penalti berdasarkan besar koefisien. Kalau skalanya beda-beda, penaltinya nggak adil dan kolom dengan angka kecil bakal kena hukuman lebih berat.
Kenapa model pohon kebal skala?
Decision tree cari titik potong terbaik di tiap kolom, misalnya "total_belanja lebih dari 150.000". Yang penting cuma urutan nilainya, bukan jaraknya.
Kalau kamu bagi semua nilai belanja dengan 1.000, titik potongnya jadi 150 dan hasil pemisahannya persis sama. Pohonnya nggak berubah sedikit pun.
Jadi kalau kamu pakai random forest atau XGBoost, lewatin aja langkah scaling. Nggak salah kalau diterapin, cuma nggak ada gunanya.
Contoh kasus: segmentasi pelanggan toko_berkah
Ini kasus di mana scaling bikin hasilnya beda total. Aku jalanin K-Means dengan 3 klaster buat segmentasi pelanggan, pakai tiga kolom: total belanja, frekuensi kunjungan per bulan, dan jarak ke toko.
Rentang aslinya timpang jauh. Belanja 15.000 sampai 4.800.000. Frekuensi 1 sampai 22. Jarak 0,3 sampai 14,7 km.
Tanpa scaling, K-Means praktis cuma ngelompokin berdasarkan belanja. Frekuensi dan jarak nggak ngaruh apa-apa soalnya angkanya kekecilan.
| Klaster | Tanpa scaling (rata-rata belanja) | Dengan StandardScaler (profil) |
|---|---|---|
| 1 | Rp 41.200 | Belanja kecil, sering datang, rumah dekat |
| 2 | Rp 186.500 | Belanja sedang, jarang datang, rumah jauh |
| 3 | Rp 1.240.000 | Belanja besar, sebulan sekali, rumah jauh |
Kolom kanan jauh lebih berguna buat pemilik toko. Klaster 1 itu pelanggan harian yang cocok dikasih program loyalitas kecil. Klaster 3 kemungkinan pembeli grosir yang perlu ditawari harga borongan.
Kolom kiri cuma bilang "ada yang belanja sedikit, sedang, dan banyak". Nggak butuh K-Means buat tau itu, MEDIAN di spreadsheet udah cukup.
Pakai Pipeline biar nggak bocor
Cara paling aman nerapin scaling adalah lewat Pipeline. Dengan pipeline, scaler otomatis di-fit ulang di tiap fold cross-validation.
from sklearn.pipeline import Pipeline
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
pipe = Pipeline([
("scaler", StandardScaler()),
("model", KNeighborsClassifier(n_neighbors=5))
])
skor = cross_val_score(pipe, X_train, y_train, cv=5, scoring="f1")
print(skor.mean().round(3))
Kalau kamu scaling manual sebelum cross-validation, tiap fold validasi udah kena pengaruh statistik dari fold lain. Skornya jadi lebih tinggi dari yang seharusnya.
Buat data yang kolomnya campur numerik dan kategorik, pakai ColumnTransformer:
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
numerik = ["umur_pelanggan", "total_belanja", "jarak_km"]
kategorik = ["kota", "metode_bayar"]
pre = ColumnTransformer([
("num", StandardScaler(), numerik),
("kat", OneHotEncoder(handle_unknown="ignore"), kategorik)
])
pipe = Pipeline([("pre", pre), ("model", KNeighborsClassifier())])
Ini juga mastiin kolom hasil one-hot nggak ikut di-scale, yang memang nggak perlu.
Kesalahan umum
Fit scaler di seluruh dataset sebelum split. Kesalahan paling sering. Rata-rata dan standar deviasi jadi mengandung informasi dari data test. Skor validasi kelihatan bagus, performa di produksi jeblok.
Scaling kolom target. Buat masalah klasifikasi, target nggak perlu di-scale sama sekali. Buat regresi, kadang berguna, tapi jangan lupa balikin hasil prediksinya pakai inverse_transform.
Scaling kolom hasil one-hot. Kolom 0/1 udah punya skala yang seragam. Nge-scale-nya bikin nilainya jadi angka desimal aneh tanpa manfaat.
Pakai MinMaxScaler di data yang punya outlier ekstrem. Cek dulu sebaran datanya. Kalau selisih antara persentil 99 dan nilai maksimum besar banget, pilih RobustScaler.
Lupa nyimpen scaler buat produksi. Model yang dilatih pakai data scaled butuh scaler yang sama waktu dipakai. Simpan scaler barengan modelnya, misalnya pakai joblib.dump().
Scaling sebelum ngisi missing value. Nilai kosong bikin perhitungan rata-rata jadi kacau. Urutan yang benar: isi missing value dulu, baru scaling.
FAQ
Apakah random forest butuh scaling fitur?
Nggak. Random forest cari titik potong berdasarkan urutan nilai di tiap kolom, jadi skala nggak berpengaruh sama sekali. Kalau kamu bagi semua nilai dengan 1.000, pohon yang terbentuk sama persis. Nerapin scaling di random forest nggak bikin salah, cuma nambah langkah tanpa efek.
Mana yang lebih baik, StandardScaler atau MinMaxScaler?
StandardScaler lebih aman buat kebanyakan kasus, apalagi kalau datanya punya outlier. MinMaxScaler dipilih kalau algoritma kamu butuh input di rentang tetap, misalnya jaringan saraf dengan aktivasi sigmoid atau data piksel gambar. Kalau ragu, mulai dari StandardScaler.
Perlu scaling untuk regresi linear biasa?
Nggak wajib. Koefisien regresi linear otomatis menyesuaikan skala tiap kolom, jadi prediksinya sama saja. Tapi kalau kamu pakai regularisasi seperti Ridge atau Lasso, scaling jadi wajib. Penaltinya dihitung dari besar koefisien, jadi kolom dengan skala berbeda bakal kena hukuman yang nggak adil.
Kapan pakai log transform daripada scaling?
Log transform buat data yang sebarannya sangat miring, misalnya nilai transaksi yang rentangnya ribuan sampai jutaan rupiah. Log bikin bentuk sebarannya lebih simetris, scaling cuma mindahin posisi dan lebarnya. Keduanya bisa dipakai bareng: log dulu, baru StandardScaler.
Gimana kalau data test punya nilai di luar rentang training?
Itu normal dan nggak perlu diperbaiki. MinMaxScaler bakal ngasih nilai di bawah 0 atau di atas 1 untuk kasus itu, StandardScaler ngasih z-score yang lebih ekstrem. Jangan potong nilainya secara paksa, soalnya itu justru ngilangin informasi bahwa data barunya memang di luar kebiasaan.
Penutup
Dua hal yang perlu kamu ingat. Scaling wajib buat model berbasis jarak dan gradient descent, nggak perlu buat model pohon. Dan selalu fit scaler di data training doang, jangan pernah di data gabungan.
Kalau kamu masih scaling manual, pindahin ke Pipeline hari ini. Satu perubahan itu ngilangin sumber kebocoran data yang paling umum.
Lanjut baca soal encoding variabel kategorik buat ngurusin kolom teks di dataset yang sama.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Artikel terkait
Pandas groupby: Agregasi Data ala Pivot di Python (2026)
groupby ngelompokin baris berdasarkan kolom, lalu ngitung ringkasan per grup kayak total atau rata-rata. Ini pivot-nya pandas.
Pandas to_excel: Ekspor DataFrame ke Excel (2026)
to_excel nyimpen DataFrame pandas jadi file Excel .xlsx. Ini cara pakainya, dari satu sheet sampai banyak sheet, plus setelan yang bikin hasilnya rapi.
Pandas read_excel: Baca File Excel di Python
pandas read_excel baca file Excel jadi DataFrame, bisa pilih sheet tertentu dan lompatin baris judul yang berantakan. Ini cara pakai plus parameter penting dengan contoh data toko.