如何在kernlab包的ksvm中自定义内核函数?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在kernlab包的ksvm中自定义内核函数?相关的知识,希望对你有一定的参考价值。

我有纬度和经度,所以我需要将RBF内核重新定义为exp(-1/2 || sophere distrance || ^ 2),这意味着我需要自己重写一个内核函数。我按如下方式编写内核:

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"

我测试了这个函数,内核应该是正确的。但是通过以下训练命令,我收到错误:

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.

更棘手的是,我在ksvm文档中尝试了示例代码:

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

但我得到了同样的错误。

任何人都知道如何正确定义内核函数?

答案

我的问题解决如下:内核代码是正确的,我应该直接定义一个函数(x,y),并将其类声明为“内核”。问题是即使在ksvm支持x,y样式的文档中,它们实际上也不起作用。将其更改为公式数据样式最终可以使事情运行:

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

此外,我还阅读了rbfdot的源代码,以及kernlab本身定义的其他内核。注意他们的代码样式是这样的:

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

但是说真的,我试过,用这种风格制作内核函数是行不通的。工作方式直接就像这种风格:

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

以上是关于如何在kernlab包的ksvm中自定义内核函数?的主要内容,如果未能解决你的问题,请参考以下文章

R:使用自定义内核(用户定义内核)的 SVM 性能在 kernlab 中不起作用

在内核k-means(R中的kernlab包)中将新数据点分配给集群?

在kernlab中的SVM训练之外的内核矩阵计算

带有 Kernlab 的内核 PCA 和结肠癌数据集的分类

scikit-learn 中自定义内核 SVM 的交叉验证

在 R 中绘制由 caret 包训练的 SVM 线性模型