Saya memiliki dataset dengan dua kelas yang tumpang tindih, tujuh poin di setiap kelas, poin berada dalam ruang dua dimensi. Di R, dan saya menjalankan svm
dari e1071
paket untuk membangun hyperplane pemisah untuk kelas-kelas ini. Saya menggunakan perintah berikut:
svm(x, y, scale = FALSE, type = 'C-classification', kernel = 'linear', cost = 50000)
di mana x
berisi titik data saya dan y
berisi label mereka. Perintah mengembalikan svm-object, yang saya gunakan untuk menghitung parameter (vektor normal) dan b (intersep) dari hyperplane pemisah.
Gambar (a) di bawah ini menunjukkan poin saya dan hyperplane dikembalikan oleh svm
perintah (mari kita sebut hyperplane ini yang optimal). Titik biru dengan simbol O menunjukkan ruang asal, garis putus-putus menunjukkan margin, dilingkari adalah titik-titik yang memiliki non-nol (variabel slack).
Gambar (b) menunjukkan hyperplane lain, yang merupakan terjemahan paralel dari yang optimal oleh 5 (b_new = b_optimal - 5). Tidak sulit untuk melihat bahwa untuk hyperplane ini fungsi objektif (yang diminimalkan dengan C-klasifikasi SVM) akan memiliki nilai yang lebih rendah daripada untuk hyperplane optimal ditunjukkan pada gambar (a). Jadi apakah ada masalah dengan fungsi ini ? Atau apakah saya membuat kesalahan di suatu tempat?
svm
Di bawah ini adalah kode R yang saya gunakan dalam percobaan ini.
library(e1071)
get_obj_func_info <- function(w, b, c_par, x, y) {
xi <- rep(0, nrow(x))
for (i in 1:nrow(x)) {
xi[i] <- 1 - as.numeric(as.character(y[i]))*(sum(w*x[i,]) + b)
if (xi[i] < 0) xi[i] <- 0
}
return(list(obj_func_value = 0.5*sqrt(sum(w * w)) + c_par*sum(xi),
sum_xi = sum(xi), xi = xi))
}
x <- structure(c(41.8226593092589, 56.1773406907411, 63.3546813814822,
66.4912298720281, 72.1002963174962, 77.649309469458, 29.0963054665561,
38.6260575252066, 44.2351239706747, 53.7648760293253, 31.5087701279719,
24.3314294372308, 21.9189647758150, 68.9036945334439, 26.2543850639859,
43.7456149360141, 52.4912298720281, 20.6453186185178, 45.313889181287,
29.7830021158501, 33.0396571934088, 17.9008386892901, 42.5694092520593,
27.4305907479407, 49.3546813814822, 40.6090664454681, 24.2940422573947,
36.9603428065912), .Dim = c(14L, 2L))
y <- structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L,
1L), .Label = c("-1", "1"), class = "factor")
a <- svm(x, y, scale = FALSE, type = 'C-classification', kernel = 'linear', cost = 50000)
w <- t(a$coefs) %*% a$SV;
b <- -a$rho;
obj_func_str1 <- get_obj_func_info(w, b, 50000, x, y)
obj_func_str2 <- get_obj_func_info(w, b - 5, 50000, x, y)
Jawaban:
Dalam libsvm FAQ disebutkan bahwa label yang digunakan "di dalam" algoritma dapat berbeda dari milik Anda. Ini terkadang akan membalikkan tanda "coefs" dari model.
Lihat pertanyaan "Mengapa tanda label yang diprediksi dan nilai keputusan terkadang dibalik?" di sini .
sumber
Saya mengalami masalah yang sama menggunakan LIBSVM di MATLAB. Untuk mengujinya, saya membuat set data 2D yang dapat dipisah secara linear yang sangat sederhana yang kebetulan diterjemahkan sepanjang satu sumbu hingga sekitar -100. Melatih svm linier menggunakan LIBSVM menghasilkan hyperplane yang intersepnya masih tepat di sekitar nol (dan tingkat kesalahannya adalah 50%, secara alami). Membakukan data (mengurangi rata-rata) membantu, meskipun svm yang dihasilkan masih tidak berkinerja sempurna ... membingungkan. Sepertinya LIBSVM hanya memutar hyperplane tentang sumbu tanpa menerjemahkannya. Mungkin Anda harus mencoba mengurangi mean dari data Anda, tetapi tampaknya aneh bahwa LIBSVM akan berperilaku seperti ini. Mungkin kita kehilangan sesuatu.
Untuk apa nilainya, fungsi MATLAB bawaan
svmtrain
menghasilkan classifier dengan akurasi 100%, tanpa standarisasi.sumber