Model yang baik lahir dari data yang dipahami lebih dulu. Pada bagian ini kita membuka dataset digits, menghitung jumlah sampel per kelas, memeriksa rentang nilai piksel, dan melihat satu gambar secara langsung. Keputusan-keputusan kecil pada tahap ini — misalnya memilih standardisasi dan menangani piksel konstan — menentukan apakah training loop pada bagian berikutnya berjalan mulus atau justru tersandung nilai yang tidak sahih.
Membuka Dataset #
Dataset digits dimuat dari scikit-learn dan langsung tersedia dalam memori tanpa unduhan. Potongan kode berikut adalah versi ringkas dari pemeriksaan yang kita jalankan:
import numpy as np
from sklearn.datasets import load_digits
kumpulan = load_digits()
X, y = kumpulan.data, kumpulan.target
print("bentuk X :", X.shape)
print("bentuk y :", y.shape)
print("nilai : min", X.min(), "maks", X.max())
jumlah_per_kelas = np.bincount(y)
print("jumlah sampel per kelas :", dict(enumerate(jumlah_per_kelas.tolist())))
# Tampilkan satu contoh gambar digit sebagai peta karakter.
indeks = 17
gambar = X[indeks].reshape(8, 8)
print(f"\ngambar #{indeks} (label {y[indeks]}):")
for baris in gambar:
print("".join("#" if v > 8 else ("+" if v > 4 else ".") for v in baris))Output yang Dihasilkan:
bentuk X : (1797, 64)
bentuk y : (1797,)
nilai : min 0.0 maks 16.0
jumlah sampel per kelas : {0: 178, 1: 182, 2: 177, 3: 183, 4: 181, 5: 182, 6: 181, 7: 179, 8: 174, 9: 180}
gambar #17 (label 7):
...+##..
..####..
.+#.##..
...+##..
..#####.
..+##+..
...##...
...##...Mari kita telaah potongan kode di atas baris per baris:
kumpulan.datadankumpulan.target: scikit-learn menyediakan gambar sudah diratakan menjadi vektor 64 nilai (1797 × 64) beserta labelnya (1797); bentuk asli 8x8 bisa dipulihkan denganreshape(8, 8).X.min()danX.max(): intensitas piksel berada pada rentang 0-16, bukan 0-255 seperti foto biasa — angka ini menjadi dasar keputusan standardisasi pada Bagian 3.np.bincount(y): menghitung jumlah sampel setiap kelas dalam satu pemanggilan, tanpa perulangan manual."#" if v > 8 else ...: memetakan nilai piksel ke tiga tingkat karakter sehingga pola angka tujuh masih terbaca di terminal — cara cepat memeriksa data tanpa matplotlib.
Keseimbangan Kelas #
Dari keluaran di atas, sepuluh kelas berjumlah 174 sampai 183 sampel — selisih terbesar hanya sembilan sampel. Tabel berikut merangkum implikasinya terhadap pilihan metrik:
| Sifat data | Nilai pada digits | Konsekuensi |
|---|---|---|
| Jumlah kelas | 10 (digit 0-9) | layer keluaran berukuran 10 |
| Sampel per kelas | 174-183 | seimbang; akurasi sudah layak dipakai |
| Baseline tebakan acak | ~0.10 (1/10) | akurasi 0.97 berarti jauh di atas acak |
Ketika kelas seimbang seperti ini, akurasi sederhana cukup mewakili kualitas model. Pada dataset yang timpang, kita perlu melengkapi akurasi dengan per-class recall — pokok bahasan chapter Metrik Klasifikasi .
Piksel Konstan dan Standardisasi #
Pemeriksaan pada data latih (1.347 sampel hasil pembagian stratified) menemukan tiga piksel yang bernilai sama pada seluruh sampel — piksel sudut yang hampir selalu nol karena tulisan tangan jarang menyentuh tepi. Simpangan baku piksel semacam ini bernilai nol, sehingga pembagian (x - rata2) / simpangan menghasilkan nilai tak hingga. Kode src/latih.py karena itu memasang penjaga simpangan[simpangan == 0] = 1.0 sebelum membagi.
Dataset kini kita kenal bentuknya: vektor 64 fitur, sepuluh kelas seimbang, intensitas 0-16, dan tiga piksel konstan yang perlu dijaga. Pada bagian berikutnya kita merancang arsitektur yang menerima vektor 64 fitur tersebut dan menghasilkan sepuluh skor kelas.