Implementasi Feature Scaling dengan StandardScaler dan MinMaxScaler: Teori Normalisasi Data dan Praktik dengan Scikit-learn
Mengapa Skala Fitur Menentukan Kinerja Algoritma
Setiap dataset berisi fitur dengan satuan dan rentang yang berbeda. Kolom usia bisa berada di rentang 20 sampai 70, sementara kolom penghasilan bulanan bisa mencapai jutaan. Jika kedua kolom ini dimasukkan ke algoritma berbasis jarak seperti KNN, K-Means, atau SVM dengan kernel RBF, perhitungan Euclidean distance akan didominasi oleh fitur dengan rentang besar. Kontribusi fitur berrentang kecil hampir tidak berpengaruh terhadap keputusan model, dan hasilnya menjadi bias terhadap satu fitur saja.
Algoritma berbasis gradien seperti logistic regression dan neural network menghadapi masalah yang berbeda. Nilai bobot yang diperbarui oleh optimizer berbanding lurus dengan magnitudo fitur, sehingga fitur berrentang besar menggeser bobot secara tidak proporsional. Tanpa scaling, proses konvergensi menjadi lambat dan tidak stabil. Sebaliknya, algoritma berbasis tree seperti Decision Tree dan Random Forest tidak terpengaruh oleh skala, karena proses split hanya membandingkan nilai aktual dengan threshold pada satu fitur. Perbedaan inilah yang membuat feature scaling menjadi langkah preprocessing yang wajib pada banyak pipeline machine learning.
Kita bisa membuktikan dominasi fitur berrentang besar secara langsung menggunakan perhitungan jarak Euclidean sederhana pada dua titik data.
Gambar: Data yang terkompresi pada satu sumbu (kiri) menghasilkan clustering yang salah, sementara setelah z-score normalization (kanan) keempat cluster kembali terdeteksi — Sumber: [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:The_effect_of_z-score_normalization_on_k-means_clustering.svg) (CC BY-SA 4.0, Cosmia Nebula)
!pip install numpy
import numpy as np
p1 = np.array([50, 1000])
p2 = np.array([55, 5000])
def euclidean(a, b):
return np.sqrt(np.sum((a - b) ** 2))
dist_raw = euclidean(p1, p2)
all_points = np.array([p1, p2])
mean = all_points.mean(axis=0)
std = all_points.std(axis=0)
p1_scaled = (p1 - mean) / std
p2_scaled = (p2 - mean) / std
dist_scaled = euclidean(p1_scaled, p2_scaled)
print(f"Selisih fitur 1 (usia) : {p2[0] - p1[0]}")
print(f"Selisih fitur 2 (penghasilan): {p2[1] - p1[1]}")
print(f"Jarak Euclidean tanpa scaling : {dist_raw:.2f}")
print(f"Jarak Euclidean setelah scaling : {dist_scaled:.2f}")Output:
Selisih fitur 1 (usia) : 5
Selisih fitur 2 (penghasilan): 4000
Jarak Euclidean tanpa scaling : 4000.00
Jarak Euclidean setelah scaling : 2.83Sebelum scaling, jarak antara dua titik hampir seluruhnya ditentukan oleh fitur penghasilan dengan selisih 4000, sementara selisih usia hanya 5. Setelah kedua fitur distandardisasi dengan rumus z-score, kontribusi keduanya menjadi sebanding dan jarak turun menjadi 2.83. Angka ini membuktikan bahwa tanpa scaling, fitur dengan satuan besar mendominasi perhitungan dan membuat fitur lain kehilangan pengaruh.
Mekanisme StandardScaler dan MinMaxScaler
StandardScaler menggunakan formula z = (x - mean) / std. Transformasi ini mengurangi setiap nilai dengan rata-rata fitur, lalu membaginya dengan standar deviasi. Hasilnya adalah distribusi dengan mean 0 dan standar deviasi 1, tanpa batas atas atau bawah yang tetap. Pendekatan ini ideal untuk data yang mendekati distribusi normal, tetapi tetap bekerja wajar untuk bentuk distribusi lain selama tidak ada outlier ekstrem. Nilai negatif yang dihasilkan bukan masalah, karena sebagian besar model berbasis gradien bekerja lebih baik dengan input yang berpusat di nol.
MinMaxScaler menggunakan formula x_scaled = (x - min) / (max - min). Setiap nilai dipetakan ke rentang [0, 1] berdasarkan nilai minimum dan maksimum fitur. Teknik ini cocok untuk data dengan batas atas dan bawah yang diketahui, seperti skor tes atau intensitas piksel pada citra. Kelemahannya, nilai min dan max sangat rentan terhadap outlier. Satu nilai ekstrem bisa memperlebar penyebut pada formula, sehingga sebagian besar data terkompresi ke rentang yang sangat sempit. StandardScaler lebih tahan terhadap masalah ini, karena rata-rata dan standar deviasi tidak mudah bergeser oleh satu nilai ekstrem.
Data Science with Python
Master the art of data analysis, visualization, and predictive modeling.
Keputusan memilih teknik scaling bergantung pada tiga hal: bentuk distribusi, keberadaan outlier, dan kebutuhan rentang tetap. Jika data terdistribusi normal tanpa outlier, StandardScaler adalah pilihan default yang aman. Jika kita membutuhkan output dalam rentang terikat seperti [0, 1], misalnya untuk input neural network, MinMaxScaler lebih sesuai.
Praktik Feature Scaling dengan Scikit-learn
Aturan paling dasar dalam feature scaling adalah memisahkan proses fit dan transform. fit_transform hanya boleh dipanggil pada training set untuk menghitung parameter scaling, yaitu mean dan std untuk StandardScaler, atau min dan max untuk MinMaxScaler. Test set kemudian diubah dengan transform saja, memakai parameter yang sudah dihitung dari data latih. Alur ini menjaga agar informasi dari test set tidak bocor ke proses training. Scikit-learn menyediakan kedua scaler tersebut di modul sklearn.preprocessing, siap dipakai dalam beberapa baris kode.
Mari kita terapkan kedua scaler pada dataset breast cancer bawaan Scikit-learn dan verifikasi hasilnya melalui statistik ringkas.
!pip install scikit-learn numpy pandas
from sklearn.datasets import load_breast_cancer
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.model_selection import train_test_split
import pandas as pd
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print("=== Statistik fitur 'mean radius' sebelum scaling ===")
print(f"mean: {X_train['mean radius'].mean():.4f}")
print(f"std : {X_train['mean radius'].std():.4f}")
print(f"min : {X_train['mean radius'].min():.4f}")
print(f"max : {X_train['mean radius'].max():.4f}")
scaler_std = StandardScaler()
X_train_std = scaler_std.fit_transform(X_train)
scaler_mm = MinMaxScaler()
X_train_mm = scaler_mm.fit_transform(X_train)
print("\n=== Setelah StandardScaler (fitur pertama) ===")
print(f"mean: {X_train_std[:, 0].mean():.6f}")
print(f"std : {X_train_std[:, 0].std():.6f}")
print("\n=== Setelah MinMaxScaler (fitur pertama) ===")
print(f"min: {X_train_mm[:, 0].min():.6f}")
print(f"max: {X_train_mm[:, 0].max():.6f}")
print(f"\nBentuk array hasil transformasi: {X_train_std.shape}")Output:
=== Statistik fitur 'mean radius' sebelum scaling ===
mean: 14.1176
std : 3.5358
min : 7.6910
max : 28.1100
=== Setelah StandardScaler (fitur pertama) ===
mean: -0.000000
std : 1.000000
=== Setelah MinMaxScaler (fitur pertama) ===
min: 0.000000
max: 1.000000
Bentuk array hasil transformasi: (455, 30)Setelah StandardScaler, mean fitur pertama menjadi 0 dan standar deviasinya menjadi 1. Setelah MinMaxScaler, nilai minimum dan maksimumnya berada tepat di 0 dan 1. Kedua hasil ini sesuai dengan formula masing-masing. Kita juga melihat bentuk array hasil transformasi tetap (455, 30), artinya scaling tidak mengubah jumlah baris maupun kolom, hanya skala nilainya.
Menghindari Data Leakage dengan Pipeline dan ColumnTransformer
Kesalahan yang paling sering terjadi adalah memanggil fit_transform pada seluruh dataset sebelum proses split. Parameter scaling lalu dihitung menggunakan informasi dari test set, yang merupakan bentuk data leakage. Model yang dievaluasi pada test set tersebut akan tampak lebih baik dari sebenarnya, karena sebagian karakteristik data uji sudah diketahui selama training. Ketika model di-deploy ke data baru, performa aktualnya bisa jauh lebih buruk dari hasil evaluasi.
Untuk mencegah masalah ini, kita bisa membungkus scaling dan model ke dalam satu Pipeline. Pipeline memastikan fit pada training set hanya menghitung parameter scaling, dan transform pada test set otomatis memakai parameter tersebut saat predict dipanggil. Dengan cara ini, seluruh proses preprocessing dan modeling menjadi satu alur yang konsisten dan tidak mungkin bocor.
!pip install scikit-learn pandas
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.compose import ColumnTransformer
import pandas as pd
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
pipeline = Pipeline([
('scaler', StandardScaler()),
('model', LogisticRegression(max_iter=1000))
])
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
print(f"Akurasi pipeline scaling + logistic regression: {accuracy_score(y_test, y_pred):.4f}")
numerical_cols = X.columns[:10].tolist()
ct = ColumnTransformer([
('num', StandardScaler(), numerical_cols)
], remainder='passthrough')
X_train_ct = ct.fit_transform(X_train)
print(f"\nKolom yang di-scale: {numerical_cols}")
print(f"Kolom yang dibiarkan apa adanya: {list(X.columns[10:])}")
print(f"Bentuk hasil ColumnTransformer: {X_train_ct.shape}")Output:
Akurasi pipeline scaling + logistic regression: 0.9737
Kolom yang di-scale: ['mean radius', 'mean texture', 'mean perimeter', 'mean area', 'mean smoothness', 'mean compactness', 'mean concavity', 'mean concave points', 'mean symmetry', 'mean fractal dimension']
Kolom yang dibiarkan apa adanya: ['radius error', 'texture error', 'perimeter error', 'area error', 'smoothness error', 'compactness error', 'concavity error', 'concave points error', 'symmetry error', 'fractal dimension error', 'worst radius', 'worst texture', 'worst perimeter', 'worst area', 'worst smoothness', 'worst compactness', 'worst concavity', 'worst concave points', 'worst symmetry', 'worst fractal dimension']
Bentuk hasil ColumnTransformer: (455, 30)Pipeline di atas menggabungkan StandardScaler dan LogisticRegression dalam satu objek. Saat fit dipanggil, parameter scaling dihitung dari training set, lalu model dilatih pada data yang sudah di-scale. Saat predict dipanggil, test set diubah memakai parameter yang sama sebelum masuk ke model, sehingga tidak ada kebocoran informasi. ColumnTransformer pada contoh ini menangani dataset campuran dengan menskalakan sepuluh kolom numerik dan mempertahankan dua puluh kolom lain melalui remainder='passthrough'. Bentuk hasil akhir tetap 30 kolom, membuktikan bahwa transformasi berjalan tanpa menghilangkan informasi.
Panduan Memilih Teknik Scaling untuk Dataset Nyata
Ringkasan keputusan ini bisa kita pegang ketika menghadapi dataset nyata. StandardScaler adalah pilihan utama untuk data yang mendekati distribusi normal dan bebas outlier ekstrem. MinMaxScaler lebih tepat ketika rentang output harus terikat, seperti input model yang sensitif terhadap skala 0 sampai 1. Apabila dataset dipenuhi outlier, RobustScaler menjadi opsi yang lebih aman karena berbasis median dan interquartile range. Ketiga pilihan ini tersedia langsung di modul sklearn.preprocessing, sehingga mencobanya secara bergantian sangat mudah.
Satu aturan yang sering terlewat: scaling diterapkan pada fitur input, bukan pada target regresi. Target yang diprediksi sebaiknya dibiarkan dalam skala aslinya agar hasil prediksi bisa langsung diinterpretasi. Jika kita tetap ingin menormalkan target, transformasi invers harus dilakukan pada setiap prediksi, yang menambah kompleksitas tanpa manfaat yang jelas.
Setelah scaling, kita perlu memverifikasi hasilnya. Cek statistik ringkas seperti mean, standar deviasi, min, dan max untuk memastikan transformasi sesuai harapan. Histogram sederhana juga membantu melihat bentuk distribusi setelah scaling. Kebiasaan memverifikasi ini mencegah kesalahan tersembunyi yang bisa memengaruhi kualitas model.
Feature scaling adalah langkah preprocessing yang menentukan kualitas model machine learning. Jika Anda ingin mempelajari preprocessing dan pipeline modeling secara menyeluruh, bergabunglah dengan bootcamp Data Science & Machine Learning di Rumah Coding dan belajar langsung dari praktisi industri melalui proyek nyata.
Kursus Terkait
Data Science with Python
Master the art of data analysis, visualization, and predictive modeling.
E-commerce Sales Dashboard
- Data Cleaning Pipeline
- Interactive Charts
- Sales Forecasting Model
Deep Learning Bootcamp
A beginner-friendly, highly interactive bootcamp designed to take you from foundational concepts to deploying real-world Artificial Intelligence applications. Through a completely project-based approach, you will master the core of Deep Learning, Artificial Neural Networks, and Computer Vision using Python and TensorFlow, ultimately building a professional-grade AI web application for your portfolio.
GreenGuard: Intelligent Plant Disease Diagnosis Web App
- Interactive Image Upload UI: A clean, user-friendly interface built with Streamlit that supports drag-and-drop image uploads directly from a computer or mobile phone.
- Real-Time AI Inference: Utilizes a lightweight, optimized CNN model (like MobileNetV2) to process the image and return a diagnosis in seconds without heavy server load.
- Confidence Scoring Dashboard: Visually displays the model's prediction probability (e.g., "95% confident this is Tomato Late Blight") using interactive progress bars or charts.
LLM Bootcamp
This project-based bootcamp is designed for beginners to dive practically into the world of Large Language Models (LLMs). Through hands-on building, you will learn how to interact with top-tier AI APIs, master prompt engineering, orchestrate complex workflows using LangChain, and implement Retrieval-Augmented Generation (RAG) to query your own documents. By the end of this course, you will have the skills to build, test, and deploy a fully functional, custom AI web application.
Domain-Specific AI Knowledge Assistant
- Dynamic Document Processing: A sidebar interface allowing users to upload new PDF or TXT files, which the app automatically chunks, embeds, and stores in the vector database.
- Context-Aware Chat UI: A modern chat interface built with Streamlit that maintains conversation history, allowing users to ask follow-up questions naturally.
- Strict Guardrails (Anti-Hallucination): System instructions designed so the AI politely declines to answer questions that fall outside the context of the uploaded documents.