Model XGBoost dan Tuning Hyperparameter dengan R
XGBoost (Extremely Gradient Boosting) adalah pustaka gradient boosting terdistribusi yang telah dioptimasi untuk mampu bekerja dengan sangat efisien, fleksibel, dan portabel. Algoritma ini merupakan peningkatan dari algoritma Gradient Boosting. XGBoost mampu menyelesaikan banyak masalah pembelajaran mesin dengan cara yang cepat dan akurat. Kode yang sama juga dapat dijalankan pada distributed environment seperti Hadoop, SGE dan MPI, serta mampu menangani komputasi yang melibatkan miliaran data.
Tutorial kali ini, kita akan mempelajari penerapan XGBoost dalam bahasa R serta melakukan tuning hyperparameter untuk meningkatkan kinerja model.
Dataset yang akan kita gunakan adalah Sonar
yang tersedia pada paket mlbench
. Dataset Sonar
terdiri dari 208 sampel, di mana setiap sampel mewakili pola sonar yang dipantulkan oleh sebuah objek di bawah air. Terdapat 60 fitur numerik yang menyatakan kekuatan sinyal sonar pada frekuensi tertentu. Fitur-fitur ini direpresentasikan sebagai bilangan real antara 0,0 hingga 1,0.
Tujuan dari pemodelan ini adalah untuk membedakan antara sinyal sonar yang dipantulkan oleh batuan (kelas “R”) dan sinyal sonar yang dipantulkan oleh tambang logam (kelas “M”).
Penyiapan Data
Untuk mengikuti tutorial ini pastikan telah menginstal paket XGBoost di R dengan menjalankan perintah install.packages("xgboost")
. Selanjutnya, impor library XGBoost dengan perintah library(xgboost)
. Paket lainnya yang juga diperlukan adalah mlbench
untuk mengakses data Sonar
dan paket caret
untuk partisi data dan tuning hyperparameter.
R
# instalasi packages # install.packages("xgboost", "mlbench", "caret") library(xgboost) library(caret) library(mlbench) # Load Dataset Sonar data(Sonar) # menampilkan summary data summary(Sonar)
Output
V1 V2 V3 V4 V5 Min. :0.00150 Min. :0.00060 Min. :0.00150 Min. :0.00580 Min. :0.00670 1st Qu.:0.01335 1st Qu.:0.01645 1st Qu.:0.01895 1st Qu.:0.02438 1st Qu.:0.03805 Median :0.02280 Median :0.03080 Median :0.03430 Median :0.04405 Median :0.06250 Mean :0.02916 Mean :0.03844 Mean :0.04383 Mean :0.05389 Mean :0.07520 3rd Qu.:0.03555 3rd Qu.:0.04795 3rd Qu.:0.05795 3rd Qu.:0.06450 3rd Qu.:0.10028 Max. :0.13710 Max. :0.23390 Max. :0.30590 Max. :0.42640 Max. :0.40100 ... V57 V58 V59 V60 Class Min. :0.00030 Min. :0.000300 Min. :0.000100 Min. :0.000600 M:111 1st Qu.:0.00370 1st Qu.:0.003600 1st Qu.:0.003675 1st Qu.:0.003100 R: 97 Median :0.00595 Median :0.005800 Median :0.006400 Median :0.005300 Mean :0.00782 Mean :0.007949 Mean :0.007941 Mean :0.006507 3rd Qu.:0.01043 3rd Qu.:0.010350 3rd Qu.:0.010325 3rd Qu.:0.008525 Max. :0.03550 Max. :0.044000 Max. :0.036400 Max. :0.043900
Langkah berikutnya adalah membagi data menjadi data latih dan data uji. Gunakan fungsi createDataPartition
dari paket caret
untuk membagi data secara acak. Parameter pertama kita berikan nilai Sonar$Class
yang merupakan kelas target ("M"
dan "R"
). Parameter p
adalah proporsi data latih (misalnya, 0.8 untuk 80% data latih dan 20% data uji).
Data yang dimasukkan pada fungsi xgboost
harus memiliki format tertentu (DMatrix
) dan tidak dapat menerima format dataframe secara langsung. Oleh karena itu perlu mengonversi data latih dan data uji menjadi format DMatrix
. Gunakan fungsi xgb.DMatrix()
untuk melakukan konversi tersebut.
Kita juga perlu mengganti label dari peubah target (Class
) menjadi 0 dan 1 karena nantinya penggunaan objective
dengan nilai "binary:logistic"
untuk klasifikasi biner mewajibkan label bernilai 0 dan 1. Pada contoh ini kita mengganti kelas "M"
menjadi 1
sementara kelas "R"
menjadi 0.
R
# Memuat dataset Sonar dari paket mlbench data(Sonar) summary(Sonar) # Menetapkan seed untuk reproduktibilitas set.seed(100) # Memisahkan data menjadi data training dan testing trainIndex <- createDataPartition(Sonar$Class, p = 0.8, list = FALSE) # Konversi data ke dalam format XGBoost trainData <- xgb.DMatrix(data = data.matrix(Sonar[trainIndex, -61]), label = ifelse(Sonar[trainIndex, 61] == "M", 1, 0)) testData <- xgb.DMatrix(data = data.matrix(Sonar[-trainIndex, -61])) # label untuk data uji testTrueLabel = Sonar[-trainIndex, 61]
Model XGBoost
Untuk membuat model XGBoost kita perlu mengatur nilai parameter-model yang akan digunakan. Beberapa parameter yang dapat diatur adalah objective
, nrounds
(jumlah maksimum iterasi), max_depth
(kedalaman maksimum pohon) dan eta
(learning rate ).
Pada sintaks di bawah ini, nilai parameter yang ditetapkan adalah objective="binary:logistic
karena model yang kita cari adalah klasifikasi biner. Selanjutnya, parameter max_depth
menggunakan nilai default yaitu 6
, eta=3
dan nrouds=100
.
Parameter lainnya yang dapat diatur yaitu nthread
. Parameter ini menunjukkan banyaknya thread yang dibuat untuk proses komputasi. Memberian nilai lebih dari 1 menunjukkan komputasi dilakukan secara multithreading. Multithreading akan mampu mempercepat proses pembelajaran namun tentu memakan resource CPU yang juga lebih besar. Pada contoh ini kita gunakan nthread=4
.
Pelatihan model dilakukan menggunakan fungsi xgboost
dengan memasukkan nilai parameter yang ditetapkan sebelumnya.
Setelah model dilatih, kita lakukan evaluasi terhadap data uji menggunakan fungsi predict
. Hasil evaluasi juga dapat kita tampilkan dalam bentuk confusion matrix.
Hasil perhitungan menunjukkan nilai akurasi pada data uji sebesar 0,8049
. Dimana dari 41 data uji, model dapat memprediksi benar sebanyak 33 amatan. Sementara 8 amatan lainnya salah prediksi.
R
# Pengaturan parameter-model params <- list(objective = "binary:logistic", max_depth = 6, eta = 0.3, nthread = 4) # Pelatihan model model <- xgboost(data = trainData, params = params, nrounds = 100, verbose = 0) # Evaluasi model (prediksi data testing) predictions <- predict(model, testData) # Merubah nilai prediksi (dalam prob.) menjadi label "M" dan "R" predictions <- as.factor(ifelse(predictions > 0.5, "M", "R")) # menampilkan label hasil prediksi print(predictions) # menampilkan label sebenarnya print(testTrueLabel) # Membuat confusion Matrix confusionMatrix(predictions, testTrueLabel)
Output
# Prediksi [1] R M R M R R R M R R R R R R R R R R R R M R R R M M M M R M M M M M M M M M M M M Levels: M R # Label sebenarnya [1] R R R R R R R R R R R R R R R R R R R M M M M M M M M M M M M M M M M M M M M M M Levels: M R Confusion Matrix and Statistics Reference Prediction M R M 17 3 R 5 16 Accuracy : 0.8049 95% CI : (0.6513, 0.9118) No Information Rate : 0.5366 P-Value [Acc > NIR] : 0.0003284 Kappa : 0.6105 Mcnemar's Test P-Value : 0.7236736 Sensitivity : 0.7727 Specificity : 0.8421 Pos Pred Value : 0.8500 Neg Pred Value : 0.7619 Prevalence : 0.5366 Detection Rate : 0.4146 Detection Prevalence : 0.4878 Balanced Accuracy : 0.8074 'Positive' Class : M
Tuning Hyperparameter
Model yang dibuat sebelumnya, menggunakan nilai-nilai parameter yang kita tetapkan langsung. Kita dapat mengatur berbagai kombinasi parameter dengan harapan memperoleh model yang memiliki performa lebih baik. Ada beberapa metode tuning yang dapat digunakan, seperti grid search atau random search.
Pada contoh ini kita menggunakan paket caret
untuk melakukan grid search. Pertama, tentukan daftar parameter beserta nilai-nilainya.
Contoh:
nrounds = c(50, 100, 200)
max.depth = c(3:6)
eta = c(0.1, 0.2, 0.3, 0.5)
Selain tiga parameter tersebut, untuk menggunakan method "xgbTree"
, kita juga wajib menentukan nilai bagi 4 parameter lainnya yaitu gamma
, colsample_bytree
, min_child_weight
dan subsample
. Namun pada contoh ini akan kita set semuanya dengan nilai 1. Silahkan jika ingin mencoba nilai-nilai lainnya sesuai rentang nilai parameter tersebut.
Selanjutnya, melalui fungsi trainControl
kita tentukan metode validasi yang mengukur performa model selama pelatihan. Di sini kita menggunakan method=cv
(k-fold cv) dengan jumlah fold (number
) sebanyak 5
. Parameter search
kita set menjadi grid
untuk melakukan pencarian menggunakan grid search.
Proses pencarian model dilakukan melalui fungsi train
dengan memasukkan nilai-nilai parameter yang sudah dibuat sebelumnya.
R
# Tuning Hyperparameter # menentukan daftar nilai parameter untuk di-tuning param_grid <- expand.grid(nrounds = c(50, 100, 200), max_depth = c(3:6), eta = c(0.2, 0.3, 0.5), gamma = 1, colsample_bytree = 1, min_child_weight = 1, subsample = 1) # mengatur validasi silang train_control <- trainControl(method = "cv", number = 5, search = "grid") tuned_model <- train(x = as.matrix(Sonar[trainIndex, -61]), y = as.factor(ifelse(Sonar$Class[trainIndex] == "M", 1, 0)), method = "xgbTree", trControl = train_control, tuneGrid = param_grid, ) # mengambil nilai parameter terbaik best_params <- as.list(tuned_model$bestTune) # menampilkan nilai-nilai parameter terbaik print(best_params)
Output
$nrounds [1] 50 $max_depth [1] 3 $eta [1] 0.2 $gamma [1] 1 $colsample_bytree [1] 1 $min_child_weight [1] 1 $subsample [1] 1
Nilai-nilai parameter terbaik hasil tuning
yaitu nrounds=50
, max_depth=3
dan eta=0.2
. Model xgboost
dengan parameter tersebut dapat diakses melalui properti finalModel
. Untuk mengukur kinerja yang sebenarnya, model ini selanjutnya kita validasi lagi menggunakan data uji.
R
# membuat model dengan parameter terbaik hasil tuning best_model <- tuned_model$finalModel # Evaluasi model (prediksi data testing) best_predictions <- predict(best_model, testData) # Merubah nilai prediksi (dalam prob.) menjadi label "M" dan "R" best_predictions <- as.factor(ifelse(best_predictions > 0.5, "M", "R")) # menampilkan label hasil prediksi print(best_predictions) # menampilkan label yang sebenarnya print(testTrueLabel) # Membuat confusion Matrix confusionMatrix(best_predictions, testTrueLabel)
Output
[1] R M R R R R R M R R R R R R R R R R R M M R R R M M M M R M M M M M M M M M M M M Levels: M R [1] R R R R R R R R R R R R R R R R R R R M M M M M M M M M M M M M M M M M M M M M M Levels: M R Confusion Matrix and Statistics Reference Prediction M R M 18 2 R 4 17 Accuracy : 0.8537 95% CI : (0.7083, 0.9443) No Information Rate : 0.5366 P-Value [Acc > NIR] : 1.883e-05 Kappa : 0.7078 Mcnemar's Test P-Value : 0.6831 Sensitivity : 0.8182 Specificity : 0.8947 Pos Pred Value : 0.9000 Neg Pred Value : 0.8095 Prevalence : 0.5366 Detection Rate : 0.4390 Detection Prevalence : 0.4878 Balanced Accuracy : 0.8565 'Positive' Class : M
Dari hasil di atas, diperoleh model yang memiliki nilai akurasi 0,8537
. Nilai lebih baik dibandingkan model tanpa tuning hyperparameter. Model mampu memprediksi benar 18 dari 20 amatan pada kelas "M"
(label : 0) serta 17 dari 21 amatan dari kelas "R"
(label : 1).