Classifier Pertama

Melatih dan menguji KNeighborsClassifier pada dataset iris secara end-to-end.

Daftar isi

Topik ini memandu pembuatan model klasifikasi pertama secara menyeluruh, mulai dari memuat data iris, memecah data, melatih KNeighborsClassifier, hingga mengukur ketepatan prediksi (accuracy) dan mencoba model pada sampel yang belum pernah terlihat. Setiap langkah dijelaskan perannya, dan keluaran yang ditampilkan adalah keluaran asli dari program yang dijalankan. Pola lima langkah yang digunakan di sini berulang untuk hampir semua model scikit-learn, sehingga program ini sekaligus menjadi pola dasar yang dapat digunakan ulang untuk model lain.

Alur lengkap program pertama#

Program pertama menyatukan lima langkah dasar machine learning, yakni pendekatan yang membangun model dari data dan bukan dari aturan yang ditulis manual. Kelima langkahnya berurutan, yaitu memuat data, memecah data, melatih model, memprediksi, dan mengukur hasilnya. Data yang digunakan adalah dataset iris bawaan scikit-learn sehingga tidak perlu mengunduh apa pun.

Model yang digunakan adalah KNeighborsClassifier dengan n_neighbors=3. Kelas ini adalah classifier, sebutan untuk model klasifikasi, yang menentukan label sebuah sampel berdasarkan tiga tetangga terdekatnya pada data latih. Data latih (training set) adalah bagian data yang digunakan model untuk belajar, sedangkan data uji (test set) adalah bagian yang disimpan khusus untuk pengukuran. Pemecahannya dilakukan oleh train_test_split dengan test_size=0.3, random_state=42, dan stratify=y. Program lengkapnya sebagai berikut.

python classifier-pertama.py
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

X, y = load_iris(return_X_y=True)

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

model = KNeighborsClassifier(n_neighbors=3)
model.fit(X_train, y_train)

y_pred = model.predict(X_test)
print("Akurasi pada data uji:", accuracy_score(y_test, y_pred))

sampel_baru = [[5.1, 3.5, 1.4, 0.2], [6.7, 3.0, 5.2, 2.3]]
print("Prediksi dua sampel baru:", model.predict(sampel_baru))
text Keluaran
Akurasi pada data uji: 0.9555555555555556
Prediksi dua sampel baru: [0 2]

Program disimpan sebagai berkas classifier-pertama.py, dan berkas yang sama dijalankan dari terminal dengan perintah berikut.

bash
# jalankan program dari folder tempat berkasnya disimpan
python3 classifier-pertama.py
text Keluaran
Akurasi pada data uji: 0.9555555555555556
Prediksi dua sampel baru: [0 2]

Setiap baris program memetakan satu langkah. load_iris(return_X_y=True) mengembalikan fitur X dan label y sebagai dua array terpisah. train_test_split memecah 150 baris menjadi 105 baris data latih dan 45 baris data uji, dengan random_state=42 menjaga agar pemecahannya tetap sama pada setiap kali dijalankan. Metode fit melatih model pada data latih, predict menghasilkan prediksi untuk data uji, dan accuracy_score membandingkan prediksi dengan label aslinya.

Mengganti model pada program ini hanya menyentuh satu baris, yaitu pembuatan objeknya. Kelas DecisionTreeClassifier maupun LogisticRegression menggunakan metode fit dan predict yang sama dengan urutan argumen yang serupa, sehingga baris lainnya tidak perlu berubah. Kesamaan perilaku inilah yang menjadikan program ini pola dasar untuk model lain dan bukan resep untuk satu model tertentu.

Membaca akurasi dan prediksi sampel baru#

Nilai akurasi pada keluaran adalah 0.9555555555555556, yaitu proporsi prediksi yang benar pada data uji. Dengan 45 sampel data uji, nilai tersebut berarti 43 sampel diprediksi benar dan 2 sampel salah. Perhitungannya dilakukan dengan membandingkan kedua array label per posisi, sehingga urutan sampel pada prediksi harus tetap sejajar dengan urutan label aslinya. Angka ini layak dipercaya karena model dinilai pada data yang tidak ikut digunakan saat pelatihan, sehingga ukurannya menyasar kemampuan model pada data baru.

