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





