rkernelsvmkernlab

How to customize a kernel function in ksvm of kernlab package?


I have latitudes and longitudes, so I need to redefine the RBF kernel into exp(-1/2||sophere distrance||^2), which means I need to rewrite a kernel function myself. I write my kernel as follows:

round.kernel <- function(x,y){
  sigma <- 1
  #R <- 6371
  R <- 1
  a <- (sin( (x[1]-y[1])/2 ))^2+cos(x[1])*cos(y[1])*(sin((x[2]-y[2])/2))^2
  c <- 2*atan2(sqrt(a),sqrt(1-a))
  d <- R*c
  res <- exp(-d^2/(2*sigma))
  return (res)
}
class(round.kernel) <- "kernel"

I tested the function, the kernel should be correct. But with the following training command I am getting the error:

fit <- ksvm(y=train[,2],x=train[,3:4],kernel=round.kernel,type='eps-svr')

Error in .local(x, ...) : 
  List interface supports only the stringdot kernel.

The more trickly thing is, I tried the sample code in ksvm document:

k <- function(x,y) {(sum(x*y) +1)*exp(-0.001*sum((x-y)^2))}
class(k) <- "kernel"

But I am getting the same error.

Anyone knows how to correctly define a kernel function?


Solution

  • My problem is solved as follows: the kernel codes are correct, I should directly define a function(x,y), and declare its class as "kernel". The problem is even in the doc the ksvm does support x,y styles, they actually do not work. Changing it to formula-data style can finally get things running:

    fit <- ksvm(Freq~lat+lon,data=train[,2:4],kernel=roundrbf,type='eps-svr')
    

    Moreover, I also read the source code of rbfdot, and other kernels defined in the kernlab itself. Notice their codes style is like this:

    function(params){
      val <- function(x,y){
      # True kernel defined here
      }
      return (new ("kernel_name",.Data=val,kpar=list(params)))
    }
    

    But seriously, I tried, and making the kernel functions in this style won't work. The working way is like this style directly:

    k <- function(x,y){
      #calculate the result
    }
    class(k) <- "kernel"