4

我正在开发一种新算法,该算法会生成一个修改过的内核矩阵,用于使用 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返回相同的模型。但是,我观察到对于一些数据集,例如glass0来自KEEL的数据集并非如此。

我在这里想念什么?

4

1 回答 1

4

我认为这与此处发布的相同问题有关。当显式使用 vanilladot() 时,kernlab 似乎以不同的方式处理 ksvm 的计算,因为它的类是“vanillakernel”而不是“kernel”。

如果您使用“kernel”类而不是“vanillakernel”类定义自己的 vanilladot 内核,则两者的代码将是等效的:

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 都与原始代码中的值不同,因为这种变化。

于 2015-09-26T23:48:25.883 回答