Pengantar Data Sains
Tugas 5
| Kontak | : \(\downarrow\) |
| ali.19arifin@gmail.com | |
| https://www.instagram.com/arifin.alicia/ | |
| RPubs | https://rpubs.com/aliciaarifin/ |
Biodata
Nama : Alicia Arifin
Prodi : Statistika Bisnis
NIM : 20214920001
Classification II : evaluation & tuning
Klasifikasi 2 : evaluasi dan menyetel
3 Evaluating accuracy
Jika seseorang melakukan pengklasifikasian dalam hasilnya tidak perlu prediksinya 100% benar, akan tetapi kita juga tidak boleh membuat terlalu banyak prediksi salah. Untuk itu, kita harus mengevaluasi keakuratan data dengan membagi data menjadi set pelatihan dan set tes.
Untuk mencari berapa besar akurasi prediksi dari data kita dapat menggunakan rumus dibawah ini.
PA = NCP/TNP
ket
- PA = Prediction Accuracy
- NCP = Number of Correct Prediction
- TNP = Total of Correct Prediction
4 Randomness and seeds
Dalam proses analisis data kita memerlukan teknik pengambilan data acak agar menghindari dari sikap ketidakadilan, memihak, atau dipengaruhi oleh faktor luar. Dengan R sendiri kita dapat melakukan pengacakan nilai dengan menggunakan set.seed(). Akan tetapi, nilai acak yang di dapat itu tidak benar-benar acak selama kita set nilai tersebut sesuai dengan seed yang sama.
Misalnya kita ingin mengambil 10 nomor acak dari 0 sampai 9 dengan menggunakan function sample(), untuk menghasilkan nilai output yang sama maka kita set menggunakan set.seed() seperti koding dibawah ini.
set.seed(1)
randnumb <- sample(0:9, 10, replace=TRUE)
randnumb## [1] 8 3 6 0 1 6 1 2 0 4
Jika kita ingin menjalankan sample lagi, kita akan dapat 10 nomor yang berbeda lagi.
randnumb <- sample(0:9, 10, replace=TRUE)
randnumb## [1] 4 9 5 9 6 8 4 4 8 8
Dan jika kita memilih nilai yang berbeda untuk seed katakanlah, 4235 kita mendapatkan urutan yang berbeda angka acak.
set.seed(4235)
randnumb <- sample(0:9, 10, replace=TRUE)
randnumb## [1] 8 3 1 4 6 8 8 4 1 7
Dengan kata lain, ketika kita sudah menentukan nilai seed, akan terus seperti itu angkanya meskipun terlihat acak.
randnumb <- sample(0:9, 10, replace=TRUE)
randnumb## [1] 3 7 8 2 8 8 6 3 3 8
Jadi, apasih gunanya pengambilan data acak untuk analisis data? Jawabannya adalah ketika ingin melakukan analisa kita ciptakan dulu nilai seed() agar tidak terkontaminasi oleh pengaruh-pengaruh luar yang mengakibatkan analisis kita itu tidak adil dalam mengambil keputusan. Ketika kita sudah melakukan setting pada seed kita akan mendapatkan nomor acak yang dapat direproduksi lagi dan digunakan berkali-kali dalam analisis kita.
5 Evaluating accuracy with tidymodels
Untuk mengevaluasi keakuratan data dalam R kita dapat menggunakan packages tidymodel. Packages ini digunakan untuk dapat mengevaluasi pengelompokan data. Lebih jelasnya dapat dilihat dari kodingan ini. Pada scatter plot di bawah dapat dilihat bahwa ada dua kelompok data yang harus di pisahkan dengan menggunakan KNN.
# load packages
library(tidyverse)
library(tidymodels)
# set the seed
set.seed(1)
# load data
cancer <- read_csv("unscaled_wdbc.csv") |>
# convert the character Class variable to the factor datatype
mutate(Class = as_factor(Class))
# create scatter plot of tumor cell concavity versus smoothness,
# labeling the points be diagnosis class
perim_concav <- 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("orange2", "steelblue2")) +
theme(text = element_text(size = 12))
perim_concav5.1 Create the train / test split
Setelah kita analisis data diatas pasti kita memiliki beberapa prediksi, nah prediksi tersebut akan dijawab dengan melakukan eksplorasi data. Langkah pertama dilakukan adalah membagi data tersebut menjadi data pelatihan dan data set. Lalu, untuk menguji model yang lebih akurat maka kita gunakan data pelatihan yang lebih besar. Sedangkan, untuk mendapatkan evaluasi yang akurat kita gunakan data set yang lebih besar. Misal, kita uji dengan 75% data pelatihan dan 25% data set.
cancer_split <- initial_split(cancer, prop = 0.75, strata = Class)
cancer_train <- training(cancer_split)
cancer_test <- testing(cancer_split)
glimpse(cancer_train)## Rows: 426
## Columns: 12
## $ ID <dbl> 8510426, 8510653, 8510824, 857373, 857810, 858477, 8~
## $ 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.640, 13.050, 8.618, 10.170~
## $ Texture <dbl> 14.36, 15.71, 12.44, 16.34, 19.31, 11.79, 14.88, 20.~
## $ Perimeter <dbl> 87.46, 85.63, 60.34, 87.21, 82.61, 54.34, 64.55, 54.~
## $ Area <dbl> 566.3, 520.0, 273.9, 571.8, 527.2, 224.5, 311.9, 221~
## $ Smoothness <dbl> 0.09779, 0.10750, 0.10240, 0.07685, 0.08060, 0.09752~
## $ Compactness <dbl> 0.08129, 0.12700, 0.06492, 0.06059, 0.03789, 0.05272~
## $ Concavity <dbl> 0.066640, 0.045680, 0.029560, 0.018570, 0.000692, 0.~
## $ Concave_Points <dbl> 0.047810, 0.031100, 0.020760, 0.017230, 0.004167, 0.~
## $ Symmetry <dbl> 0.1885, 0.1967, 0.1815, 0.1353, 0.1819, 0.1683, 0.27~
## $ Fractal_Dimension <dbl> 0.05766, 0.06811, 0.06905, 0.05953, 0.05501, 0.07187~
glimpse(cancer_test)## Rows: 143
## Columns: 12
## $ ID <dbl> 84501001, 846381, 84799002, 849014, 852763, 853401, ~
## $ Class <fct> M, M, M, M, M, M, M, B, M, M, M, B, B, B, B, B, B, M~
## $ Radius <dbl> 12.460, 15.850, 14.540, 19.810, 14.580, 18.630, 16.7~
## $ Texture <dbl> 24.04, 23.95, 27.54, 22.15, 21.53, 25.11, 21.59, 18.~
## $ Perimeter <dbl> 83.97, 103.70, 96.73, 130.00, 97.41, 124.80, 110.10,~
## $ Area <dbl> 475.9, 782.7, 658.8, 1260.0, 644.8, 1088.0, 869.5, 5~
## $ Smoothness <dbl> 0.11860, 0.08401, 0.11390, 0.09831, 0.10540, 0.10640~
## $ Compactness <dbl> 0.23960, 0.10020, 0.15950, 0.10270, 0.18680, 0.18870~
## $ Concavity <dbl> 0.22730, 0.09938, 0.16390, 0.14790, 0.14250, 0.23190~
## $ Concave_Points <dbl> 0.085430, 0.053640, 0.073640, 0.094980, 0.087830, 0.~
## $ Symmetry <dbl> 0.2030, 0.1847, 0.2303, 0.1582, 0.2252, 0.2183, 0.18~
## $ Fractal_Dimension <dbl> 0.08243, 0.05338, 0.07077, 0.05395, 0.06924, 0.06197~
Berdasarkan hasil pengujian 75% pelatihan dan 25% set, di dapat bahwa data pelatihan memuat 426 data dan data set memuat 143 data. Setelah, kita tau proporsih dari masing-masing data. Kita dapat kelompokan dengan meringkas data tersebut untuk mendapatkan presentasi dari pengelompokan M dan B.
cancer_proportions <- cancer_train |>
group_by(Class) |>
summarize(n = n()) |>
mutate(percent = 100*n/nrow(cancer_train))
cancer_proportionsPada data Cancer_Train didapat 63% itu Benign dan 37% Malignant.
5.2 Preprocess the data
Sebelum memasuki langkah pemerosesan, kita perlu melakukan preprocessor standarisasi dengan menggunakan data pelatihan. Kenapa menggunakan data pelatihan, agar pada saat menentukan standarisasi tidak dipengaruhi oleh data set kita. Setelah itu, kita aplikasikan secara terpisah ke set data pelatihan dan pengujian.
cancer_recipe <- recipe(Class ~ Smoothness + Concavity, data = cancer_train) |>
step_scale(all_predictors()) |>
step_center(all_predictors())5.3 Train the classifier
Setelah kita membagi data menjadi set pelatihan dan pengujian, kita dapat melanjutkan dengan melakukan pengklasifikasian KNN dengan menggunakan data set pelatihan. Langkah pertama tentukan nilai K = 3. Lalu, buat spesifikasi model dengan menggabungkan add_model() dan add_recipe() dalam prosesnya. Dapat dilihat pada koding dibawah ini.
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.1150235
## Best kernel: rectangular
## Best k: 3
5.4 Predict the labels in the test set
cancer_test_predictions <- predict(knn_fit, cancer_test) |>
bind_cols(cancer_test)
cancer_test_predictions5.5 Compute the accuracy
Pada step kini. kita dapat menghitung pengklasifikasian yang telah kita buat. Untuk melakukan hal ini, kita perlu menggunakan fungsi metrics. Fungsi ini untuk mendapatkan hasil statistik untuk menentukan kebenaran dan memperkirakan estimasinya:
cancer_test_predictions |>
metrics(truth = Class, estimate = .pred_class) |>
filter(.metric == "accuracy")
BErdasarkan hasil nilai variabel di atas, estimasi menunjukkan bahwa keakuratan dari klasifikasi pada data sebesar 86%.
Kita juga dapat melihat confusion matrix nya menggunakan fungsi conf_mat:
confusion <- cancer_test_predictions |>
conf_mat(truth = Class, estimate = .pred_class)
confusion## Truth
## Prediction M B
## M 39 6
## B 14 84
Berdasarkan hasil di atas, matrix menunjukkan bahwa 39 pengamatan diprediksi sebagai jenis ganas / M, dan 84 diprediksi sebagai jenis jinak / B. Maka dari itu, hasil menunjukkan bahwa 39+84 = 123 adalah benar. Akan tetapi, disini kita juga bisa melihat bahwa proses klasifikasi bisa membuat kesalahan. Seperti yang bisa kita lihat, hasil mengklasifikasi 14 sebagai jinak ketika mereka benar-benar ganas /M, dan 6 pengamatan sebagai ganas ketika merkea benar-benar jinak / B.
5.6 Critically analyze performance
Ketika kita melakukan langkah-langkah sebelumnya, kita menjadi tahu bahwa hasil dari pengklasifikasian adalah 86% akurat pada data yang kita tes. Terlihat bagus. Tapi apakah itu baik? atau apakah kita membutuhkan sesuatu yang lebih tinggi?
Dalam hal ini, apakah klasifikasi berdasarkan akurasi tentu akan akurat hasilnya? Kita belum bisa menentukannya. Kenapa? Karena akurasi saja tidak cukup, kita juga perlu menentukan jenis kesalahan yang dihasilkan juga. Kita ambil contoh dari yang sebelumnya, Mungkin akan buruk ketika hasil klasifikasi menunjukkan dan memprediksi hasilnya ganas, padahal sebenarnya kelasnya jinak. Pasien bisa saja akan mendapatkan dosis yang sangat kuat. BEgitu juga ketika prediksi menunjukkan hasil jinak, padahal sebenarnya adalah tipe ganas. Sehingga pasien tidak menerima pengobatan yang pas.i. Inilah sebabnya mengapa penting tidak hanya untuk melihat akurasi, tetapi juga matriks kebingungan.
Sebagai contoh, dalam data kanker payudara, ingat proporsi pengamatan jinak dan ganas dalam data pelatihan adalah sebagai berikut:
cancer_proportions
Walaupan berdasarkan hasil di atas menunjukkan tipe kelas jinak memiliki akurasi sekitar 63%, kita harus tetap waspada agar lebih akurat. kita masih harus berhati-hati karena dalam aplikasi ini, kemungkinan sangat penting untuk tidak salah mendiagnosis tumor ganas untuk menghindari pasien yang hilang yang benar-benar membutuhkan perawatan medis. Matriks kebingungan di atas menunjukkan bahwa pengklasifikasi memang salah mendiagnosis sejumlah besar tumor ganas sebagai jinak (14 dari 53 tumor ganas, atau 26%!). Oleh karena itu, meskipun akurasi meningkat pada pengklasifikasi mayoritas, analisis kritis kami menunjukkan bahwa pengklasifikasi ini mungkin tidak memiliki kinerja yang sesuai untuk aplikasi.
6 Tuning the classifier
Dalam model statistik dan mechine learning memiliki parameter. Parameter adalah nomor yang harus kita pilih sebelumnya yang dapat menentukan aspek kedepannya. Misalnya dalam klasifikasi K-nn. K-nn adalah parameter yang harus kita gunakan untuk menentukan bereapa banyak pendekatan/tetangga yang berpartisipasi/bergabung.
Pada langkah ini, kita akan memilih nilai terbaik dari K-nn. Dimana kita akan memilih nilai parameter yang baik dan tepat untuk membantu kita dalam melakukan klasifikasi. Tuning adalah bagian dari pelatihan model.
6.1 Cross-validation
Langkah pertama dalam memilih parameter K-nn adalah dapat mengevaluasi pengklasifikasi hanya dengan menggunakan training set. Dalam langkah ini, kita akan coba membagi data training set nya, satu pelatihan dari 1 subset, dan yang lainnya evaluasi. Subset data pelatihan yang digunakan untuk evaluasi sering disebut set validasi.
Disini, kami akan mencoba menghasilkan 5 validasi yang berbeda dari training data, pemisahan 5 model K-nn yang berbeda, dan mengevaluasi akurasi nya. Kita akan mulai dari 1 pemisahan saja.
# 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.8598131
Perkiraan akurasi yang dihasilkan menggunakan cara ini adalah bernilai 88,8%. Sekarang kita ulangi kode di atas 4 kali lagi, yang menghasilkan 4 perpecahan lagi. Oleh karena itu kita mendapatkan lima shuffle data yang berbeda, dan oleh karena itu lima nilai akurasi yang berbeda: 88,8%, 86,9%, 83,2%, 88,8%, 87,9%. Tidak satupun dari nilai ini yang selalu paling benar, Ini hanya 5 perkiraan akurasi yang benar dan mendasari pengklasifikasian yang kita buat.
Dalam praktiknya, kita tidak menggunakan pemisahan acak, tapi menggunakan pemisahan yang lebih terstruktur dalam kumpulan data yang digunakan dalam 1 kali saja. Nama strategi ini adalah validasi silang / cross-validation. Dalam corss-validator, kita akan membagi data training set kita secara keseluruhan menjadi C. Lalu, secara berulang menggunakan 1 shunk sebagai set validasi dan menggabungkan potongan c-1 yang tersisa.
Di sini, C = 5 potongan yang berbeda dari kumpulan data digunakan, menghasilkan 5 pilihan berbeda untuk set validasi; kami menyebut 5-fold cross-validation.
Figure 6.4 : 5-fold cross-validation
Untuk melakukan ini, kita mengunakan library tidymodels, kita menggunakan fungsi vfold_cv. Fungsi ini dapat membagi data pelatihan menjadi v berlipat secara otomatis. Kita men-set strata ke kategori variabel (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_vfoldKemudian, ketika kita membuat alur kerja analisis data kita, kita menggunakan fungsi fit_resamples alih-alih fungsi yang sesuai untuk pelatihan. Ini menjalankan validasi silang pada setiap pemisahan 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)
knn_fitFungsi collect_metrics digunakan untuk mengumpulkan rata-rata dan standar error akurasi validasi pengklasifikasi di lipatan. Kita akan menemukan hasil yang terkait dengan keakuratan baris dengan akurasi yang tercantum di bawah kolom .metric. Kita harus mempertimbangkan rata-rata (mean) sebagai perkiraan akurasi, sedangkan kesalahan standar (std_err) adalah ukuran seberapa tidak pasti kita dalam nilai rata-rata. Perlakuan terperinci tentang hal ini berada di luar lingkup bab ini. tetapi kira-kira, jika perkiraan rata-rata nya adalah 0,88 dan kesalahan standar adalah 0,02, kita dapat mengharapkan akurasi rata-rata sebenarnya dari pengklasifikasi berada di suatu tempat sekitar antara 86% dan 90% (meskipun mungkin berada di luar kisaran ini). kita dapat mengabaikan kolom lain dalam bingkai data metrik, karena kolom tersebut tidak memberikan wawasan tambahan. Anda juga dapat mengabaikan seluruh baris kedua dengan roc_auc di kolom .metric, karena berada di luar cakupan buku ini.
knn_fit |>
collect_metrics() 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_metricsSemakin banyak kita menggunakan fold, semakin baik akurasi kita dan kesalahan standar lebih rendah. Namun, kita dibatasi oleh kekuatan komputasi, semakin banyak lipatan yang kita pilih, semakin banyak perhitungan yang dibutuhkan, dan karenanya semakin banyak waktu yang dibutuhkan untuk menjalankan analisis. Jadi ketika Anda melakukan validasi silang, Anda perlu mempertimbangkan ukuran data, dan kecepatan algoritma (misalnya K-nn) dan kecepatan komputer Anda. Dalam praktiknya, ini adalah proses trial-and-error, tetapi biasanya CC dipilih menjadi 5 atau 10. Di sini kita menunjukkan bagaimana kesalahan standar berkurang ketika kita menggunakan validasi silang 10 kali lipat daripada 5 kali lipat.
6.2 Parameter value selection
Dengan menggunakan validasi silang 5 dan 10 kali lipat, kami memperkirakan bahwa akurasi prediksi pengklasifikasi kami berada di suatu tempat sekitar 89%. Apakah itu baik atau tidak tergantung sepenuhnya pada aplikasi hilir analisis data. Dalam kasus saat ini, kami mencoba memprediksi diagnosis tumor , dengan terapi kemo / radiasi yang mahal dan merusak atau kematian pasien sebagai konsekuensi potensial dari salah persiapan. Oleh karena itu, kami mungkin ingin melakukan lebih baik dari 89% untuk aplikasi ini.
Untuk meningkatkan pengklasifikasi kami, kami memiliki satu pilihan parameter yaitu angka K. Karena validasi silang membantu mengevaluasi keakuratan pengklasifikasi , kami dapat menggunakan validasi silang untuk menghitung akurasi untuk setiap nilai K dalam kisaran yang wajar, dan kemudian memilih nilai K yang memberi akurasi terbaik. Koleksi library tidymodels menyediakan sintaks yang sangat sederhana untuk model tuning: setiap parameter dalam model yang akan disetel harus ditentukan 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 menggunakan fit atau fit_resamples, kita akan menggunakan fungsi tune_grid agar sesuai dengan model untuk setiap nilai dalam berbagai nilai parameter. Secara khusus, pertama-tama kami membuat kerangka data dengan variabel K yang berisi urutan nilai K untuk dicoba. di bawah ini kami membuat dataframe k_vals dengan variabel neighbors yang mengandung nilai dari 1 hingga 100 (melangkah dengan 5) menggunakan fungsi seq. Kemudian kita meneruskan dataframe itu 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 memutuskan jumlah K mana yang terbaik dengan merencanakan akurasi versus K, seperti yang ditunjukkan pada Gambar 6.5
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_k
Menetapkan jumlah tetangga K = 41 memberikan akurasi tertinggi (89,16%). Tetapi tidak ada jawaban yang tepat atau sempurna di sini; setiap pilihan dari K = 30 dan 6060 akan dibenarkan secara wajar, karena semua ini berbeda dalam akurasi pengklasifikasi dengan jumlah kecil. Ingat, nilai yang Anda lihat di plot ini adalah perkiraan keakuratan sebenarnya dari pengklasifikasi kami. Meskipun nilai K = 41 lebih tinggi daripada yang lain pada plot ini, itu tidak berarti pengklasifikasi sebenarnya lebih akurat dengan nilai parameter ini! Umumnya, ketika memilih K (dan parameter lain untuk model prediktif lainnya), kami mencari nilai di mana:
1. kami mendapatkan akurasi yang kira-kira optimal, sehingga model kami kemungkinan akan akurat;
2. mengubah nilai ke yang terdekat (misalnya, menambah atau mengurangi angka kecil) tidak mengurangi akurasi terlalu banyak, sehingga pilihan kami dapat diandalkan di hadapan ketidakpastian;
3.biaya pelatihan model tidak melarang (misalnya, dalam situasi kita, jika K terlalu besar, memprediksi menjadi mahal!).
Kita tahu bahwa K = 41 memberikan perkiraan akurasi tertinggi. Selanjutnya, Gambar 6.5 menunjukkan bahwa perkiraan akurasi berubah hanya dengan jumlah kecil jika kita menambah atau menurunkan KK di dekat K = 41. Dan akhirnya, K = 41 tidak menciptakan biaya pelatihan komputasi yang sangat mahal. Mempertimbangkan tiga poin ini, kami memang akan memilih K = 41 untuk pengklasifikasi.
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()
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_lots6.3 Under/Overfitting
Apa yang terjadi jika kita terus meningkatkan jumlah K nya? Bahkan, akurasinya benar-benar mulai berkurang! Mari kita tentukan rentang nilai K yang jauh lebih besar untuk dicoba dalam grid. Gambar 6.6 menunjukkan plot akurasi yang diperkirakan saat kita memvariasikan K dari 1 hingga hampir jumlah pengamatan dalam kumpulan data.
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()
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_lots Figure 6.6 : PLot of accuracy estimate versus number of neighbors for many K values.
Underfitting: Apa yang sebenarnya terjadi pada pengklasifikasian ini? Ketika kita meningkatkan jumlah K, semakin banyak pengamatan pelatihan (dan mereka yang lebih jauh dan lebih jauh dari intinya) mendapatkan “katakanlah” dalam apa kelas pengamatan baru. Hal ini menyebabkan semacam “efek rata-rata” terjadi, membuat batas antara di mana pengklasifikasi kita akan memprediksi tumor menjadi ganas versus jinak untuk menghaluskan dan menjadi lebih sederhana.
6.7 Effect of K in overfitting and underfitting.
Overfitting: Sebaliknya, ketika kita mengurangi jumlah K, setiap titik data individu memiliki suara yang lebih kuat dan lebih kuat mengenai poin-poin terdekat. Jika kita membawa kasus ini ke ekstrem, mengatur K = 1, maka pengklasifikasi pada dasarnya hanya mencocokkan setiap pengamatan baru dengan K-nn terdekatnya dalam kumpulan training set. Ini sama bermasalahnya dengan kasus K yang besar , karena pengklasifikasi menjadi tidak dapat diandalkan pada data baru: jika kita memiliki set pelatihan yang berbeda, prediksinya akan sangat berbeda. Secara umum, jika model dipengaruhi terlalu banyak oleh data pelatihan, dikatakan terlalu sesuai dengan data.
Baik overfitting dan underfitting bermasalah dan akan mengarah pada model yang tidak menggeneralisasi dengan baik untuk data baru. Ketika memasang model, kita perlu menyeimbangkan antara keduanya. kita dapat melihat dua efek ini pada Gambar 6.7, yang menunjukkan bagaimana pengklasifikasi berubah saat kami menetapkan jumlah tetangga KK menjadi 1, 7, 20, dan 300.
7 Summary
Classification algorithm menggunakan satu atau lebih variabel kuantitatif untuk memprediksi nilai variabel kategoris lain. Secara khusus, algoritma Knn pertama-tama mencari nilai K di training data terdekat ke observasi baru, dan mengambil suara terbanyak dari pengamatan (training observasi). Kita dapat mengevaluasi pengklasifikasi dengan membagi data secara acak menjadi kumpulan data pelatihan dan pengujian, menggunakan training set untuk membangun pengklasifikasi, dan menggunakan set tes untuk memperkirakan keakuratannya. Akhirnya, kita dapat menyetel pengklasifikasi (misalnya, pilih jumlah K pada KNN) dengan memaksimalkan perkiraan akurasi melalui validasi silang atau cross validation. Proses keseluruhan diringkas pada Gambar 6.8.
Gambar 6.8: Gambaran umum klasifikasi KNN.
Alur cara melakukan klasifikasi K-nearest neighbor menggunakan tidymodels :
Gunakan
initial_splituntuk membagi data menjadi training set dan pengujian. Atur argumenstratake variabel label kelas. Sisihkan test set untuk saat ini.Gunakan fungsi
vfold_cvuntuk membagi training set yang akan digunakan untuk validasi silang.Buat fungsi
recipeyang menentukan label kelas dan prediktor, serta langkah-langkah preprocessing untuk semua variabel. training data akan dianggap sebagaidataargumen dalam recipe.Buat spesifikasi model
nearest_neighbors, denganneighbors = tune().Tambahkan spesifikasi resep dan model ke
workflow(), dan gunakan fungsitune_gridpada pemisahan train/validation untuk memperkirakan akurasi pengklasifikasi untuk berbagai nilai K.Pilih K yang menghasilkan perkiraan akurasi tinggi yang tidak banyak berubah kalau menggantikan K ke nilai terdekat.
Buat spesifikasi model baru dengan nilai parameter terbaik (yaitu, K), dan melatih kembali pengklasifikasi menggunakan fungsi
fit.Mengevaluasi perkiraan akurasi pengklasifikasi pada set tes menggunakan fungsi prediksi.
Dalam dua bab terakhir ini, kami berfokus pada Knn terdekat K, tetapi ada banyak metode lain yang bisa kami gunakan untuk memprediksi label kategoris.
Kelebihan : + simple, algoritma intuitif + membutuhkan beberapa asumsi tentang seperti apa data itu + bisa digunakan untuk masalah binary dan multi-class
Kekurangan : + sangat lambat jika training set semakin besar, + mungkin tidak melakukan performa baik dengan sejumlah besar prediktor, dan + mungkin tidak melakukan performa baik ketika kelas tidak seimbang.
8 Predictor variable selection
Catatan: Bagian ini tidak diperlukan membaca untuk sisa buku teks. Ini termasuk bagi pembaca yang tertarik untuk mempelajari bagaimana variabel yang tidak relevan dapat mempengaruhi kinerja pengklasifikasi, dan bagaimana memilih subset variabel yang berguna untuk dimasukkan sebagai prediktor.
Bagian yang berpotensi penting dalam penyetelan pengklasifikasi adalah memilih variable dari data yang dijadikan sebagai variabel predictor. Secara teknis kita bisa memilih satu variabel predictor pada data (K-nn menerima semua tipe angka). Namun, lebih banyak predictor tidak berarti prediksi lebih bagus. Kadang prediktor yang tidak relevan sebenarnya dapat berdampak negatif terhadap kinerja yang lebih berkelas.
8.1 The effect of irrelevant predictors
Mari kita lihat contoh di mana Knn bekerja lebih buruk ketika diberi lebih banyak prediktor. Dalam contoh ini, kami memodifikasi data kanker payudara untuk hanya memiliki variabel Smoothness, Concavity, dan Perimeter dari data asli. Kemudian, kita akan menambahkan variabel yang tidak relevan yang di buat sendiri menggunakan angka acak.
Variabel yang irrelevan masing-masing mengambil nilai 0 atau 1 dengan probabilitas yang sama untuk setiap pengamatan. Variabel yang tidak relevan tidak memiliki hubungan yang berarti dengan variabel Class .
cancer_irrelevant |>
select(Class, Smoothness, Concavity, Perimeter, Irrelevant1, Irrelevant2)
# Hasil :
## # A tibble: 569 x 6
## Class Smoothness Concavity Perimeter Irrelevant1 Irrelevant2
## <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 M 0.118 0.300 123. 1 0
## 2 M 0.0847 0.0869 133. 0 0
## 3 M 0.110 0.197 130 0 0
## 4 M 0.142 0.241 77.6 0 1
## 5 M 0.100 0.198 135. 0 0
## 6 M 0.128 0.158 82.6 1 0
## 7 M 0.0946 0.113 120. 0 1
## 8 M 0.119 0.0937 90.2 1 0
## 9 M 0.127 0.186 87.5 0 0
## 10 M 0.119 0.227 84.0 1 1
## # ... with 559 more rows
Selanjutnya, kita membuat urutan pengklasifikasi K-NN yang termasuk Smoothness, Concavity, dan Perimeter sebagai variabel prediktor, tetapi juga semakin banyak variabel yang tidak relevan. Secara khusus, kami membuat 6 set data dengan 0, 5, 10, 15, 20, dan 40 prediktor yang tidak relevan. Lalu, kita membangun model, disetel menggunakan 5-fold cross-validation, untuk setiap data set. Gambar 6.9 menunjukkan perkiraan akurasi validasi silang (cross validation) versus jumlah prediktor yang tidak relevan. Saat kami menambahkan variabel prediktor yang lebih tidak relevan, perkiraan akurasi pengklasifikasi kami menurun. variabel yang tidak relevan menambahkan jumlah acak ke jarak antara setiap pasangan pengamatan; semakin tidak relevan variabel yang ada, semakin banyak (acak) pengaruh yang mereka miliki, dan semakin mereka merusak set tetangga terdekat yang memberikan suara pada kelas pengamatan baru untuk diprediksi.
Figure 6.9
Meskipun akurasi menurun seperti yang diharapkan, satu hal mengejutkan tentang Gambar 6.9 adalah bahwa hal itu menunjukkan bahwa metode ini masih mengungguli pengklasifikasi mayoritas dasar (dengan akurasi sekitar 63%) bahkan dengan 40 variabel yang tidak relevan. Ini bisa terjadi karena pada Gambar 6.10 prosedur penyetelan untuk klasifikasi K-nn melawan keacakan ekstra dari variabel yang tidak relevan dengan meningkatkan neighbor. Tentu saja karena semua angka dari variabel yang tidak relevan, jumlah tetangga tidak meningkat dengan lancar; tetapi tren umum meningkat. Gambar 6.11 menguatkan bukti ini; jika kita memperbaiki jumlah tetangga ke K = 3, akurasinya jatuh lebih cepat.
Figure 6.10
Figure 6.11
8.2 Finding a good subset of predictors
Cara menemukan predictor yang baik : Metode sederhana + menyingkirkan data / kelas yang tidak mungkin atau tidak terlalu penting . contohnya pada data cancer ID.
Kita sebenarnya bisa memilih subset predictor menggunakan visualisasi dan analisis eksplorasi, tetapi proses ini akan memakan waktu dan terdapat error ketika ada banyak variabel yang perlu dipertimbangkan. Kita membutuhkan cara yang lebih sistematis dan menggunakan program untuk memilih variabel.
Ide yang mungkin muncul Ketika memikirkan cara sistematis untuk memilih prediktor adalah mencoba semua subset prediktor yang mungkin, kemudian memilih set yang menghasilkan pengklasifikasi “terbaik”. Cara ini bisa dibilang best subset selection : 1. membuat model terpisah untuk setiap subset prediktor yang mungkin, 2. menyetel masing-masing menggunakan validasi silang 3. pilih subset prediktor yang memberi Anda akurasi validasi silang tertinggi.
Best subset selection berlaku untuk metode klasifikasi apa pun (K-NN atau lainnya). Tetapi cara ini menjadi sangat lambat Ketika kita memiliki predictor moderat (lebih dari 10). Jumlah subset predictor ini mungkin prosesnya sangat cepat tetapi kita harus melatih model. Contoh jika kita punya 2 prediktor, Secara umum, jumlah model yang harus kita latih untuk prediktor mm adalah \(2^m -1\). 2 prediktor itu A dan B, jadi kita punya 3 set variabel yang akan dicoba (A, B, dan AB). Bayangkan jika kita punya predictor yang snagat banyak, maka kita harus memodelkan itu sendiri.
Jadi meskipun ini adalah metode sederhana, pemilihan subset terbaik biasanya terlalu mahal secara komputasi untuk digunakan dalam praktik.
Ada cara lain untuk membangun secara berulang model dengan menambahkan satu variabel prediktor pada satu waktu. Metode ini dikenal sebagai forward selection yang juga berlaku luas dan cukup mudah. Ini melibatkan langkah-langkah berikut: - Mulailah dengan model yang tidak memiliki prediktor. - Jalankan langkah berikut sampai Anda kehabisan prediktor:
- Untuk setiap prediktor yang tidak digunakan, tambahkan ke model untuk membentuk model kandidat.
- Tune semua model kandidat.
- Perbarui model untuk menjadi model kandidat dengan akurasi validasi silang tertinggi.
- Pilih model yang memberikan trade-off terbaik antara akurasi dan kesederhanaan. Katakanlah Anda memiliki prediktor dengan total m. Dalam iterasi pertama, Anda harus membuat m model kandidat, masing-masing dengan 1 prediktor. Kemudian pada iterasi kedua, Anda harus membuat model kandidat m−1, masing-masing dengan 2 prediktor (yang Anda pilih sebelumnya dan yang baru). Pola ini berlanjut untuk iterasi sebanyak yang Anda inginkan. Jika Anda menjalankan metode sampai Anda kehabisan prediktor untuk memilih, Anda akan berakhir melatih $ ½ m(m+1) $ model terpisah. Ini adalah peningkatan besar dari model \(2^m -1\) yang pilihan subset terbaik mengharuskan kita untuk berlatih.
Catatan: Satu kata peringatan sebelum kita melanjutkan. Setiap model tambahan yang kita latih meningkatkan kemungkinan bahwa kita akan mendapatkan rintangan pada model yang memiliki perkiraan akurasi validasi silang yang tinggi, tetapi akurasi benar yang rendah pada data tes dan pengamatan masa depan lainnya. Karena seleksi ke depan melibatkan pelatihan banyak model, kita menjalankan risiko yang cukup tinggi dari hal ini terjadi. Untuk menjaga risiko ini tetap rendah, gunakan saja pemilihan ke depan ketika Anda memiliki sejumlah besar data dan jumlah prediktor yang relatif kecil. Metode yang lebih maju tidak terlalu menderita masalah ini; lihat sumber daya tambahan di akhir bab ini untuk mengetahui lebih lanjut tentang metode pemilihan prediktor lanjutan.
8.3 Forward selection in R
Sayangnya tidak ad acara pendek untuk melakukan ini, kita harus mengkodekan sendiri. Pertama kita akan menggunakan fungsi select untuk mengekstrak set prediktor “total” yang bersedia kita kerjakan. Di sini kita akan memuat versi modifikasi dari data kanker dengan prediktor yang tidak relevan, dan memilih Smoothness, Concavity,Perimeter,Irrelevant1, Irrelevant2, dan Irrelevant3 sebagai prediktor potensial, dan variabel Class sebagai label. Kami juga akan mengekstrak nama kolom untuk set lengkap variabel prediktor.
cancer_subset <- cancer_irrelevant |>
select(Class,
Smoothness,
Concavity,
Perimeter,
Irrelevant1,
Irrelevant2,
Irrelevant3)
names <- colnames(cancer_subset |> select(-Class))
cancer_subset
## # A tibble: 569 x 7
## Class Smoothness Concavity Perimeter Irrelevant1 Irrelevant2 Irrelevant3
## <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 M 0.118 0.300 123. 1 0 1
## 2 M 0.0847 0.0869 133. 0 0 0
## 3 M 0.110 0.197 130 0 0 0
## 4 M 0.142 0.241 77.6 0 1 0
## 5 M 0.100 0.198 135. 0 0 0
## 6 M 0.128 0.158 82.6 1 0 1
## 7 M 0.0946 0.113 120. 0 1 1
## 8 M 0.119 0.0937 90.2 1 0 0
## 9 M 0.127 0.186 87.5 0 0 1
## 10 M 0.119 0.227 84.0 1 1 0
## # ... with 559 more rows
Ide utama forward selection code adalah menggunakan fungsi paste (menggabungkan string yang dipisahkan oleh spasi) untuk membuat rumus model untuk setiap subset prediktor yang ingin kita bangun modelnya. Argumen collapse memberi tahu paste apa yang harus diletakkan di antara item dalam daftar; untuk membuat rumus, kita perlu menempatkan simbol + di antara setiap variabel. Sebagai contoh, mari kita buat rumus model untuk semua prediktor, yang harus menghasilkan sesuatu seperti Class ~ Smoothness + Concavity + Perimeter + Irrelevant1 + Irrelevant2 + Irrelevant3:
example_formula <- paste("Class", "~", paste(names, collapse="+"))
example_formula
## [1] "Class ~ Smoothness+Concavity+Perimeter+Irrelevant1+Irrelevant2+Irrelevant3"
Akhirnya, kita perlu menulis beberapa kode yang melakukan tugas secara berurutan menemukan prediktor terbaik untuk ditambahkan ke model. Jika Anda mengingat akhir dari bab wrangling, kadang-kadang seseorang membutuhkan bentuk iterasi yang lebih fleksibel daripada apa yang telah kami gunakan sebelumnya, dan dalam kasus ini seseorang biasanya menggunakan loop for. Di sini kita akan menggunakan dua for loop: satu lebih meningkatkan prediktor set ukuran (di mana Anda melihat for (i in 1:length(names)) di bawah), dan lain untuk memeriksa prediktor mana yang akan ditambahkan di setiap putaran (di mana Anda melihat `for (j in 1:length(names))di bawah). Untuk setiap set prediktor for mencoba, kami membangun formula model, meneruskannya ke dalam recipe, membangun workflow() yang menyetel pengklasifikasi K-NN menggunakan 5-fold-cross-validation, dan akhirnya mencatat perkiraan akurasi.
# 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) |>dalam
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]
}
accuracies
tibble1
Prosedur seleksi ke depan pertama kali menambahkan tiga variabel yang berarti Perimeter, Concavity, dan Smoothness, diikuti oleh variabel yang tidak relevan. Gambar 6.12 memvisualisasikan akurasi versus jumlah prediktor dalam model.
Ketika prediktor yang berarti ditambahkan, perkiraan akurasi meningkat dan saat Anda menambahkan variabel yang tidak relevan, keakuratannya adanya pengurangan saat model mencoba menyetel jumlah tetangga untuk memperhitungkan kebisingan ekstra.
Untuk memilih model yang tepat dari urutan, kita harus menyeimbangkan akurasi tinggi dengan kesimpelan model (predictor sedikit, pleuang lebih rendah untuk overfitting). Cara mencari keseimbangan itu adalah denga melihat lekukan / “patahan” pada grafik. Siku pada Gambar 6.12 tampaknya terjadi pada model dengan 3 prediktor; setelah itu tingkat akurasi turun. Dapat disimpulkan kalau trade-off akurasi dan jumlah prediktor yang tepat terjadi dengan 3 variabel: Class ~ Perimeter + Concavity + Smoothness.
Dengan kata lain, kami telah berhasil menghapus prediktor yang tidak relevan dari model! Selalu diingat, bagaimanapun, bahwa apa yang diberikan validasi silang / cross-validation kepada kita adalah perkiraan akurasi sebenarnya; kita harus menggunakan penilaian kita ketika melihat plot ini untuk memutuskan di mana siku terjadi, dan apakah menambahkan variabel memberikan peningkatan akurasi yang berarti.
Catatan: Karena pilihan variabel mana yang akan dimasukkan sebagai prediktor adalah bagian dari penyetelan pengklasifikasi Anda, Anda tidak dapat menggunakan data pengujian Anda untuk proses ini!
Figure 6.12 : Estimated accuracy versus the number of predictors for the sequence of models built using forward selection.