Вычисление матрицы ядра вне обучения 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 оба отличаются от их значений в исходном коде из-за этого изменения.