Tugas (lengkap) · Catatan ← → / spasi · salin per slide · cetak PDF
Tugas · Pertemuan 06
Uji data Iris dengan holdout, K-fold, dan leave-one-out. Klasifikasinya k-NN, k = 5.
Tugas · Pertemuan 06
File 6. iris.csv. Ada 150 baris, 4 atribut, dan 3 class. Setosa, versicolor, dan virginica masing-masing 50 baris. Label di file: Iris-setosa, Iris-versicolor, Iris-virginica.
Atributnya sepal length, sepal width, petal length, dan petal width. File berurutan: baris 1–50 setosa, 51–100 versicolor, 101–150 virginica.
Tugas · Pertemuan 06
Holdout · analisis
Training 120 baris: 1–40, 51–90, dan 101–140. Test 30 baris: 41–50 setosa, 91–100 versicolor, 141–150 virginica. Semua prediksi benar. 27 baris suaranya 5 lawan 0. Tiga baris selisih suaranya kecil, tetap benar: baris 143 suara 4 virginica lawan 1 versicolor, baris 147 dan 150 suara 3 virginica lawan 2 versicolor.
Lima baris yang salah di leave-one-out (71, 73, 84, 107, 120) ada di training, jadi holdout tidak menguji mereka. Hasilnya tergantung baris mana yang jadi test. Kalau 80% diambil dari urutan file, test-nya baris 121–150, semuanya virginica. Training virginica tinggal 20 baris. Salah 6 dari 30, error 20%.
0%
0 / 30 × 100% = 0%
holdout.py
Tiap class: 80% baris awal untuk training, sisanya test. 50 × 0,8 = 40, jadi 10 test per class. Training: baris 1–40, 51–90, 101–140. Test: 41–50, 91–100, 141–150.
for label in ("setosa", "versicolor", "virginica"): items = by[label] n = round(len(items) * 0.8) train += items[:n] test += items[n:] wrong = [] ties = 0 for point in test: pred, tied = predict(point, train) ties += tied if pred != point[5]: wrong.append(point[0]) print(f"{'Holdout':<16} salah {len(wrong):2} / {len(test):<3} error {percent(wrong, len(test)):6.2f}%")
Hasil
0%
0 salah dari 30 data test. Semua prediksi sama dengan class-nya.
K-fold · analisis
Data dibagi 10 fold berurutan. Tiap fold 15 baris. Setosa tidak ada yang salah. Fold 1, 2, 3, 4, 7, dan 10 error-nya 0.
Yang salah ada di batas versicolor dan virginica. Fold 5 (baris 61–75) salah 3, error 20%. Fold 6 (baris 76–90) salah 2, error 13,33%. Fold 8 (baris 106–120) salah 2, error 13,33%. Fold 9 (baris 121–135) salah 3, error 20%. Versicolor diprediksi virginica: baris 69, 71, 73, 78, 84. Virginica diprediksi versicolor: baris 107, 120, 127, 128, 134.
Satu fold 15 baris dikeluarkan sekaligus. Tetangga di fold yang sama tidak ikut memilih class. Karena itu K-fold salah lebih banyak daripada leave-one-out.
6,67%
E = (1/10) × (0 + 0 + 0 + 0 + 20 + 13,33 + 0 + 13,33 + 20 + 0) = 6,67%
kfold.py
10 fold berurutan. Tiap fold 15 baris untuk test, sisanya training. Tiap fold sama besar, jadi rata-rata error sama dengan jumlah salah dibagi 150.
size = len(rows) // FOLDS folds = [] ties = 0 for fold in range(FOLDS): test = rows[fold * size : (fold + 1) * size] train = rows[: fold * size] + rows[(fold + 1) * size :] wrong = [] for point in test: pred, tied = predict(point, train) ties += tied if pred != point[5]: wrong.append(point[0]) folds.append((test, wrong)) wrong = [no for _, fold_wrong in folds for no in fold_wrong] print(f"{'K-fold K=10':<16} salah {len(wrong):2} / {len(rows):<3} error {percent(wrong, len(rows)):6.2f}%")
Hasil
6,67%
10 salah dari 150. Semuanya versicolor tertukar dengan virginica. Fold 5 dan 9 salah 3. Fold 6 dan 8 salah 2. Fold lain tidak salah.
Leave-one-out · analisis
Ada 150 kali uji. Tiap kali 149 baris untuk training, 1 baris untuk test. Salah 5, semuanya di batas versicolor dan virginica. Baris 71, 73, dan 84 versicolor, diprediksi virginica. Suara versicolor lawan virginica: 2–3, 1–4, dan 0–5. Baris 107 dan 120 virginica, diprediksi versicolor. Suaranya 5–0 dan 3–2.
Kelima baris itu juga salah di K-fold. Lima baris lain (69, 78, 127, 128, 134) salah di K-fold, benar di sini, karena tetangganya masih ada di training. Hampir semua data ikut training. Yang tetap salah hanya baris yang lebih dekat ke class lain.
3,33%
E = 5 / 150 × 100% = 3,33%
leave_one_out.py
150 kali. Satu baris untuk test, 149 baris untuk training.
wrong = [] ties = 0 for i, point in enumerate(rows): train = rows[:i] + rows[i + 1 :] pred, tied = predict(point, train) ties += tied if pred != point[5]: wrong.append(point[0]) print(f"{'Leave-one-out':<16} salah {len(wrong):2} / {len(rows):<3} error {percent(wrong, len(rows)):6.2f}%")
Hasil
3,33%
5 salah dari 150. Baris 71, 73, dan 84 versicolor, diprediksi virginica. Baris 107 dan 120 virginica, diprediksi versicolor.
knn.py · k-NN (k=5)
Tiap data test diukur ke data training dengan jarak Euclidean. Empat atribut dipakai apa adanya. Ambil 5 tetangga terdekat. Kalau jaraknya sama, nomor baris yang lebih kecil yang dipakai. Class-nya suara terbanyak. Tidak ada suara seri.
Error = (jumlah salah / jumlah data test) × 100%
def predict(point, train): nearest = sorted(train, key=lambda tr: (math.dist(point[1:5], tr[1:5]), tr[0]))[:KNN] ranked = Counter(tr[5] for tr in nearest).most_common() tied = len(ranked) > 1 and ranked[0][1] == ranked[1][1] return ranked[0][0], tied def percent(wrong, total): return len(wrong) / total * 100
Hasil
Prediksi salah kalau class-nya beda dengan label. Holdout 0%, K-fold 6,67%, leave-one-out 3,33%.
Rata-rata error
Setosa tidak pernah salah. Semua salah ada di batas versicolor dan virginica.
Holdout 0% karena lima baris yang sulit (71, 73, 84, 107, 120) masuk training, dan 30 baris test-nya mudah ditebak. K-fold paling tinggi, 6,67%. Satu blok 15 baris keluar sekaligus, jadi tetangga yang seharusnya memilih class yang benar ikut keluar. Leave-one-out 3,33%. Tetangga dekat masih ada di training, jadi 5 dari 10 salah K-fold kembali benar.
Holdout: 0 / 30 × 100% = 0%
K-fold (K = 10): 10 / 150 × 100% = 6,67%
Leave-one-out: 5 / 150 × 100% = 3,33%