Вычисление матрицы ядра вне обучения SVM в Kernlab

Я разрабатывал новый алгоритм, который генерирует модифицированную матрицу ядра для обучения с SVM, и столкнулся со странной проблемой.

В целях тестирования я сравнивал модели SVM, изученные с использованием интерфейса kernelMatrix и обычного интерфейса ядра. Например,

# Model with kernelMatrix computation within ksvm
svp1 <- ksvm(x, y, type="C-svc", kernel=vanilladot(), scaled=F)
# Model with kernelMatrix computed outside ksvm
K <- kernelMatrix(vanilladot(), x)
svp2 <- ksvm(K, y, type="C-svc")
identical(nSV(svp1), nSV(svp2))

Обратите внимание, что я отключил масштабирование, так как я не уверен, как выполнить масштабирование для матрицы ядра.

Из моего понимания как svp1 а также svp2 должен вернуть ту же модель. Однако я заметил, что это не относится к нескольким наборам данных, например glass0 от КИЛ.

Что мне здесь не хватает?

1 ответ

Решение

Я думаю, что это связано с тем же вопросом, опубликованным здесь. Kernlab, по-видимому, по-разному относится к вычислению ksvm, когда явно использует vanilladot(), потому что его класс - vanillakernel, а не kernel.

если вы определите свое собственное ядро ​​vanilladot с классом 'kernel' вместо 'vanillakernel', код будет эквивалентен для обоих:

kfunction.k <- function(){
   k <- function (x,y){crossprod(x,y)}
   class(k) <- "kernel"
   k}
l<-0.1 ; C<-1/(2*l)

svp1 <- ksvm(x, y, type="C-svc", kernel=kfunction.k(), scaled=F)

K <- kernelMatrix(kfunction.k(),x)

svp2 <- ksvm(K, y, type="C-svc", kernel='matrix', scaled=F)

identical(nSV(svp1), nSV(svp2))

Стоит отметить, что svp1 и svp2 оба отличаются от их значений в исходном коде из-за этого изменения.

Другие вопросы по тегам