Introduction to Data Science
Tugas 4 Kelompok, Chapter 6 Classification II: Evaluating & Tuning
| Kontak | : \(\downarrow\) |
| naftaligunawan@gmail.com | |
| https://www.instagram.com/nbrigittag/ | |
| RPubs | https://rpubs.com/naftalibrigitta/ |
6.1 Overview
Jika pada chapter sebelumnya kita sudah mengenal model prediksi melalui klasifikasi kelas yang kita buat. Pada kali ini, kita akan melakukan bagaimana menilai atau menaksir keakurasian dari klasifikasi yang kita prediksi. Hal ini bertujuan untuk menghasilkan klasifikasi yang efektif dan dapat berguna untuk informasi yang akan disampaikan.
6.2 Chapter Learning Objectives
Pada akhir bab, para pembaca dapat melakukan hal berikut: * Menjelaskan apa yang dimaksud dengan pelatihan, validasi, dan kumpulan data uji dan bagaimana mereka digunakan dalam klasifikasi.
Memisahkan data menjadi set data pelatihan, validasi, dan pengujian.
Menjelaskan apa itu benih acak dan pentingnya dalam analisis data yang dapat direproduksi.
Mengatur seed acak di R menggunakan fungsi
set.seed.Mengevaluasi akurasi klasifikasi dalam R menggunakan kumpulan data validasi dan metrik yang sesuai.
Menjalankan validasi silang di R untuk memilih jumlah tetangga dalam \(K\)-pengklasifikasi tetangga terdekat.
Menjelaskan keuntungan dan kerugian dari \(K\)-algoritma klasifikasi tetangga terdekat.
6.3 Evaluating Accuracy
Terkadang klasifikasi yang kita buat memiliki tingkat kemungkinan salah prediksi. Dan memang pada faktanya klasifikasi tidak selalu menyentuh persentase 100% untuk dijadikan informasi, tetapi jauh lebih baik jika kita mengurangi tingkat kesalahan atau error pada klasifikasi yang kita buat. Dan pada kesempatan kali ini, kita akan menggunakan data yang kita pakai untuk chapter sebelumnya, yaitu yang berkaitan dengan klasifikasi tingkat pada kanker atau tumor. Dengan data tersebut, kita akan mencoba latihan untuk mengukur seberapa akurat prediksi yang kita buat dan tujuannya adalah untuk memberikan informasi yang bermanfaat nantinya. Lantas sebetulnya bagaimana cara untuk menghitung tingkat akurasi pada prediksi yang kita buat? Berikut ini adalah caranya.
\[PA = NCP / TNP\]
Note
PA : Prediction Accuracy
NCP : Number of Correct Predictions
TNP : Total Number of Predictions
6.4 Randomness and Seeds
Pada chapter kali ini, kita akan lebih sering menggunakan data acak dan ini digunakan setiap momen untuk mengambil keputusan dalam analisa secara adil dan tidak memihak. Keputusan yang adil sangat penting ketika menganalisa suatu hal dan hal tersebut nantinya sangat berpengaruh kepada hasil analisa atau prediksi. Kita menggunakan bahasa pemrograman R untuk latihan untuk mengerti dasar dari bagian ini.
Ketika kita menggunakan data acak dalam analisa akan mendapat hasil yang berbeda-beda, hal ini tentunya bertentangan dengan prinsip utama analisa data, yaitu Reproduktifitas yang memiliki hasil yang sama. Untuk permasalahan ini dapat diselesaikan dengan R menggunakan fungsi seed yang memiliki peran untuk data yang terlihat acak, tetapi pada kenyataannya data tersebut sudah direproduksi secara total. Hal tersebut akan membuat hasil yang sama pada analisa data yang kita lakukan karena kita sudah memilih nilai seed yang sama juga. Agar lebih jelasnya lagi, mari kita coba dengan memilih nomor secara acak dan mengetahui cara kerja fungsi seed.
# panggil seed dan nilai utama
set.seed(2)
acakness <- sample(1:9, 10, replace = TRUE)
acakness## [1] 5 6 6 8 1 1 9 2 1 3
kita bisa melihat bahwa hasil tersebut terdiri dari 10 nomor acak dari angka 1 sampai 9 dan hal ini terlihat acak bukan? Dan bagaimana hasilnya jika kita tidak menggunakan seed ?
mari kita coba!
acakness <- sample(1:9, 10, replace = TRUE)
acakness## [1] 6 2 3 7 8 7 1 6 9 4
kita tetap mendapat 10 angka acak, namun dengan perubahan angka. Hal ini dapat kita asumsikan bahwa walau kita mendapat angka yang acak, tetapi kita dapat menentukan nilai seed nya. Dan hasilnya akan membedakan dengan yang tidak menentukan seed dan menentukan. Pada intinya, seed berperan untuk mengatur data acak yang digunakan tetap sama pada percobaan pertama dan selanjutnya. Hal yang perlu diingat adalah ketika mengatur seed lebih baik hanya sekali dari awal percobaan analisis karena jika menggunakan berkali-kali pastinya akan memengaruhi hasilnya.
6.5 Evaluating Accuracy with tidymodels
Kita dapat menggunakan perpustakaan tidymodels untuk mengetahui dan menaksir seberapa baik klasifikasi yang kita kerjakan. Jika pada chapter sebelumnya kita telah belajar tidymodels digunakan untuk membuat klasifikasi dengan metode K-nearest neighbors dan sekarang kita juga menggunakan perpustakaan tersebut pada chapter kali ini. Untuk mencobanya lebih detail lagi dan sebagai pelatihan, kita akan menggunakan data pada chapter sebelumnya yang menelisik tentang kanker atau tumor.
pertama, kita harus memanggil perpustakaan atau packages
library(tidyverse)
library(tidymodels)kemudian, kita dapat memulai mengulik untuk pelatihan.
# mengatur nilai seed
set.seed(2)
# load data
cancer <- read.csv("C:/Users/Naftali Brigitta/Documents/Kampus/PDS/unscaled_wdbc.csv")
cancerkita harus mengubah tipe data pada kolom Class yang belum berupa data statistikal dan kita dapat mengubahnya menjadi factor.
cancer <- cancer |>
mutate(Class = as.factor(Class))terakhir kita dapat melihat scatter plot berdasarkan concavity dan smoothness.
sekater <- cancer |>
ggplot(aes(x = Smoothness, y = Concavity, color = Class)) +
geom_point(alpha = 0.5) +
labs(color = "Diagnosis") +
scale_color_manual(labels = c("Malignant", "Benign"),
values = c("red", "green")) +
theme(text = element_text(size = 12))
sekater6.5.1 Create the train / test split
Kita perlu membagi data yang kita import menjadi training set dan test set untuk memutuskan sebuah hasil dari prediksi yang kita rancangkan. Pada umumnya, training set terdiri dari 50% dan 95% data yang kita miliki, sedangkan test set terdiri dari 5% sampai dengan 50%. Untuk mendapatkan model yang akurat dan evaluasi yang akurat kita akan menggunakan 75% dan 25%.
Dalam proses pemisahan data ini, kita dapat menggunakan fungsi initial_splituntuk membuat training set dan test set dengan prop = 0.75. Untuk memastikan bahwa subset training dan test berisi proporsi yang tepat, maka kita harus mengatur strata ke label kategori.
cancer_split <- initial_split(cancer, prop = 0.75, strata = Class)
cancer_train <- training(cancer_split)
cancer_test <- testing(cancer_split)selanjutnya, kita dapat memanggil data yang sudah dipisah dengan menggunakan fungsi glimpse
glimpse(cancer_train)## Rows: 426
## Columns: 12
## $ ID <int> 8510426, 8510653, 8510824, 854941, 85713702, 857155,~
## $ Class <fct> B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B~
## $ Radius <dbl> 13.540, 13.080, 9.504, 13.030, 8.196, 12.050, 13.490~
## $ Texture <dbl> 14.36, 15.71, 12.44, 18.42, 16.84, 14.63, 22.30, 21.~
## $ Perimeter <dbl> 87.46, 85.63, 60.34, 82.61, 51.71, 78.04, 86.91, 74.~
## $ Area <dbl> 566.3, 520.0, 273.9, 523.8, 201.9, 449.3, 561.0, 427~
## $ Smoothness <dbl> 0.09779, 0.10750, 0.10240, 0.08983, 0.08600, 0.10310~
## $ Compactness <dbl> 0.08129, 0.12700, 0.06492, 0.03766, 0.05943, 0.09092~
## $ Concavity <dbl> 0.066640, 0.045680, 0.029560, 0.025620, 0.015880, 0.~
## $ Concave_Points <dbl> 0.047810, 0.031100, 0.020760, 0.029230, 0.005917, 0.~
## $ Symmetry <dbl> 0.1885, 0.1967, 0.1815, 0.1467, 0.1769, 0.1675, 0.18~
## $ Fractal_Dimension <dbl> 0.05766, 0.06811, 0.06905, 0.05863, 0.06503, 0.06043~
glimpse(cancer_test)## Rows: 143
## Columns: 12
## $ ID <int> 842517, 84300903, 84501001, 84610002, 848406, 848620~
## $ Class <fct> M, M, M, M, M, M, M, M, M, M, M, B, M, B, B, M, B, M~
## $ Radius <dbl> 20.570, 19.690, 12.460, 15.780, 14.680, 16.130, 19.8~
## $ Texture <dbl> 17.77, 21.25, 24.04, 17.89, 20.13, 20.68, 22.15, 14.~
## $ Perimeter <dbl> 132.90, 130.00, 83.97, 103.60, 94.74, 108.10, 130.00~
## $ Area <dbl> 1326.0, 1203.0, 475.9, 781.0, 684.5, 798.8, 1260.0, ~
## $ Smoothness <dbl> 0.08474, 0.10960, 0.11860, 0.09710, 0.09867, 0.11700~
## $ Compactness <dbl> 0.07864, 0.15990, 0.23960, 0.12920, 0.07200, 0.20220~
## $ Concavity <dbl> 0.08690, 0.19740, 0.22730, 0.09954, 0.07395, 0.17220~
## $ Concave_Points <dbl> 0.070170, 0.127900, 0.085430, 0.066060, 0.052590, 0.~
## $ Symmetry <dbl> 0.1812, 0.2069, 0.2030, 0.1842, 0.1586, 0.2164, 0.15~
## $ Fractal_Dimension <dbl> 0.05667, 0.05999, 0.08243, 0.06082, 0.05922, 0.07356~
kemudian, kita dapat menggunakan group_by dan summarize untuk menentukan persentase dari kanker yang bersifat ganas dan jinak dari data cancer_train.
cancer_percentage <- cancer_train |>
group_by(Class) |>
summarize(n = n()) |>
mutate(percent = n/nrow(cancer_train)*100)
cancer_percentageDari hasil tersebut dapat kita lihat bahwa 63% bersifat jinak dan 37% bersifat jinak berdasarkan data training.
6.5.2 Preprocess the Data
Kita perlu membuat preprocess agar data memenuhi standard, berdasarkan chapter yang sebelumnya disebutkan bahwa algoritma KKN sangat sensitif terhadap jarak prediktornya. Kita akan menggunakan data training dalam hal ini untuk memastikan bahwa data test tidak memengaruhi aspek apapun. Untuk membuat prepocess standarization, kita akan menggunakan fungsi recipe untuk memecahkan masalah ini.
cancer_recipe <- recipe(Class ~ Smoothness + Concavity, data = cancer_train) |>
step_scale(all_predictors()) |>
step_center(all_predictors())6.5.3 Train the classifier
Kita sudah membagi data kita menjadi training dan test, lalu kita bisa membuat K-nearest neighbors dengan menggunakan data training saja. Di sini kita coba menggunakan nilai K = 3 dan menggunakan concavity dan smoohtness sebagai predictornya. Sebelum kita membuat sebuah klasifikasi haruslah kita membuat workflow terlebih dahulu dengan memadukan model spesifikasi dengan recipe.
knn_spec <- nearest_neighbor(weight_func = "rectangular", neighbors = 3) |>
set_engine("kknn") |>
set_mode("classification")knn_fit <- workflow() |>
add_recipe(cancer_recipe) |>
add_model(knn_spec) |>
fit(data = cancer_train)
knn_fit## == Workflow [trained] ==========================================================
## Preprocessor: Recipe
## Model: nearest_neighbor()
##
## -- Preprocessor ----------------------------------------------------------------
## 2 Recipe Steps
##
## * step_scale()
## * step_center()
##
## -- Model -----------------------------------------------------------------------
##
## Call:
## kknn::train.kknn(formula = ..y ~ ., data = data, ks = min_rows(3, data, 5), kernel = ~"rectangular")
##
## Type of response variable: nominal
## Minimal misclassification: 0.1126761
## Best kernel: rectangular
## Best k: 3
6.5.4 Predict the labels in the test set
Objek klasifikasi yang sudah kita dapat akan digunakan untuk memprediksi label untuk data test yang tadi kita buat.
cancer_test_predictions <- predict(knn_fit, cancer_test) |>
bind_cols(cancer_test)
cancer_test_predictions6.5.5 Compute the accuracy
Selanjutnya, kita dapat menentukan akurasi dari klasifikasi yang sudah kita buat. Kita menggunakan fungsi metrics untuk mendapat informasi statistik.
cancer_test_predictions |>
metrics(truth = Class, estimate = .pred_class) |>
filter(.metric == "accuracy")berdasarkan informasi tersebut, dapat kita ketahui bahwa kurang lebih 86% keakurasian dari klasifikasi yang kita buat. Dan kita juga dapat mencari seberapa banyak observasi yang benar dan keliru dengan confusion matrix.
konpusion <- cancer_test_predictions |>
conf_mat(truth = Class, estimate = .pred_class)
konpusion## Truth
## Prediction B M
## B 76 7
## M 14 46
berdasarkan informasi tersebut dapat kita ketahui bahwa terdapat 78 observasi kanker jinak yang benar dan 44 observasi kanker ganas yang benar. Sedangkan, terdapat juga 9 observasi kanker jinak yang ternyata ganas dan 12 observasi kanker ganas yang ternyata jinak.
6.5.6 Critically Analyze Performance
Sekarang kita sudah mengetahui bahwa klasifikasi yang kita buat ternyata memiliki tingkat akurasi sebesar 86%. Namun, lebih baik jika tidak hanya melihat dari sekedar persentasenya saja. Hal ini terbukti dari adanya confusion matrix yang memberi informasi adanya kesalahan kelas untuk pasien. Jadi, yang seharusnya jinak malah mendapat kelas ganas dan membuat kesalahan perawatan medis nantinya.
Berdasarkan proporsi yang sudah dibuat diawal menghasilkan persentase mayoritas sebesar 63% dan ketika menggunakan metode K-nearest neighbors memiliki peningkatan persetansenya. Akan tetapi, terdapat kesalahan lain yang ditemukan ketika menggunakan confusion matrix. Jadi, kita dapat asumsikan juga bahwa sebaiknya tidak hanya melihat dari segi persentase yang meningkat, tetapi dari hal lain juga. Seberapa tinggi akurasi yang ditunjukan juga harus melihat apakah sesuai dengan kinerja untuk pengaplikasian kasus.
6.6 Tuning the classifier
Model prediktif dalam ilmu statistik dan mesin pasti memiliki parameter. Apa itu parameter? Parameter adalah angka yang harus kita pilih untuk menentukan populasi. Contohnya dalam algoritma klasifikasi K-Nearest Neighbor, nah K itu sendiri adalah parameter yang harus kita pilih dalam menentukan seberapa banyak neighbor yang harus berpartisipasi dalam pemilihan class.
Jadi, bagaimana cara untuk memilih nilai terbaik dari K? Yang akan kita lakukan adalah sama seperti mengevaluasi classifier, kita akan membagi data menjadi 2 subset, yang satu untuk model training, sedangkan yang satu lagi kita gunakan untuk mengevaluasi. Pada bagian ini kita akan membahas detail prosedur, dan cara menggunakan prosedur dalam memilih nilai parameter yang baik.
Dan yang harus diingat : Jangan sesekali menyentuh set tes selama proses penyetelan masih berjalan, karena Tuning (penyetelan) adalah bagian dari model training.
6.6.1 Cross-validation
Langkah pertama dalam memilih parameter \(K\) adalah dapat mengevaluasi pengklasifikasi dengan menggunakan training data. Jika memungkinkan, kita dapat membandingkan kinerja pengklasifikasi untuk nilai \(K\) yang berbeda dan memilih yang terbaik dengan menggunakan training data. Seperti yang kami katakan, kami akan menyelesaikan ini dengan memisahkan data pelatihan, pelatihan pada satu subset, dan mengevaluasi subset lainnya. Subset data pelatihan yang digunakan untuk evaluasi sering disebut validation set (set validasi). Ada satu perbedaan utama dari pemisahan kereta/pengujian yang kami lakukan sebelumnya. Secara khusus, kami hanya membuat satu pemisahan data, karena pada akhirnya kita harus menghasilkan satu pengklasifikasi. Jika kita memiliki beberapa pemisahan data yang berbeda menjadi data pelatihan dan pengujian, hasil yang akan keluar menjadi beberapa pengklasifikasi yang berbeda. Sekarang ayo kita coba kerjakan! Kita akan menghasilkan 5 pemisahan validasi, melatih 5 model \(K\)-nearest neighbor yang berbeda-beda.
# create the 25/75 split of the training data into training and validation
cancer_split <- initial_split(cancer_train, prop = 0.75, strata = Class)
cancer_subtrain <- training(cancer_split)
cancer_validation <- testing(cancer_split)
# recreate the standardization recipe from before
# (since it must be based on the training data)
cancer_recipe <- recipe(Class ~ Smoothness + Concavity,
data = cancer_subtrain) |>
step_scale(all_predictors()) |>
step_center(all_predictors())
# fit the knn model (we can reuse the old knn_spec model from before)
knn_fit <- workflow() |>
add_recipe(cancer_recipe) |>
add_model(knn_spec) |>
fit(data = cancer_subtrain)
# get predictions on the validation data
validation_predicted <- predict(knn_fit, cancer_validation) |>
bind_cols(cancer_validation)
# compute the accuracy
acc <- validation_predicted |>
metrics(truth = Class, estimate = .pred_class) |>
filter(.metric == "accuracy") |>
select(.estimate) |>
pull()
acc## [1] 0.8878505
Estimasi akurasi dengan memakai split ini adalah 88,8%. Sekarang, ayo kita ulangi kode di atas sebanyak 4 kali. Setelah dihitung kembali, kami mendapatkan hasil yang berbeda-beda, antara lain : 88,8% ; 86,9% ; 83,2% ; 88,8% ; 87,9%. Kelima hasil itu hanya perkiraan dari akurasi dasar yang sebenarnya, dari kelima perhitungan tersebut, kami mengambil rata-ratanya adalah 87%.
Dalam praktik, kita menggunakan prosedur pemisahan yang berstruktur, sehingga setiap pengamatan dalam kumpulan data digunakan dalam kumpulan validasi hanya satu kali, strategi ini disebut cross-validation. Dalam cross-validation, kami membagi keseluruhan data pelatihan kami menjadi \(C\) setiap potongan berukuran sama. Kemudian, kita menggunakan potongan \(1\) secara iteratif sebagai set validasi dan kita menggabungkan potongan \(C-1\) yang tersisa sebagai set pelatihan.
Untuk menunjukkan cross-validation sebanyak 5 kali dengan tidymodels, kita harus menggunakan fungsi vfold_cv. Guna dari fungsi itu adalah untuk membagi data pelatihan menjadi lipatan v secara otomatis. Kami men-set argumen strata ke variabel label kategoris (Class) untuk memastikan bahwa subset pelatihan dan validasi berisi proporsi yang tepat dari setiap kategori pengamatan.
cancer_vfold <- vfold_cv(cancer_train, v = 5, strata = Class)
cancer_vfoldSelanjutnya, kita membuat data analysis workflow menggunakan fungsi fit_resamples, fungsi fit guna nya untuk training. Guna dari fungsi diatas adalah untuk menjalankan cross-validation pada pemisahahan kereta/validasi.
# recreate the standardization recipe from before
# (since it must be based on the training data)
cancer_recipe <- recipe(Class ~ Smoothness + Concavity,
data = cancer_train) |>
step_scale(all_predictors()) |>
step_center(all_predictors())
# fit the knn model (we can reuse the old knn_spec model from before)
knn_fit <- workflow() |>
add_recipe(cancer_recipe) |>
add_model(knn_spec) |>
fit_resamples(resamples = cancer_vfold)## Warning: package 'kknn' was built under R version 4.1.2
knn_fitFungsi collect_metrics berguna untuk menggabungkan rata-rata dan standar error pada akurasi validasi pengklasifikasi di seluruh lipatan. Anda akan menemukan hasil yang terkait dengan akurasi di baris dengan akurasi yang tercantum di bawah kolom .metrik. Anda harus mempertimbangkan mean (rata-rata) sebagai akurasi yang diperkirakan, sedangkan kesalahan standar (std_err) adalah ukuran seberapa tidak pasti kita dalam nilai rata-rata.
knn_fit |>
collect_metrics()Kami dapat memilih jumlah lipatan berapa pun, dan biasanya semakin banyak kami menggunakan, semakin baik perkiraan akurasi kami (kesalahan standar lebih rendah).Jadi ketika Anda melakukan cross-validation, Anda perlu mempertimbangkan ukuran data, dan kecepatan algoritme (mis., \(K\)-nearest neighbor) dan kecepatan komputer Anda. Di bawah ini, kita akan menunjukkan bagaimana kesalahan standar berkurang ketika kami menggunakan cross-validation 10 kali lipat daripada 5 kali lipat:
cancer_vfold <- vfold_cv(cancer_train, v = 10, strata = Class)
vfold_metrics <- workflow() |>
add_recipe(cancer_recipe) |>
add_model(knn_spec) |>
fit_resamples(resamples = cancer_vfold) |>
collect_metrics()
vfold_metrics6.6.2 Parameter value selection
Dengan menggunakan cross-validation dengan range 5 dan 10 kali lipat, kami memperkirakan bahwa akurasi prediksi pengklasifikasi kami sekitar 89%. Dalam situasi saat ini, kami mencoba memprediksi diagnosis tumor, dengan terapi kemoterapi/radiasi yang mahal dan merusak atau kematian pasien sebagai konsekuensi potensial dari kesalahan prediksi. Untuk meningkatkan classifier kami, kami memiliki satu pilihan parameter, yaitu: number of neigbor, alias \(K\). Sedangkan cross-validation membantu kita mengevaluasi keakuratan pengklasifikasi. Library tidymodels menyediakan sintaks yang sangat sederhana untuk model penyetelan: setiap parameter dalam model yang akan disetel harus ditetapkan sebagai tune() dalam spesifikasi model daripada diberi nilai tertentu.
knn_spec <- nearest_neighbor(weight_func = "rectangular",
neighbors = tune()) |>
set_engine("kknn") |>
set_mode("classification")Kemudian, kita akan menggunakan fit atau fit_resamples, lalu menggunakan fungsi tune_grid supaya sesuai dengan model untuk setiap nilai dalam rentang nilai parameter. Di bawah ini, ayo kita buat bingkai data k_vals dengan variabel neighbors yang berisi nilai dari 1 hingga 100 (bertahap 5) menggunakan fungsi seq. Kemudian kita meneruskan bingkai data tersebut ke argumen grid dari tune_grid.
k_vals <- tibble(neighbors = seq(from = 1, to = 100, by = 5))
knn_results <- workflow() |>
add_recipe(cancer_recipe) |>
add_model(knn_spec) |>
tune_grid(resamples = cancer_vfold, grid = k_vals) |>
collect_metrics()
accuracies <- knn_results |>
filter(.metric == "accuracy")
accuraciesKita dapat mengambil keputusan, jumlah neighbor yang mana yang terbaik dengan cara plotting akurasi.
accuracy_vs_k <- ggplot(accuracies, aes(x = neighbors, y = mean)) +
geom_point() +
geom_line() +
labs(x = "Neighbors", y = "Accuracy Estimate") +
theme(text = element_text(size = 12))
accuracy_vs_kPerlu diingat: nilai yang Anda lihat di plot ini adalah perkiraan akurasi sebenarnya dari pengklasifikasi kami. Umumnya, saat memilih \(K\) (dan parameter lain untuk model prediktif lainnya), kita mencari nilai di mana:
mendapatkan akurasi yang kira-kira optimal, sehingga hasil model kami kemungkinan akan akurat;
mengubah nilai ke nilai terdekat (misalnya, menambah atau mengurangi angka kecil) tidak mengurangi akurasi terlalu banyak;
biaya pelatihan model tidak terlalu mahal (misalnya, dalam situasi kita, jika \(K\) terlalu besar, maka hasil prediksi menjadi mahal).
6.6.3 Under / Overfitting
Apa yang akan terjadi, jika kita meningkatkan number of neighbor \(K\) secara terus-menerus? Ternyata akurasinya berkurang. Untuk membuktikan, ayo kita coba menentukan rentang nilai \(K\) dalam grid bagian dari argumen tune_grid.
k_lots <- tibble(neighbors = seq(from = 1, to = 385, by = 10))
knn_results <- workflow() |>
add_recipe(cancer_recipe) |>
add_model(knn_spec) |>
tune_grid(resamples = cancer_vfold, grid = k_lots) |>
collect_metrics()## ! Fold01: preprocessor 1/1, model 1/1: 381 samples were requested but there were 3...
## ! Fold02: preprocessor 1/1, model 1/1: 381 samples were requested but there were 3...
## ! Fold03: preprocessor 1/1, model 1/1: 381 samples were requested but there were 3...
## ! Fold04: preprocessor 1/1, model 1/1: 381 samples were requested but there were 3...
## ! Fold05: preprocessor 1/1, model 1/1: 381 samples were requested but there were 3...
## ! Fold06: preprocessor 1/1, model 1/1: 381 samples were requested but there were 3...
## ! Fold07: preprocessor 1/1, model 1/1: 381 samples were requested but there were 3...
## ! Fold08: preprocessor 1/1, model 1/1: 381 samples were requested but there were 3...
## ! Fold09: preprocessor 1/1, model 1/1: 381 samples were requested but there were 3...
## ! Fold10: preprocessor 1/1, model 1/1: 381 samples were requested but there were 3...
accuracies <- knn_results |>
filter(.metric == "accuracy")
accuracy_vs_k_lots <- ggplot(accuracies, aes(x = neighbors, y = mean)) +
geom_point() +
geom_line() +
labs(x = "Neighbors", y = "Accuracy Estimate") +
theme(text = element_text(size = 12))
accuracy_vs_k_lotsUnderfitting: Apa yang sebenarnya terjadi pada classifier kami yang menyebabkan ini? Saat kita menambah jumlah tetangga, semakin banyak pengamatan pelatihan (dan pengamatan yang semakin jauh dari titik).
Overfitting: Sebaliknya, ketika kita mengurangi jumlah tetangga, setiap titik data individu memiliki suara yang lebih kuat dan lebih kuat mengenai titik terdekat.
6.7 Summary
Algoritma klasifikasi menggunakan satu atau lebih variabel kuantitatif berguna untuk prediksi nilai variabel kategori lain. Ternyata, algoritma \(K\)-nearest neighbors menemukan titik \(K\) dalam data pelatihan terlebih dahulu. Kita dapat mengevaluasi pengklasifikasi dengan memisahkan data secara acak menjadi : kumpulan data pelatihan (untuk membangun pengklasifikasi), dan data pengujian (untuk memperkirakan akurasinya). Terakhir, kita dapat menyetel classifier (misalnya, memilih jumlah neighbor \(K\) di \(K\)-NN) dengan memaksimalkan akurasi yang diperkirakan melalui cross-validation.
Berikut alur kerja untuk melakukan klasifikasi \(K\)-nearest neighbors, antara lain :
1. Menggunakan fungsi initial_split untuk membagi data menjadi set pelatihan dan pengujian. Set argumen strata ke variabel label kelas. Sisihkan tes untuk saat ini.
2. Menggunakan fungsi vfold_cv untuk memisahkan data pelatihan untuk cross-validation.
3. Membuat recipe yang menentukan label kelas dan prediktor, serta langkah-langkah prapemrosesan untuk semua variabel. Pass data pelatihan sebagai argumen data resep.
4. Buat model spesifikasi near_neighbors, dengan neighbor = tune().
5. Menambahkan resep dan spesifikasi model ke workflow(), dan gunakan fungsi tune_grid pada pemisahan validasi untuk memperkirakan akurasi pengklasifikasi untuk rentang nilai \(K\).
6. Memilih nilai \(K\) yang menghasilkan perkiraan akurasi tinggi yang tidak banyak berubah jika Anda mengubah \(K\) ke nilai terdekat.
7. Membuat spesifikasi model baru untuk nilai parameter terbaik (yaitu, \(K\)), dan latih kembali pengklasifikasi menggunakan fungsi fit.
8. Mengevaluasi akurasi estimasi pengklasifikasi pada set tes menggunakan fungsi prediksi.
Masih banyak metode lain yang dapat kita gunakan untuk prediksi label kategorikal. Dibawah ini, kita akan menyampaikan kelebihan dan kekurangan masing-masing \(K\)-nearest neighbors classification :
Kelebihan:
1. adalah algoritma yang sederhana dan intuitif
2. membutuhkan sedikit asumsi, contohnya : seperti apa tambpilan datanya
3. dapat bekerja untuk masalah klasifikasi biner (2 kelas) dan multi-class (lebih dari 2 kelas).
Kekurangan:
1. menjadi lambat karena training data semakin besar dan semakin banyak
2. memungkinkan bekerja kurang efisien karena angka prediktor yang besar
3. memungkinkan bekerja kurang baik ketika class tidak seimbang.
6.8 Predictor variable selection
Walaupun bagian ini di katakan tidak wajib, tapi di bagian ini kita bisa mempelajari variabel yang tidak relevan bisa mempengaruhi kinerja dalam pengklasifikasi,dan di sini juga di tunjukan bagaimana cara memilih subset variabel yang nantinya berguna bisa di masukan sebagai prediktor Dan di sini juga di jelaskan bagian yang berpotensi penting dari penyetelan pengklasifikasi
Secara Teknis kita dapat memilih apapun mulai dari satu variabel prediktor sampai setiap variabel di data juga bisa kita pergunakan Algoritma K-nearst neighbor menerima beberapa prediktor. Menggunakan prediktor tidak bisa menjamin kita dapat menghasilkan prediksi yang tepat atau sesuai dengan Faktanya.
6.8.1 The effect of irrelevant predictors
Sekarang ini kita mencoba menambahkan variabel baru, yaitu Irrelevant1 dan Irrelevant2 yang berisi nilai 0 atau 1. Nilai pada variabel irrelevant ini tidak memiliki hubungan yang berarti dengan variabel Class.
Mari Kita Coba!
cancer <- cancer %>% mutate(Irrelevant1 = sample(c(0,1), replace=TRUE, size=569)) %>%
select(Class, Smoothness, Concavity, Perimeter, Irrelevant1)
cancer <- cancer %>% mutate(Irrelevant2 = sample(c(0,1), replace=TRUE, size=569)) %>%
select(Class, Smoothness, Concavity, Perimeter, Irrelevant1, Irrelevant2)
cancerDengan kita menambahkan variabel tersebut membuat keakurasian dari klasifikasi kita akan menurun karena memberikan nilai acak kepada jarak kepada setiap objek observasinya. Makin banyak jumlah besar pengaruh acak yang ada, maka akan semakin merusak hasilnya.
6.8.2 Finding a good ubset of predictors
Ketika kita ingin melakukan prediksi harusnya tidak menggunakan predictor yang kurang penting atau tidak ideal. Maka dari itu, kita seharusnya mengecek mana variabel yang cocok menjadi predictor dan mana yang tidak yang artinya jangan diambil semuanya karena belum tentu semuanya ideal. Contohnya di sini adalah variabel ID yang tidak kita gunakan untuk prediksi dalam menentukan klasifikasi dengan alasan variabel ini tidak memiliki suatu nilai yang akan memberikan hasilnya karena tujuan kita adalah mencari tahu tentang kanker jinak dan ganas saja.
Untuk menemukan predictor yang ideal agar mendapat hasil yang baik dalam klasifikasi kita dapat menggunakan metode yang bernama best subset selection dengan langkah sebagai berikut.
- Membuat terpisah untuk setiap predictor
- Menyesuaikan menggunakan cross-validation
- Memilih predictor berdasarkan nilai akurasi tertingginya
Pemilihan predictor yang ideal dapat berlaku untuk metode klasifikasi apapun. Namun, kurang efektif ketika memliki jumlah predictor yang lumayan banyak.
6.8.3 Forward selection in R
Untuk melakukan Forward Selection di R kita akan menggunakan fungsi select untuk mengekstrak total predictor yang ingin kita amati. Kita akan memasukkan variabel irrelevant. Dan kita tambahkan Irrelevant3 yang berisi nilai 0 atau 1 seperti sebelumnya.
cancer_subset <- cancer %>% mutate(Irrelevant3 = sample(c(0,1), replace=TRUE, size=569)) %>%
select(Class, Smoothness, Concavity, Perimeter, Irrelevant1, Irrelevant2, Irrelevant3)
names <- colnames(cancer_subset |> select(-Class))
cancer_subset Kunci dalam kasus ini adalah menggunakan fungsi paste.
example_formula <- paste("Class", "~", paste(names, collapse="+"))
example_formula## [1] "Class ~ Smoothness+Concavity+Perimeter+Irrelevant1+Irrelevant2+Irrelevant3"
Terakhir, kita sebaiknya menemukan predictor terbaik yang dilakukan secara berurutan. Dalam kasus ini, kita menggunakan for loop dengan langkah sebagai berikut.
# create an empty tibble to store the results
accuracies <- tibble(size = integer(),
model_string = character(),
accuracy = numeric())
# create a model specification
knn_spec <- nearest_neighbor(weight_func = "rectangular",
neighbors = tune()) |>
set_engine("kknn") |>
set_mode("classification")
# create a 5-fold cross-validation object
cancer_vfold <- vfold_cv(cancer_subset, v = 5, strata = Class)
# store the total number of predictors
n_total <- length(names)
# stores selected predictors
selected <- c()
# for every size from 1 to the total number of predictors
for (i in 1:n_total) {
# for every predictor still not added yet
accs <- list()
models <- list()
for (j in 1:length(names)) {
# create a model string for this combination of predictors
preds_new <- c(selected, names[[j]])
model_string <- paste("Class", "~", paste(preds_new, collapse="+"))
# create a recipe from the model string
cancer_recipe <- recipe(as.formula(model_string),
data = cancer_subset) |>
step_scale(all_predictors()) |>
step_center(all_predictors())
# tune the KNN classifier with these predictors,
# and collect the accuracy for the best K
acc <- workflow() |>
add_recipe(cancer_recipe) |>
add_model(knn_spec) |>
tune_grid(resamples = cancer_vfold, grid = 10) |>
collect_metrics() |>
filter(.metric == "accuracy") |>
summarize(mx = max(mean))
acc <- acc$mx |> unlist()
# add this result to the dataframe
accs[[j]] <- acc
models[[j]] <- model_string
}
jstar <- which.max(unlist(accs))
accuracies <- accuracies |>
add_row(size = i,
model_string = models[[jstar]],
accuracy = accs[[jstar]])
selected <- c(selected, names[[jstar]])
names <- names[-jstar]
}
accuraciesDi dalam prosedur forward selection, kita menambahkan tiga variabel yang penting, yaitu Perimeter, Concavity and Smoothness. Cara untuk menemukan keseimbangan itu adalah dengan mencari elbow, yaitu tempat di plot di mana akurasi berhenti meningkat secara dramatis dan level off atau mulai menurun. Selalu perlu kita ingat, bahwa apa yang diberikan cross-validation kepada kita adalah perkiraan akurasi yang sebenarnya