我正在开发一种新算法,该算法生成一个修改后的内核矩阵,用于使用SVM进行训练,并遇到一个奇怪的问题。
出于测试目的,我正在比较使用kernelMatrix接口和普通内核接口学习的SVM模型。例如,
# 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
应返回相同的模型。但是我发现这对于一些数据集来说并非如此,例如来自KEEL的glass0
。
我在这里缺少什么?
答案 0 :(得分:4)
我认为这与发布here的同一问题有关。 kernlab似乎在明确使用vanilladot()时对ksvm的计算有不同的看法,因为它的类是“vanillakernel”。而不是&#39; kernel&#39;。
如果你用一类内核定义你自己的vanilladot内核&#39;而不是&#39; vanillakernel&#39;代码对于两者都是等效的:
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都与原始代码中的值不同。