scikit-learn menyeragamkan seluruh pekerjaan pemodelan menjadi satu pola yang
tetap, yaitu bagi data, pilih baseline, latih, dan nilai, sehingga bertukar
model hanyalah bertukar satu baris. Topik ini mengeksekusi pola tersebut pada
dataset latihan untuk klasifikasi kualitas udara, dari train_test_split
berbiji tetap sampai perbandingan akurasi terhadap baseline. Setelah
membacanya, pola empat langkah ini berlaku pada model apa pun yang ditemui
kemudian.
Empat langkah yang tetap#
Langkah pertama adalah memisahkan data uji (train-test split) sebelum
menyentuh model, karena penilaian hanya sah atas data yang belum pernah
dilihat model. Argumen random_state mengunci pembagiannya agar hasil dapat
direproduksi, dan stratify menjaga proporsi kelas tetap sama pada kedua
sisi bila kelasnya timpang.
Langkah kedua adalah melatih baseline terlebih dahulu, sebab baseline adalah
garis dasar yang wajib dikalahkan sebagaimana ditegaskan pada topik sebelumnya.
Langkah ketiga adalah fit pada data latih, dan langkah keempat adalah
evaluasi pada data uji dengan metrik yang sudah dipilih sesuai biaya
keputusannya.
Keseragaman antarmuka scikit-learn membuat empat langkah ini tidak berubah
antarmodel, yaitu setiap model memakai fit dan predict dengan bentuk yang
sama, dan dokumentasi resminya menyebut konvensi ini sebagai dasar seluruh
pustaka.
Satu skrip penuh dari data sampai keputusan#
Skrip berikut menjalankan seluruh pola pada masalah klasifikasi, yaitu
memprediksi kategori kualitas udara dari suhu, kelembapan, dan identitas
stasiun yang disandikan sebagai dummy melalui get_dummies. Argumen
max_iter=1000 pada regresi logistik memberi ruang konvergensi yang cukup
agar tidak ada peringatan yang muncul.
"""Alur kerja scikit-learn: split, baseline, fit, evaluasi."""
import pandas as pd
from sklearn.dummy import DummyClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
data = pd.read_csv(
"ukuran_udara.csv",
na_values=["kosong", "-999.0"],
dtype={"pm25": "string", "kelembapan": "string", "kualitas": "string"},
)
data["pm25"] = data["pm25"].astype("float")
data["kelembapan"] = data["kelembapan"].str.replace(",", ".", regex=False).astype("float")
data["stasiun"] = (
data["stasiun"].str.strip().str.replace(r"\s+", " ", regex=True).str.title()
)
data["kualitas"] = data["kualitas"].str.title()
sah = data[data["pm25"] < 500].dropna(
subset=["pm25", "suhu_c", "kelembapan", "kualitas"]
)
X = pd.get_dummies(sah[["stasiun", "suhu_c", "kelembapan"]], columns=["stasiun"])
y = sah["kualitas"]
X_latih, X_uji, y_latih, y_uji = train_test_split(
X, y, test_size=0.25, random_state=42, stratify=y
)
print("latih:", len(X_latih), "| uji:", len(X_uji))
baseline = DummyClassifier(strategy="most_frequent").fit(X_latih, y_latih)
model = LogisticRegression(max_iter=1000).fit(X_latih, y_latih)
print("akurasi baseline :", round(accuracy_score(y_uji, baseline.predict(X_uji)), 3))
print("akurasi logreg :", round(accuracy_score(y_uji, model.predict(X_uji)), 3))latih: 36 | uji: 13
akurasi baseline : 0.615
akurasi logreg : 0.692Keluarannya menahan kesimpulan yang berlebihan, yaitu akurasi model 0.692 memang di atas baseline 0.615, tetapi selisihnya tipis pada 13 baris uji. Pengujian ulang dengan data yang lebih banyak adalah tindak lanjut yang sah, dan klaim yang dilaporkan berbunyi “sedikit lebih baik dari baseline pada data yang sangat kecil”, bukan “model berhasil”.
Struktur yang sama pada model lain hanya mengganti satu baris, misalnya
DecisionTreeClassifier menggantikan LogisticRegression tanpa menyentuh
langkah lain, dan keseragaman inilah yang membuat eksperimen bertahap murah.
Split yang jujur dan penyebaran kelas#
Pembagian acak menimbulkan dua pertanyaan yang wajib dijawab, yaitu berapa
porsi ujinya dan apakah kelasnya seimbang. Porsi yang lazim untuk data
sedang adalah seperempat hingga sepertiga, sedangkan data yang sangat kecil
membuat data uji kurang teliti, dan cross_val_score menjadi alternatif
yang memanfaatkan seluruh data dengan beberapa putaran pembagian.
stratify=y menjaga proporsi kelas pada kedua sisi, dan tanpa itu kelas
langka dapat nyaris hilang dari data uji secara kebetulan. Pada dataset
latihan ini kelasnya berimbang, tetapi kebiasaan stratify dibangun sejak
awal karena sebagian besar data nyata tidak seimbang.
Penilaian juga dilakukan sekali pada akhir, bukan berulang-ulang pada data uji yang sama. Setiap pemeriksaan pada data uji adalah kesempatan menyetel secara halus terhadapnya, dan data uji yang dipakai berkali-kali perlahan berubah menjadi data latih kedua, dengan penangkal validasi silang pada pemilihan modelnya.
Kesalahan umum#
Kesalahan pertama adalah menilai model pada data latihnya sendiri. Akurasi latih yang tinggi menyatakan daya hafalan, bukan daya prediksi, dan hanya data uji yang belum dilihat yang boleh dinilai.
Kesalahan kedua adalah melupakan random_state sehingga setiap jalanan
menghasilkan angka berbeda. Hasil yang berubah-ubah menutup peluang
pembandingan antar model, sedangkan biji yang dicatat membuat setiap
perbandingan dapat diulang.
Kesalahan ketiga adalah melompati baseline karena terasa sepele. Tanpa baseline, akurasi 0.692 tidak bermakna apa pun, dan baseline paling murah justru yang menegaskan maknanya.
Ringkasan#
- Empat langkah tetap, yaitu split berbiji tetap, baseline, fit, dan evaluasi pada data uji, berlaku untuk setiap model scikit-learn.
stratifymenjaga proporsi kelas, dan data uji hanya dinilai sekali pada akhir.- Antarmuka
fitdanpredictyang seragam membuat bertukar model menjadi satu baris, sehingga eksperimen bertahap murah. - Akurasi model latihan hanya tipis di atas baseline, dan klaim yang sah menyebut batas ukuran datanya.
Referensi#
- Getting Started — scikit-learn documentation — tutorial resmi pola fit dan predict yang dipakai topik ini.
- sklearn.model_selection.train_test_split — scikit-learn documentation — rujukan resmi pembagian data beserta argumen stratify dan random_state.