Pengatar Data Science
~ Tugas 3 ~
| Kontak | : \(\downarrow\) |
| mugemisausan05@gmail.com | |
| https://www.instagram.com/saram.05/ | |
| RPubs | https://rpubs.com/sausanramadhani/ |
Anggota Kelompok
Statistika Bisnis 2021 1. Calvin Riswandi 2. Sausan Ramadhani 3. Ferdinand Nathaniel Widjaya
6.1 Overview
Bab ini melanjutkan pengenalan mengenai model prediksi klasifikasi. Bab sebelumnya sudah membahas tentang training dan preprocessing, bab ini lebih fokus tentang bagaimana mengevaluasi akurasi klasifikasi, tepatnya bagaimana classifier memaksimalkan akurasinya.
6.2 Chapter Learning Objectives
Pokok bahasan yang dapat diambil setelah memperlajari bab ini :
• Mendeskripsikan training, validation, dan tes data sets serta bagaimana kita menggunakannya pada klasifikasi.
• Membagi data menjadi training, validation, dan tes data sets.
• Mendeskripsikan apa itu random seed dan pentingnya dalam reproduksi analisis data.
• Mengatur random seed di R menggunakan fungsi set.seed.
• Mengevaluasi akurasi klasifikasi di R menggunakan validasi data set dan metrics yang sesuai.
• Mengeksekusi cross-validation di R untuk memilih jumlah neighbors pada classifier KNN.
• Mendeskripsikan kelebihan dan kekurangan dari algoritma klasifikasi KNN.
6.3 Evaluating Accuracy
Untuk mengevaluasi keakuratan classifier, kita bisa menyisihkan true label dari test set. Barulah kita menggunakan classifier untuk memprediksi label pada test set.
6.4 Randomness and Seeds
Penggunaan randomize biasanya saat membuat keputusan dalam analisis yang harus adil, tidak memihak, dan tidak dipengaruhi oleh masukan manusia. kali ini, kita akan membagi data set menjadi training set dan test set untuk mengevaluasi pengklasifikasi. Kita menggunakan R untuk membagi data secara randomly.
Sebenarnya, randomness bertentangan dengan prinsip analisis data yaitu reproduktifitas yang mana biasanya menghasilkan hasil yang sama setiap dijalankan. Namun, cara mengatasinya sebenarnya randomization dalam R tidak benar-benar acak melainkan R menggunakan random number generator. Kita menggunakan fungsi set.seed untuk menciptakan kembali sequence yang kita dapatkan (seed valuenya sama). Berikut ini kita coba cara kerja seeds di R dengan menggunakan 10 nomor acak dari 0-9 (juga menggunakan fungsi sample):
set.seed(1)
random_numbers <- sample(0:9, 10, replace=TRUE)
random_numbers## [1] 8 3 6 0 1 6 1 2 0 4
Setelah terlihat hasilnya, kita gunakan kembali fungsi sample dengan 10 angka acak.
random_numbers <- sample(0:9, 10, replace=TRUE)
random_numbers## [1] 4 9 5 9 6 8 4 4 8 8
Dengan menggunakan set.seed kita bisa memanggil sequence angka yang sama dengan argumentvalue yang sama
set.seed(1)
random_numbers <- sample(0:9, 10, replace=TRUE)
random_numbers## [1] 8 3 6 0 1 6 1 2 0 4
random_numbers <- sample(0:9, 10, replace=TRUE)
random_numbers## [1] 4 9 5 9 6 8 4 4 8 8
Dengan seed yang berbeda, sequence angkanya juga berbeda
set.seed(4235)
random_numbers <- sample(0:9, 10, replace=TRUE)
random_numbers## [1] 8 3 1 4 6 8 8 4 1 7
random_numbers <- sample(0:9, 10, replace=TRUE)
random_numbers## [1] 3 7 8 2 8 8 6 3 3 8
randomness tidak hanya menggunakan fungsi sample melainkan juga menggunakan tidymodels, tidyverse, dan lainnya. Dalam analisis data, setelah memuat package maka kita memanggil fungsi set.seed supaya data kita bisa di panggil kembali dan tidak ada re-random.
6.5 Evaluating Accuracy With tidymodels
Selain digunakan untuk memproses KNN, tidymodels juga bisa menjelaskan jalannya klasifikasi yang kita lakukan.
# 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_concav6.5.1 Create the train / test split
Berikut ini akan dibuat train/test split menggunakan initial_split dari tidymodels.
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~
Dengan menggunakan fungsi glimpse untuk melihat data dengan skala yang besar, kita bisa tahu bahwa jumlah data masing-masing set. 426 di Training dan 143 di Test sesuai dengan pembagian 75-25 yang diinginkan.
Lalu menggunakan group_by dan summarize untuk melihat proporsi antara malignant dan benign.
cancer_proportions <- cancer_train |>
group_by(Class) |>
summarize(n = n()) |>
mutate(percent = 100*n/nrow(cancer_train))
cancer_proportions6.5.2 Preprocess the data
Metode KNN Sangat sensitive terhadap hasil predictor, harus dilakukan standarize terhadap Training data menggunakan recipe dari package tidymodels
cancer_recipe <- recipe(Class ~ Smoothness + Concavity, data = cancer_train) |>
step_scale(all_predictors()) |>
step_center(all_predictors())6.5.3 Train the classifier
Kita akan membuat Classification menggunakan K-Nearest Neighbour dengan Training Set menggunakan K=3 dengan concavity dan smoothness sebagai predictor. Pertama kita membuat model spesifiknya lalu mengkombinasikan dengan recipe lalu gunakan fit pada training data untuk membuat classifier.
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
6.5.4 Predict the labels in the test set
Setelah memiliki classifier dari K-nearest neighbors, kita akan mencoba mengujinya untuk memprediksi dan melabeli data menggunakan test set. Menggunakan bind_cols untuk menambahkan kolom prediksi ke test data membuat dataframe bernama cancer_test_prediction Dengan variabel Class yang berisi diagnosa sebenarnya dan .pred_class adalah diagnosa menggunakan classifier KNN.
cancer_test_predictions <- predict(knn_fit, cancer_test) |>
bind_cols(cancer_test)
cancer_test_predictions6.5.5 Compute the accuracy
Menghitung accuracy dari classifier menggunakan metric dari package tidyverse dengan perhitungan truth dengan argument sebagai perhitungan akurasi.
cancer_test_predictions |>
metrics(truth = Class, estimate = .pred_class) |>
filter(.metric == "accuracy")Dari hasil metric kita hanya mengambil accuracy karena itu yang dicari, lalu jika melihat .estimate menunjukkan akurasi sebesar 86% Kita juga bisa melihat spesifikasi hasil prediksi dari KNN menggunakan conf_mat
confusion <- cancer_test_predictions |>
conf_mat(truth = Class, estimate = .pred_class)
confusion## Truth
## Prediction M B
## M 39 6
## B 14 84
Hasil confusion tersebut menunjukkan 39 data berhasil diprediksi Magnant dan 84 sebagai Benign sesuai dengan diasgnosa aslinya. Tapi masih ada ruang kecil untuk kesalahan, dimana Prediksi mengatakan 14 sebagai Magnant, walau aslinya adalah Benign dan 6 yang Sebaliknya.
6.5.6 Critically analyze performance
Tingkat AKurasi 86% sudah cukup tinggi, apakah bisa lebih akurat lagi? Umumnya, level akurasi ditentukan oleh aplikasi prediksi tersebut. Jika ingin memprediksikan klasifikasi tumor dengan level aurasi 99% mungkin masih kurang akurat ditambah jika ada faktor Error dan kesalahan yang dibuat oleh AI. Efeknya adalah kesalahan penanganan dan pengobatan pada pengidap tumor yang menerima treatment, seperti Pasien dengan kelas Malignant yang dilabeli Benign tidak menerima pengobatan seperti yang harusnya seorang pengidap tumor Malignant jalani.
KNN juga dipengaruhi oleh Kelas Mayoritas, setelah menginput data seperti diatas kita berharap agar KNN dapat memiliki prediksi yang akurat , bisa dilihat proporsi data cancer data proportions
cancer_proportionsBenign merupakan kelas mayoritas di dataset tersebut, expectationnya adalah KNN memiliki accuracy diatas persentase kelas mayoritas (63%) yang ternyata bisa lebih akurat daripada harapan (86%). Tapi efek kelas mayoritas tersebut mempengaruhi beberapa Malignant Tumors yang salah di Diagnosis menjadi Benign sebanyak 14 dari 53 data (26%) error rate yang cukup besar apalagi mempengaruhi pennanganan medis dan nyawa seseorang.
6.6 Turning The Classifier
Kebanyakan Machine Learning dan statistics memiliki Parameter, sebuah batasan yang kita pilih untuk menentukan model bekerja. Di KNN kita memilih parameter K untuk menentukan berapa banyak neighbor yang masuk dalam kelas. Beda nilai K beda juga hasil prediksi.
Bagaimana cara memilih nilai K yang paling efektif untuk memaksimalkan peformance dari data classifier yang kita punya? Menggunakan metode Split yang sama seperti sebelumnya lalu melakukan step-by-step sampai mendapatkan parameter yang tepat untuuk melakukan klasifikasi.
P.S. : Jangan menyentuh apa yang ada di Test Set selama proses tuning, gunakan Test Set saat proses pengujian
6.6.1 Cross-validation
Pertama, kita melakukan perbandingan dari hasil setiap nilai dari K dan memilih yang paling cocok dengan menggunakan Training Set (Validation set) Berbeda dengan sebelumnya, kita hanya membuat single split dari data. Karena in the end hanya ada 1 classifier yang akan digunakan. Tapi selama proses tuning, kita bebas menciptakan banyak classifier dengan berbagai faktor untuk menentukan parameter value yang paling tepat dan akurasi yang lebih baik .
Contohnya, kita akan menguji 5 splits atau hitungan yang berbeda selama proses tuning dan membandingkan dengan yang hanya 1 kali splits. Mulai dengan Single Split
# 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
Dalam Sekali hitung atau dengan sekali split, akurasi berada di 88%. Kita lakukan ulang coding tersebt sebanyak 4 kali untuk mendapatkan 5 jenis data dengan 5 level akurasi berbeda : 88.8%, 86.9%, 83.2%, 88.8%, 87.9% . Nilai Akurasi tersebut tidaklah jauh berbeda dengan yang lainnya, kelimanya hanyalah estimasi nilai akurasi dari Classifier yang kita miliki dengan rata-rata 87%.
Dalam prakteknya, kita tidak menggunakan random splits, tapi meggunakan procedure split dimana satu data/amatan hanya muncul satu kali di Validation Set atau Test Set. Taktik ini bernama Cross-Validation. Dimana kita meng-split data menjadi C bagian sama besar dan menggunakan 1 bagian msebagai Validation Set dan Sisanya sebagai Training Set
Dengan R, Cross-Validation 5 Splits bisa dilakulkan dengan package tidymodels dengan function vfold_cv yang membagi data kita mnenjadi v bagian. Lalu strata untuk membedakan label memastikan masing-masing splits memiliki proporsi yang sama dengan label atau kelasnya.
cancer_vfold <- vfold_cv(cancer_train, v = 5, strata = Class)
cancer_vfoldLalu menggunakan fit_resamples untuk melakukan cross validation di tiap splits
# 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_fitMenggunakan collect_metrics untuk mendapatkan agregate dari mean dan standard error setiap classifier. Nilai accuracy akan tampil di accuracy di kolom .metric . Mean (mean) dijadikan sebagai perkiraan akurasi dan standard error (std_err) menyatakan nilai error dari Mean. Jika Mean 0.88 dan Standard Error 0.02 maka nilai akurasinya berkisar antara 86%-90% Untuk smentara, kita bisa mengabaikan baris roc_auc
knn_fit |>
collect_metrics() Kita bisa melakukan dengan berbagai jumlah splits yang pastinya meningkatkan average akurasi tapi semakin memberatkan system dan waktu proses semakin lama. DAlam melakukan hak ini, perhatikan ukuran dan jumlah data juga kemampuan hardware dan algoritma. Biasanya nilai C adalah 5 atau 10. Contoh Cross-Validation dengan 10 Splits
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
Di tahap sebelumnyaa, setelah perhitungan diestimasikan tingkat akurasi dari classifier tersebut sekitar 89% Dalam kondisi tertentu, itu sudah cukup tapi untuk data Cancer yang berhubungan dengan resiko tinggi bahkan sampai melibatkan Nyawa seseorang, kit aperlu meningkatkan tingkat akurasinya.
Untuk menongkatkan level akurasinya, kita bisa menentukan parameter jumlah neighbor, K. Dengan metode Cross-Validation kta bisa menentukan akurasi dari masing-masing nilai K dalam range yang ditentukan lalu memilih K yang punya akurasi terbaik. tidymodels menyediakan function yang bisa digunakan yaitu tune()
knn_spec <- nearest_neighbor(weight_func = "rectangular",
neighbors = tune()) |>
set_engine("kknn") |>
set_mode("classification")Menggunakan tune_grid untuk mencocokkan model tiap nilai K. Pertama-tama buat dataframe neighbor variabel yang terdapat squence dari nilai K dalam dataframe bernama k_vals dari 1-100 dengan kelipatan 5 lalu memasukkan data ke grid dalam 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")
accuraciesMenggunakan plot, kita bisa melihat nilai K mana yang memberikan tingkat akurasi paling tinggi
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_kK=41 memiliki akurasi tertinggi sebesar 89,17% dan nilai K antara 30 sampai 60 bisa menjadi pilihan yang cocokk. Tapi apa yang ada di plot tersebut hanyalah estimasi, bukan brarti classifiernya akan super akurat dengan nilai K sekian. Yang dicari adalah
- Akurasi yang Optimal supaya model classifiernya akan akurat
- Jike nilai K diganti dengan nilai K yang berbeda sedikit (Misalnya menjumlahkan atau mengurangi dengan angka kecil) tidak merubah tingkat akurasi secara signifikan
- Tidak terlalu memakan banyak effort (Cost, Resources dll)
Kita mengetahui bahwa K=41 memnerikan tingkat akurasi tertinggi dan tidak memiliki perbedaan signifikan jika diganti sedikit (Poin 2) dan tidak terlalu memakan banyak Cost di proses komputasi (poin 3 ). Maka dipilihlah K=41
6.6.3 Under/Overfitting
Apa yang terjadi jika nilai K semakin membersar ? Akurasi akan menurun. Dengan grid di tune_grid menampilkan plot dengan nilai K dari 1 sampai jumlah total amatan dalam dataset.
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_lotsUnderfitting : Semakin meningkat nilai K, maka semakin banyak data yang salah masuk kelas, perbatasan antara klasifikasi Benign dan Malignant menjadi tidak jelas, dimana semakin banyak amatan yang malah masuk kelas mayoritas.
Overfitting : Ketika nilai K menurun, dan karena Data yang angkanya berbeda-beda, Classifier akan menyamakan kelasnya dengan amatan yang didekatnya, membuat batas dimana Klasifikasi menjadi tidak jelas atau berantakan.
6.7 Summary
Algoritma Klasifikasi seperti K-Nearest Neighbor membandingkan data dengan amatan terdekatnya lalu mengklasifikan kelasnya. Mengevaluasi tingkat akurasi dari classifier bisa dengan Split Training Set dan test set atau dengan melakukan Cross-Validation.
Cara Kerja K-Nearest Neighbor dari tidymodels
- Menggunakan
initial_splituntuk membagi data menjadi training dan test set denganstratasebagai kelas pembagi nya - Gunakan
vfold_cvuntuk split data untuk melakukan cross-validation - Mmebuat
recipeyang menspesifikasi class labels dan prediktonya serta melakukan preprocessing data. Masukkan Training Data sebagaidatadi recipe. - Membuat
nearest_neighbormodel denganneighbor = true () - Menggabungkan Recipe dan Model ke
workflow()dengantune_griduntuk mengestimasi nilai akurasi dari nilai K - Memilih nilai K dengan Akurasi tertinggi
- membuat model baru untuk mencari Parameter
- Evaluasi nilai akurasi yang terlah diestimasi dengan
predict
Plus Side K -nearest neighbors classification + Algoritma yang Simple + Membutuhkan asumsi seperti apa bentukannyadata + Bekerja untuk klasifikasi binary (2) dan multi class
Down Side dari K-nearest neighbors classification - Melambat ketika Datanya Besar - Tidak terlalu optimal dengan jumlah predictor yang besar - Tidak terlalu optimal apabila proporsi kelas tidak sama.
6.8 Predictor Variable Selection
Anda bisa memilih variabel apapun dari data sebagai variabel yang akan digunakan untuk memprediksi. Semakin banyak predictor bukan berarti semakin akurat jika memilih Predictor yang salah bisa merusak klasifikasi yang ada.
6.8.1 The effect of irrelevant predictors
Sebagai contoh, di data Breast cancer akan menggunakan variabel predictor yaitu Smoothness Concavity dan Perimeter dengan menambahkan Data angka random 0 dan 1 yang dusebut sebagai irrelevant1 dan Irrelevant2
cancer_irrelevant = cancer
cancer_irrelevant$Irrelevant1 = sample(c(0,1), replace=TRUE, size=569)
cancer_irrelevant$Irrelevant2 = sample(c(0,1), replace=TRUE, size=569)
cancer_irrelevant$Irrelevant3 = sample(c(0,1), replace=TRUE, size=569)cancer_irrelevant |>
select(Class, Smoothness, Concavity, Perimeter, Irrelevant1, Irrelevant2)Selanjutnya, membuat KNN dengan melibatkan variabel-variabel tersebut. Semakin banyak Irrelevant variables, semakin turun pula nilai akurasi dari classifier tersebut karena kehadiran variabel tersebut menghadirkan influence yang bisa merusak jumlah neighbor yang mempernaruhi proses dan hasil klasifikasi.
6.8.2 Finding a good subset of predictors
Bagaimana memilih variabel yang cocok untuk melakukan klasifikasi? Bisa menggunakan proses visualisasii data untuk menunjukkan kira-kira mana variabel yang relevan untuk digunakan.
Cara pertama dengan menggunakan semua subset yang mungkin, melakukan proses trial dan error berulang kali sampai mendapatkan klasifikasi yang terbaik. Disebut juga best subset selection (Beale, Kendall, and Mann 1967; Hocking and Leslie 1967) Kelemahannya adalah memperlambat kinerja system dan cenderung menghabiskan banyak waktu serta biaya, karena kita menggunakan semua kombinasi yang mungkin terjaid. Contohnya ada 3 variabel (A,B,C) maka kita melakuan subset and trial sebanyak 7 kali (A,B,C AB, AC, BC, ABC)
Cara Kedua bisa dengan membuat model klasifikasi lalu menambahkan satu-persatu variabel disebut juga forward selection (Eforymson 1966; Draper and Smith 1966) Dimulai dengan membuat model dengan jumlah predictor = 0 lalu menambahkan satu persatu variabel tersebut ke dalam model sampai menghasilkan model yanhg memiliki tingkat akurasi tertinggi.
6.8.3 Forward selection in R
Di R tepatnya tidyverse tidak ada cara yang fully automatic dalam melakukan ini. Tapi bisa dengan manual, pertama-tama select untuk mengekstrak predictors.
cancer_subset <- cancer_irrelevant |>
select(Class,
Smoothness,
Concavity,
Perimeter,
Irrelevant1,
Irrelevant2,
Irrelevant3)
names <- colnames(cancer_subset |> select(-Class))
cancer_subsetMenggunakan fungsi paste untuk menciptakan model. Lalu collapse akan menentukan paste apa yang harus ditaruh di antara items . Untuk membuat formula =nya
example_formula <- paste("Class", "~", paste(names, collapse="+"))
example_formula## [1] "Class ~ Smoothness+Concavity+Perimeter+Irrelevant1+Irrelevant2+Irrelevant3"
Lalu, membuat code dimana akan mencari prediktor terbaik untuk dipakai di model akhir. Setiap predictor dibuatkan model formula, dimasukkan ke recipe , membuat workflow dengan K-NN classifier menggunakan Cross-Validation dengan 5 Splits lalu mencatat nilai estimasi akurasinya.
# 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]
}
accuraciesDari hasilnya, dilihat bahwa kombinasi Class, Concativity dan Smoothness Memiliki nilai akurasi paling tinggi sehingga ketiga variabel itulah yang akan kita gunakan dalam membuat Classifier.