Tugas (lengkap) · Catatan ← → / spasi · salin per slide · cetak PDF

Tugas · Pertemuan 06

Dataset Iris

Uji data Iris dengan holdout, K-fold, dan leave-one-out. Klasifikasinya k-NN, k = 5.

Tugas · Pertemuan 06

Dataset Iris

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

Tugas

Holdout · analisis

Analisis holdout

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

Holdout

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.

python3 holdout.py: salah 0 / 30, error 0.00%

K-fold · analisis

Analisis K-fold

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

K-fold, K = 10

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.

python3 kfold.py: salah 10 / 150, error 6.67%, plus tabel fold

Leave-one-out · analisis

Analisis leave-one-out

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

Leave-one-out

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.

python3 leave_one_out.py: salah 5 / 150, error 3.33%, baris 71, 73, 84, 107, 120

knn.py · k-NN (k=5)

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%.

python3 knn.py: Holdout 0.00%, K-fold 6.67%, leave-one-out 3.33%

Rata-rata error

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%

python3 tugas.py: Holdout 0.00%, K-fold 6.67%, leave-one-out 3.33%