rsvmr-caretkernlabmlr

R package mlr: option for custom kernels in classif.ksvm


I want to build an svm with a custom kernel. Usually I use the R package kernlab for that. Since, I want to try out different kernels and tune the hyper-parameters, I wanted to use the nice package mlr. However, as far as I can see, it doesn't support the kernel type option "matrix" to pass a custom kernel to the ksvm learner ("classif.ksvm").

Does somebody know if there is a plan to fix that? Or if there is another package which allows custom kernels and nice wrappers for tuning parameters and resampling methods. To my knowledge, the caret package is also not taking custom kernels.


Solution

  • We don't have any plans to support that. You can define a custom learner to support this quite easily though. There are two changes to classif.ksvm as far as I can see (untested).

    First, allow the new parameter value for the kernel parameter:

    makeDiscreteLearnerParam(id = "kernel", default = "rbfdot",
        values = c("vanilladot", "polydot", "rbfdot", "tanhdot", "laplacedot", "besseldot", "anovadot", "splinedot", "matrix"))
    

    Then, change the train function to take the new kernel into account:

    trainLearner.classif.ksvm = function(.learner, .task, .subset, .weights = NULL, degree, offset, scale, sigma, order, length, lambda, normalized,  ...) {
      kpar = learnerArgsToControl(list, degree, offset, scale, sigma, order, length, lambda, normalized)
      f = getTaskFormula(.task)
      pm = .learner$predict.type == "prob"
      parlist = list(...)
      if (base::length(kpar) > 0L)
        kernlab::ksvm(f, data = getTaskData(.task, .subset), kpar = kpar, prob.model = pm, ...)
      else if (parlist$kernel == "matrix")
        kernlab::ksvm(kernlab::as.kernelMatrix(getTaskData(.task, .subset)), data = getTaskData(.task, .subset), prob.model = pm, ...)
      else
        kernlab::ksvm(f, data = getTaskData(.task, .subset), prob.model = pm, ...)
    }
    

    This is assuming that the data you're passing in the task defines the custom kernel, which is a bit kludgy...