Referensi cepat scikit-learn untuk machine learning klasik. Estimator API, pipeline, preprocessing, model selection, evaluasi, dan deployment model Python.
Scikit-learn dipakai untuk machine learning berbasis data tabular, teks, dan vektor berdimensi tetap. Library ini kuat untuk baseline, klasifikasi, regresi, clustering, seleksi fitur, serta evaluasi eksperimen. Ia bukan pilihan untuk melatih neural network besar. Untuk itu, pakai PyTorch atau TensorFlow.
Dokumentasi stable saat cheat sheet ini ditulis memakai scikit-learn 1.9.1. Instal library utama seperti ini.
python -m pip install -U scikit-learn pandas numpy joblibHampir semua objek scikit-learn mengikuti kontrak estimator. fit() mempelajari parameter dari data training. transform() mengubah input. predict() menghasilkan prediksi. fit_transform() cocok untuk transformer karena menjalankan dua langkah itu sekaligus.
import sklearn
from sklearn.preprocessing import StandardScaler
print(sklearn.__version__)
X_train = [[170, 65], [180, 80], [160, 55]]
scaler = StandardScaler()
scaler.fit(X_train) # Pelajari mean dan standar deviasi dari train.
X_train_scaled = scaler.transform(X_train)
print(scaler.mean_)
print(X_train_scaled)Jangan memanggil fit() pada data test. Transformer yang belajar dari seluruh dataset dapat membocorkan informasi test ke proses training. Pipeline ada untuk mencegah kesalahan yang kelihatannya kecil ini.
X berarti fitur dan biasanya berbentuk tabel dua dimensi: (n_samples, n_features). y berarti target dan umumnya satu dimensi. Pandas DataFrame enak dipakai karena nama kolom tetap terbawa sampai ColumnTransformer.
import pandas as pd
X = pd.DataFrame(
{
"umur": [21, 35, 29, 42],
"pendapatan": [4_000_000, 8_000_000, 6_500_000, 12_000_000],
"kota": ["Bandung", "Jakarta", "Bandung", "Surabaya"],
}
)
y = pd.Series([0, 1, 0, 1], name="berlangganan")
print(X.shape) # (4, 3)
print(y.shape) # (4,)Kolom target jangan ikut masuk ke X. Ini bentuk data leakage paling jelas, tapi kolom seperti status_pesanan_akhir, tanggal_pembatalan, atau fitur yang baru tersedia sesudah keputusan bisnis sering lebih licik.
Simpan test set untuk pemeriksaan akhir. Pakai stratify=y saat klasifikasi agar proporsi kelas di train dan test tidak berubah jauh. random_state bikin pembagian dapat diulang.
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,
stratify=y,
)Sebelum mencoba model rumit, bandingkan dengan baseline. DummyClassifier yang memilih kelas paling sering membantu kamu tahu apakah model sungguhan benar-benar belajar.
from sklearn.dummy import DummyClassifier
from sklearn.metrics import accuracy_score
baseline = DummyClassifier(strategy="most_frequent")
baseline.fit(X_train, y_train)
print(accuracy_score(y_test, baseline.predict(X_test)))Untuk regresi, gunakan DummyRegressor(strategy="mean") atau strategy="median". Nilai baseline yang susah dikalahkan biasanya memberi sinyal bahwa fitur belum cukup informatif, target berisik, atau metrik yang dipilih tidak cocok.
Data produksi jarang cuma berisi angka bersih. Kamu biasanya perlu mengisi nilai kosong, menormalkan angka, lalu mengodekan kategori. ColumnTransformer menerapkan transformer berbeda ke grup kolom berbeda dan menggabungkan hasilnya. Pipeline menyatukan preprocessing dan estimator menjadi satu objek yang dapat di-cross-validation.
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
X = pd.DataFrame(
{
"umur": [21, None, 29, 42, 31, 26],
"pendapatan": [4.0, 8.0, None, 12.0, 7.0, 5.5],
"kota": ["Bandung", "Jakarta", "Bandung", "Surabaya", "Jakarta", None],
"paket": ["gratis", "pro", "gratis", "pro", "pro", "gratis"],
}
)
y = [0, 1, 0, 1, 1, 0]
numeric_features = ["umur", "pendapatan"]
categorical_features = ["kota", "paket"]
numeric_pipeline = Pipeline(
steps=[
("imputer", SimpleImputer(strategy="median")),
("scaler", StandardScaler()),
]
)
categorical_pipeline = Pipeline(
steps=[
("imputer", SimpleImputer(strategy="most_frequent")),
(
"encoder",
OneHotEncoder(handle_unknown="ignore", sparse_output=False),
),
]
)
preprocessor = ColumnTransformer(
transformers=[
("numeric", numeric_pipeline, numeric_features),
("categorical", categorical_pipeline, categorical_features),
],
remainder="drop",
)
model = Pipeline(
steps=[
("preprocessor", preprocessor),
("classifier", LogisticRegression(max_iter=1_000)),
]
)
model.fit(X, y)
print(model.predict_proba(X.iloc[[0]]))OneHotEncoder(handle_unknown="ignore") penting saat kategori baru muncul pada inference. Tanpa opsi itu, kategori seperti kota baru bisa memicu error. sparse_output=False membuat output NumPy dense agar contoh mudah dibaca. Untuk kategori banyak atau data besar, biarkan nilai default sparse_output=True dan pilih estimator yang mendukung sparse matrix.
remainder="drop" adalah default. Kolom yang tidak disebut akan dibuang. Ganti menjadi "passthrough" kalau kamu sengaja ingin meneruskan kolom lain apa adanya, tetapi cek lagi urutan dan tipe data kolomnya.
Gunakan dua underscore untuk masuk ke estimator di dalam pipeline. Nama sebelum __ harus sama dengan nama langkah yang kamu beri.
model.set_params(
classifier__C=0.5,
preprocessor__numeric__imputer__strategy="mean",
)Akses langkah yang sudah fit lewat named_steps.
fitted_preprocessor = model.named_steps["preprocessor"]
print(fitted_preprocessor.get_feature_names_out())Nama fitur hasil sering berbentuk numeric__umur atau categorical__kota_Bandung. Ini berguna ketika kamu perlu melacak koefisien atau importance ke kolom asal.
Pilihan transformer bergantung pada bentuk data dan estimator setelahnya. Model berbasis pohon umumnya tidak perlu scaling, sedangkan Logistic Regression, SVM, KNN, PCA, dan model dengan regularisasi cukup sensitif terhadap skala.
| Kondisi data | Transformer | Catatan |
|---|---|---|
| Angka dengan skala berbeda | StandardScaler | Mean nol dan standar deviasi satu. Cocok untuk model linear dan SVM. |
| Angka dengan outlier berat | RobustScaler | Menggunakan median dan IQR. |
| Rentang tetap | MinMaxScaler | Memetakan nilai train ke rentang yang kamu tentukan. Data baru bisa keluar dari rentang itu. |
| Nilai kosong angka | SimpleImputer | Mulai dari median bila distribusi miring. |
| Nilai kosong kategori | SimpleImputer | Gunakan most_frequent atau constant. |
| Kategori nominal | OneHotEncoder | Jangan pakai OrdinalEncoder untuk kategori tanpa urutan. |
| Kategori berurutan | OrdinalEncoder | Tentukan urutan kategori secara eksplisit bila urutannya bermakna. |
Contoh transformasi log untuk fitur nonnegatif dengan distribusi miring. np.log1p aman untuk nilai nol karena menghitung log(1 + x).
import numpy as np
from sklearn.preprocessing import FunctionTransformer
log_transformer = FunctionTransformer(np.log1p, feature_names_out="one-to-one")
X_pengeluaran = np.array([[0.0], [100_000.0], [5_000_000.0]])
print(log_transformer.fit_transform(X_pengeluaran))Jangan menerapkan log ke nilai negatif tanpa aturan yang jelas. Kalau data punya angka negatif, pahami dulu arti kolom itu. Menggeser seluruh nilai dengan konstanta hanya agar fungsi tidak error dapat mengubah makna fitur.
Pilih model dari karakter data, bukan dari tren. Untuk data tabular kecil sampai menengah, mulai dari Logistic Regression atau Random Forest. Lalu bandingkan dengan gradient boosting.
from sklearn.ensemble import HistGradientBoostingClassifier, RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
linear_model = LogisticRegression(max_iter=1_000, class_weight="balanced")
forest_model = RandomForestClassifier(
n_estimators=400,
min_samples_leaf=3,
random_state=42,
n_jobs=-1,
)
boosting_model = HistGradientBoostingClassifier(
learning_rate=0.08,
max_leaf_nodes=31,
random_state=42,
)
svm_model = SVC(C=1.0, kernel="rbf", probability=True, random_state=42)class_weight="balanced" dapat membantu saat kelas minoritas jarang, tetapi bukan pengganti evaluasi yang benar. SVC(probability=True) menambah proses kalibrasi internal dan membuat training lebih lambat. Aktifkan hanya bila kamu memang membutuhkan predict_proba().
from sklearn.ensemble import HistGradientBoostingRegressor, RandomForestRegressor
from sklearn.linear_model import Ridge
ridge = Ridge(alpha=1.0)
forest = RandomForestRegressor(
n_estimators=400,
min_samples_leaf=3,
random_state=42,
n_jobs=-1,
)
boosting = HistGradientBoostingRegressor(
learning_rate=0.08,
max_leaf_nodes=31,
random_state=42,
)Ridge cocok sebagai baseline regularized linear. alpha lebih besar memberi regularisasi lebih kuat. Model pohon menangkap hubungan nonlinier dan interaksi tanpa kamu menulis rumus interaksi satu per satu, tetapi masih perlu validasi ketat.
Satu train-test split dapat kebetulan menguntungkan atau merugikan model. cross_validate() menguji model di beberapa fold dan memberi beberapa metrik dalam satu pemanggilan.
from sklearn.model_selection import StratifiedKFold, cross_validate
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_validate(
model,
X,
y,
cv=cv,
scoring={"accuracy": "accuracy", "f1": "f1"},
return_train_score=False,
)
print(scores["test_accuracy"].mean())
print(scores["test_f1"].mean())Untuk klasifikasi multiclass, pilih f1_macro, f1_weighted, atau metrik lain yang sesuai. Jangan memakai string "f1" untuk multiclass biasa karena default itu mengasumsikan target biner.
GridSearchCV mencoba setiap kombinasi. Gunakan ruang parameter kecil yang masuk akal. Pencarian besar dengan data sedikit gampang memilih konfigurasi yang hanya menang di fold tertentu.
from sklearn.model_selection import GridSearchCV
search = GridSearchCV(
estimator=model,
param_grid={
"classifier__C": [0.1, 1.0, 10.0],
"classifier__class_weight": [None, "balanced"],
},
scoring="f1",
cv=cv,
n_jobs=-1,
refit=True,
)
search.fit(X, y)
print(search.best_params_)
print(search.best_score_)
best_model = search.best_estimator_RandomizedSearchCV lebih cocok bila ruang parameter luas. Tentukan n_iter, random_state, serta distribusi parameter dari scipy.stats. Semua preprocessing harus berada di dalam estimator yang kamu kirim ke search. Jika scaling dikerjakan sebelum CV, statistik tiap fold tercampur.
Metrik harus mengikuti biaya kesalahan. Accuracy bisa menipu pada kelas timpang. Jika 99 persen transaksi valid, model yang selalu mengatakan valid mendapat accuracy 99 persen dan tetap gagal mendeteksi fraud.
from sklearn.metrics import (
ConfusionMatrixDisplay,
classification_report,
precision_recall_curve,
roc_auc_score,
)
best_model.fit(X_train, y_train)
y_pred = best_model.predict(X_test)
y_prob = best_model.predict_proba(X_test)[:, 1]
print(classification_report(y_test, y_pred, digits=3))
print("ROC AUC:", roc_auc_score(y_test, y_prob))
ConfusionMatrixDisplay.from_predictions(y_test, y_pred)Precision menjawab: dari prediksi positif, berapa yang benar? Recall menjawab: dari kasus positif nyata, berapa yang tertangkap? F1 menggabungkan keduanya. Untuk probabilitas, lihat ROC AUC dan terutama precision-recall curve bila kelas positif langka.
Threshold 0.5 bukan hukum. Pilih threshold berdasarkan biaya bisnis, lalu simpan keputusan itu bersama model.
import numpy as np
from sklearn.metrics import precision_score, recall_score
threshold = 0.35
y_pred_custom = (y_prob >= threshold).astype(int)
print("precision:", precision_score(y_test, y_pred_custom))
print("recall:", recall_score(y_test, y_pred_custom))Untuk regresi, pakai MAE bila kamu ingin rata-rata kesalahan absolut yang mudah dibaca dalam satuan target. RMSE lebih menghukum error besar. r2_score bagus sebagai pembanding terhadap baseline mean, tapi jangan dibaca sebagai persentase akurasi.
from sklearn.metrics import mean_absolute_error, root_mean_squared_error, r2_score
# y_true dan y_pred harus berasal dari model regresi yang sama.
print(mean_absolute_error(y_true, y_pred))
print(root_mean_squared_error(y_true, y_pred))
print(r2_score(y_true, y_pred))VarianceThreshold menghapus fitur dengan variasi terlalu kecil. Ia tidak tahu apakah fitur berguna terhadap target. Pakai sebagai filter awal, terutama pada matriks lebar.
from sklearn.feature_selection import SelectKBest, VarianceThreshold, f_classif
from sklearn.pipeline import make_pipeline
selector = make_pipeline(
VarianceThreshold(),
SelectKBest(score_func=f_classif, k=20),
)
X_selected = selector.fit_transform(X_numeric_train, y_train)Jalankan seleksi fitur di dalam pipeline dan CV. Memilih fitur pada seluruh dataset sebelum CV juga leakage, walau kamu tidak memakai kolom target secara langsung.
Untuk model linear, cek koefisien setelah preprocessing. Untuk model apa pun, permutation importance mengukur dampak ketika satu kolom diacak pada data evaluasi.
from sklearn.inspection import permutation_importance
result = permutation_importance(
best_model,
X_test,
y_test,
scoring="f1",
n_repeats=20,
random_state=42,
n_jobs=-1,
)
importance = pd.Series(result.importances_mean, index=X_test.columns)
print(importance.sort_values(ascending=False))Nilai importance bukan bukti sebab-akibat. Fitur yang sangat berkorelasi bisa membagi importance dan terlihat lemah satu per satu. Pakai hasil ini untuk debugging dan diskusi domain, bukan sebagai alasan tunggal menghapus kolom.
Simpan pipeline utuh, bukan hanya estimator akhirnya. Pipeline menyimpan imputer, encoder, scaler, dan model dengan urutan transformasi yang sama saat inference.
import joblib
joblib.dump(best_model, "model_pelanggan.joblib")
loaded_model = joblib.load("model_pelanggan.joblib")
print(loaded_model.predict(X_test.head(2)))Jangan memuat file joblib dari sumber yang tidak tepercaya. joblib.load() memakai mekanisme pickle Python dan bisa mengeksekusi kode berbahaya saat deserialisasi.
Clustering mengelompokkan data tanpa target. KMeans adalah pilihan awal yang cepat. Tentukan jumlah cluster lewat metode siku, silhouette, atau pengetahuan domain. Hasil clustering tidak punya label benar, jadi evaluasinya lewat metrik struktur seperti silhouette_score.
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
kmeans = KMeans(n_clusters=4, n_init=10, random_state=42)
kmeans.fit(X_scaled)
labels = kmeans.labels_
centers = kmeans.cluster_centers_
print("silhouette:", silhouette_score(X_scaled, labels))Skala fitur sebelum clustering. Jarak Euclidean yang dipakai KMeans dominan terhadap fitur berjangkauan besar. Kalau distribusi cluster bukan bulat, pertimbangkan DBSCAN atau AgglomerativeClustering, tetapi keduanya punya asumsi sendiri.
PCA mengurangi dimensi dan membuang variansi kecil. Ia berguna untuk visualisasi, kompresi, dan mempercepat model. Komponen yang dihasilkan adalah kombinasi linear fitur asal.
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_reduced = pca.fit_transform(X_scaled)
print("explained variance ratio:", pca.explained_variance_ratio_)
print("total variance kept:", pca.explained_variance_ratio_.sum())Untuk data kategori yang telah di-one-hot, dimensinya bisa sangat lebar. TruncatedSVD bekerja pada sparse matrix dan lebih hemat memori daripada PCA untuk kasus itu. Cek apakah estimator kamu memakai kernel atau metrik yang sensitif terhadap skala sebelum memutuskan PCA.
Pipeline.StratifiedKFold untuk klasifikasi, GroupKFold bila satu pengguna muncul berulang, TimeSeriesSplit untuk urutan waktu.| Istilah | Arti praktis |
|---|---|
| Estimator | Objek scikit-learn yang belajar melalui fit(). Classifier, regressor, dan transformer semuanya estimator. |
| Transformer | Estimator yang mengubah X lewat transform(), misalnya StandardScaler. |
| Predictor | Estimator yang menghasilkan prediksi, misalnya LogisticRegression. |
| Feature | Kolom input yang dipakai model untuk membuat prediksi. |
| Target | Nilai yang ingin diprediksi, biasanya disimpan di y. |
| Pipeline | Rangkaian transformer dan estimator akhir yang diperlakukan sebagai satu estimator. |
| Data leakage | Informasi dari test, masa depan, atau outcome masuk ke training sehingga skor tampak terlalu bagus. |
| Cross-validation | Evaluasi berulang pada beberapa pembagian data training. |
| Hyperparameter | Konfigurasi sebelum training, misalnya C, max_depth, atau n_estimators. |
| Overfitting | Model terlalu cocok pada training dan gagal bekerja pada data baru. |
| Sparse matrix | Representasi hemat memori untuk matriks yang mayoritas nilainya nol, umum setelah one-hot encoding. |
Login atau daftar akun gratis untuk membaca cheat sheet ini.