Tutorial ini adalah bagian dari mata kuliah Fundamen Sains Data, Informatika, UII. Pada Pertemuan 13, kita akan mencoba mengaplikasikan SVM ke dalam R Code.
Pertama, kita akan mencoba SVM pada data dengan dua kelas yang dapat dipisahkan secara linear. Kali ini, data set yang akan digunakan, kita buat sendiri dengan fungsi membangkitkan bilangan secara random dan terdistribusi normal.
set dulu seed-nya. Tujuannya agar saat bilangan random tersebut kita bangkit lagi di lain waktu, kita mendapatkan bilangan yang sama dengan sebelumnya.Nilai parameter di method seed() bebas, yang penting saat bilangan random tersebut kita bangkit lagi di lain waktu, nilai parameternya harus sama jika diinginkan mendapatkan bilangan yang sama dengan sebelumnya.
rnorm(). Bilangan-bilangan yang telah dibangkitkan tersebut akan dimasukkan ke dalam matrix dengan ukuran 20 baris dan 2 kolom.## [,1] [,2]
## [1,] 0.4992207 0.83459057
## [2,] -0.5095988 0.86535664
## [3,] -0.3130123 -0.54000741
## [4,] 0.7136758 0.09454017
## [5,] -1.0506291 -0.49390571
## [6,] -0.7504743 0.19165412
## [7,] -0.3502830 -0.16827662
## [8,] 0.6202636 -0.03877393
## [9,] -0.2169360 0.03409674
## [10,] -0.2485535 0.68234694
## [11,] 0.3264276 0.40061717
## [12,] -0.3113315 0.38550956
## [13,] 1.7057305 0.52631182
## [14,] 1.3354574 -1.49779748
## [15,] -2.3406379 1.20544301
## [16,] 0.2445945 -1.18418390
## [17,] -0.2278119 0.53916368
## [18,] -1.3640324 1.32334502
## [19,] 0.6404738 0.17708567
## [20,] -2.0440209 0.95016425
Dua puluh baris dan 2 kolom merepresentasikan: 20 data point atau 20 sampel (banyaknya data) dengan dua variabel x1 dan x2. Misal: x1 adalah ukuran kadar gula darah seseorang dan x2 adalah banyak gula yang dikonsumsi seseorang, yang nilainya telah dinormalisasi. Sehingga kita memiliki data set yang berukuran 20x2.
rep(). Parameter pertama menyatakan data yang ingin direplicate sedangkan parameter kedua menyatakan berapa kali data di parameter pertama ingin direplicate## [1] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 1 1
## Levels: -1 1
Perintah rep() tersebut bisa juga ditulis rep(c(-1, 1), each=10). Perintah factor() digunakan agar nilai (+1) dan (-1) menjadi kategori.
## [,1] [,2]
## [1,] 0.4992207 0.83459057
## [2,] -0.5095988 0.86535664
## [3,] -0.3130123 -0.54000741
## [4,] 0.7136758 0.09454017
## [5,] -1.0506291 -0.49390571
## [6,] -0.7504743 0.19165412
## [7,] -0.3502830 -0.16827662
## [8,] 0.6202636 -0.03877393
## [9,] -0.2169360 0.03409674
## [10,] -0.2485535 0.68234694
## [11,] 3.3264276 3.40061717
## [12,] 2.6886685 3.38550956
## [13,] 4.7057305 3.52631182
## [14,] 4.3354574 1.50220252
## [15,] 0.6593621 4.20544301
## [16,] 3.2445945 1.81581610
## [17,] 2.7721881 3.53916368
## [18,] 1.6359676 4.32334502
## [19,] 3.6404738 3.17708567
## [20,] 0.9559791 3.95016425
Penjumlahan dengan angka 3 di sini hanya bertujuan untuk memperbesar perbedaan data antara data point di kelas y=(+1) dan y=(-1). Buka kembali catatan teman-teman terkait pengaksesan elemen matriks untuk memahami code di atas.
data frame. Data frame berfungsi untuk menggabungkan beberapa variabel seperti bentuk tabel. Data frame adalah struktur data yang sering digunakan di pemodelan dengan R.myData diberi nama.myData. Axis x untuk variabel x2 atau konsumsi gula. Axis y untuk variabel x1 atau kadar gula. Data point yang termasuk kelas (+1) akan diberi warna biru. Sedangkan, data point yang termasuk kelas (-1) akan diberi warna merahDapat kita lihat, data point pada dua kelas di atas cukup terpisah, sehingga dapat dipisahkan secara linear (linearly separable).
Data point-data point di data set myData coba kita kelompokkan menggunakan SVM tanpa membagi data menjadi training data dan test data.
Jika package e1071 tidak ditemukan, install dulu package e1071 dengan perintah install.packages("e1071"). Dokumentasi dari package e1071 dapat dilihat di sini.
myData menggunakan SVM dengan memanggil fungsi svm().Parameter pertama, jika berisi suatu factor, maka factor tersebut akan menjadi acuan dalam membangun model (fit). Parameter kedua adalah data yang bertipe data frame dan berisi variabel-variabel yang akan diklasifikasikan. Parameter ketiga untuk mendeskripsikan kernel yang akan digunakan.
modelSVM1##
## Call:
## svm(formula = Diabetes ~ ., data = myData, kernel = "linear")
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: linear
## cost: 1
##
## Number of Support Vectors: 3
Berdasarkan hasil komputasi di atas, terlihat ada 3 support vector yang ditemukan.
plotPada plot di atas, support vector ditunjukkan dengan simbol “x” dan data point yang lain dengan simbol “o”. Pada plot tersebut warna merah pada simbol “x” dan simbol “o” menunjukkan bahwa dia masuk kelas (+1), sedangkan warna hitam pada simbol “x” dan simbol “o” menunjukkan bahwa dia masuk kelas (-1). Terlihat, kelas y=(+1) memiliki 2 support vector dan kelas y=(-1) memiliki 1 support vector.
Pada contoh ini, data point-data point di data set myData coba kita kelompokkan menggunakan SVM dengan membagi data menjadi training data dan test data. Pembagian data tersebut menggunakan cross validation. Di contoh ini data akan dibagi ke dalam 5 lipatan atau 5-fold cross validation.
Gambar 1 menunjukkan ilustrasi 5-fold cross validation. Misal data set kita memiliki 100 data point. Seratus data point tersebut dibagi 5 (karena yang diminta 5 lipatan). Jadi ada 5 lipatan lipatan 1, lipatan 2, lipatan 3, lipatan 4, dan lipatan 5. Masing-masing lipatan berisi 20 data point. Karena ada 5 lipatan, maka akan ada 5 kali training juga. Salah satu dari lima lipatan tersebut akan bergantian menjadi test data dan sisanya menjadi training data di setiap training-nya.
Gambar 1. 5-fold cross validation
trainControl() yang akan membantu dalam proses cross validation.## Loading required package: lattice
## Loading required package: ggplot2
Jika package caret tidak ditemukan, install dulu package caret dengan perintah install.packages("caret"). Dokumentasi dari package caret dapat dilihat di sini.
set dulu seed-nya.trainControl()myData yang telah dibagi ke training data dan test data dibangun menggunakan SVM. Berbeda dengan sebelumnya, kali ini model dibangun menggunakan fungsi train() dari package caret.Dari hasil di atas dapat dilihat bahwa akurasi yang dapat dicapai di setiap fold adalah 1 (100% benar dalam memprediksi kelas dalam setiap test set).
## Cross-Validated (5 fold) Confusion Matrix
##
## (entries are percentual average cell counts across resamples)
##
## Reference
## Prediction -1 1
## -1 50 0
## 1 0 50
##
## Accuracy (average) : 1
Dari hasil di atas dapat dilihat bahwa 50 data point dari kelas (-1) dapat diklasifikasikan dengan tepat ke kelas (-1). Begitu pula, 50 data point dari kelas (+1) dapat diklasifikasikan dengan tepat ke kelas (+1).
Kedua, kita akan mencoba SVM pada data dengan dua kelas yang tidak dapat dipisahkan secara linear. Kali ini, data set yang akan digunakan, kita buat sendiri berdasarkan tutorial di sini).
set dulu seed-nya. Tujuannya agar saat bilangan random tersebut kita bangkit lagi di lain waktu, kita mendapatkan bilangan yang sama dengan sebelumnya.runif(). Seribu data random tersebut dibangkitkan 2 kali, sebagai variabel x1 dan x2. Kemudian dua varibel tersebut digabung menjadi 1 matrix menggunakan fungsi cbind().eta <- x[,2] - sin(10*x[,1])
prob <- 1/(1+exp(-5*eta))
y <- 2*rbinom(n, 1, prob)-1
y <- as.factor(y)data frame dengan nama myData2.myData2 diberi nama.myData2. Axis x untuk variabel x2 atau konsumsi gula. Axis y untuk variabel x1 atau kadar gula.. Data point yang termasuk kelas (+1) akan diberi warna biru. Sedangkan, data point yang termasuk kelas (-1) akan diberi warna merahplot(myData2$konsumsiGula,myData2$kadarGula, col = ifelse(y=="1", "blue", "red"), pch = 19)
legend("topright", c("Y=1","Y=-1"),pch=19,col=c("blue", "red"), inset=0.05, bg=gray(1), cex=1.5)Dapat kita lihat, data point pada dua kelas di atas bercampur, sehingga tidak dapat dipisahkan secara linear (not linearly separable).
Pada Contoh 3 ini, kita lakukan langkah yang sama dengan Contoh 1. Bedanya hanya data set yang digunakan pada Contoh 3 adalah myData2 dan kernel yang digunakan pada SVM adalah radial basis. 1. Membangun model klasifikasi untuk data point di myData2 menggunakan SVM
library(e1071)
# set.seed(453)
modelSVM3 <- svm(Diabetes ~ ., data = myData2, kernel = "radial")
print(modelSVM3)##
## Call:
## svm(formula = Diabetes ~ ., data = myData2, kernel = "radial")
##
##
## Parameters:
## SVM-Type: C-classification
## SVM-Kernel: radial
## cost: 1
##
## Number of Support Vectors: 524
Berdasarkan hasil komputasi di atas, terlihat ada 524 support vector yang ditemukan.
plotPada plot di atas, support vector ditunjukkan dengan simbol “x” dan data point yang lain dengan simbol “o”. Pada plot tersebut warna merah pada simbol “x” dan simbol “o” menunjukkan bahwa dia masuk kelas (+1), sedangkan warna hitam pada simbol “x” dan simbol “o” menunjukkan bahwa dia masuk kelas (-1). Terlihat, ada potensi misklasifikasi di plot tersebut.
Pada Contoh 4 ini, kita lakukan langkah yang sama dengan Contoh 2. Bedanya hanya data set yang digunakan pada Contoh 4 adalah myData2, kernel yang digunakan pada SVM adalah radial basis, dan jumlah lipatan yang pada cross validation adalah 10 atau 10-fold cross validation.
myData2 menggunakan SVMlibrary(caret)
set.seed(543)
train_control2 <- trainControl(method="cv", number=10)
modelSVM4 <- train(Diabetes ~., data = myData2, method = "svmRadial", trControl = train_control2)
modelSVM4$resampleDari hasil di atas dapat dilihat bahwa akurasi yang dapat dicapai di setiap fold sekitar 0.8 (kurang lebih 80% benar dalam memprediksi kelas dalam setiap test set).
## Cross-Validated (10 fold) Confusion Matrix
##
## (entries are percentual average cell counts across resamples)
##
## Reference
## Prediction -1 1
## -1 29.9 7.1
## 1 8.7 54.3
##
## Accuracy (average) : 0.842
Dari hasil di atas dapat dilihat bahwa rata-rata akurasi sebesar 0.84. Untuk perhitungan hasil rata-rata TPR, FPR, TNR, FNR dari confusion matrix berdasarkan 10 fold di atas dapat dihitung menggunakan panduan di sini.
~Terima Kasih ~