Nilai n_neighbors=3 berarti setiap prediksi mengambil suara terbanyak dari tiga tetangga terdekat pada data latih. Nilai ini adalah hyperparameter, yaitu nilai yang ditetapkan sebelum pelatihan, dan mengubahnya cukup dilakukan pada satu argumen tanpa menyentuh sisa program. Nilai ganjil lazim dipilih untuk klasifikasi dua kelas agar hasil suara tidak berakhir seri, meskipun iris memuat tiga kelas.

Panggilan predict terakhir membuktikan bahwa model siap digunakan pada data yang sama sekali baru. Baris pertama [5.1, 3.5, 1.4, 0.2] diprediksi sebagai kelas 0 dan baris kedua [6.7, 3.0, 5.2, 2.3] sebagai kelas 2, yaitu jenis setosa dan virginica menurut urutan label iris. Bentuk masukannya adalah daftar yang berisi dua baris karena predict menerima kumpulan sampel dalam susunan dua dimensi, sekalipun yang diminta hanya satu sampel. Kesalahan dua prediksi dari 45 sampel data uji adalah keadaan yang wajar untuk model sederhana pada data baru. Perbaikan bila diperlukan dilakukan pada sisi data atau pengaturan model, bukan pada angka accuracy yang sudah dihasilkan.

Kesalahan umum#

Kesalahan yang sering terjadi ketika memprediksi satu sampel baru adalah memberikan satu baris fitur secara langsung dalam bentuk satu dimensi. Bentuk ini berbeda dari kebiasaan menulis vektor pada matematika, sehingga kesalahan ini hampir selalu dialami pemula. scikit-learn menuntut masukan dua dimensi, yaitu daftar yang berisi baris-baris fitur, sehingga satu sampel tetap harus ditulis sebagai daftar yang berisi satu daftar. Kode berikut merekam pesan error aslinya.

python Contoh: masukan satu dimensi pada predict
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

model = KNeighborsClassifier(n_neighbors=3)
model.fit(X_train, y_train)

sampel_satu_dimensi = [5.1, 3.5, 1.4, 0.2]
try:
    model.predict(sampel_satu_dimensi)
except ValueError as e:
    print("ValueError:", e)
text Keluaran
ValueError: Expected 2D array, got 1D array instead:
array=[5.1 3.5 1.4 0.2].
Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.

Perbaikannya tercantum pada pesan error itu sendiri. Baris fitur cukup dibungkus dengan satu daftar tambahan sehingga bentuknya menjadi (1, 4), misalnya model.predict([[5.1, 3.5, 1.4, 0.2]]), atau array numpy dirapikan dengan reshape(1, -1). Kasus sebaliknya juga muncul pada data dengan satu fitur, yaitu banyak baris dengan satu kolom, dan bentuk yang diinginkan menjadi (n, 1) melalui reshape(-1, 1). Pesan error serupa juga muncul pada metode lain seperti transform, karena seluruh fungsi scikit-learn menuntut bentuk masukan yang sama. Bila kejadian seperti ini berulang, periksa bentuk array dengan atribut .shape sebelum pemanggilan dilakukan.

Ringkasan#

  • Alur lima langkah, yaitu memuat data, memecah data, melatih model, memprediksi, dan mengukur ketepatan, menjadi pola dasar untuk semua model scikit-learn.
  • accuracy_score menghitung proporsi prediksi yang benar pada data uji yang tidak digunakan saat pelatihan.
  • predict menerima masukan dua dimensi berupa baris-baris fitur, termasuk saat hanya satu sampel yang diprediksi.
  • random_state dan stratify menjaga agar pemecahan data tetap sama dan proporsinya terjaga pada setiap kali dijalankan.

Referensi#