Kernlab kraziness:相同问题的不一致结果
Kernlab kraziness: inconsistent results for identical problems
我在 kernlab 包中发现了一些令人费解的行为:估计数学上相同的 SVM 在软件中会产生不同的结果。
为了简单起见,此代码片段仅获取鸢尾花数据并使其成为二元分类问题。如您所见,我在两个 SVM 中都使用了线性内核。
library(kernlab)
library(e1071)
data(iris)
x <- as.matrix(iris[, 1:4])
y <- as.factor(ifelse(iris[, 5] == 'versicolor', 1, -1))
C <- 5.278031643091578
svm1 <- ksvm(x = x, y = y, scaled = FALSE, kernel = 'vanilladot', C = C)
K <- kernelMatrix(vanilladot(), x)
svm2 <- ksvm(x = K, y = y, C = C, kernel = 'matrix')
svm3 <- svm(x = x, y = y, scale = FALSE, kernel = 'linear', cost = C)
然而,svm1 和 svm2 的摘要信息显着 不同:kernlab 报告完全不同的支持向量计数、训练错误率和 objective 函数值之间两个模型。
> svm1
Support Vector Machine object of class "ksvm"
SV type: C-svc (classification)
parameter : cost C = 5.27803164309158
Linear (vanilla) kernel function.
Number of Support Vectors : 89
Objective Function Value : -445.7911
Training error : 0.26
> svm2
Support Vector Machine object of class "ksvm"
SV type: C-svc (classification)
parameter : cost C = 5.27803164309158
[1] " Kernel matrix used as input."
Number of Support Vectors : 59
Objective Function Value : -292.692
Training error : 0.333333
为了比较,我还使用 e1071 计算了相同的模型,它为 libsvm 包提供了 R 接口。
svm3
Call:
svm.default(x = x, y = y, scale = FALSE, kernel = "linear", cost = C)
Parameters:
SVM-Type: C-classification
SVM-Kernel: linear
cost: 5.278032
gamma: 0.25
Number of Support Vectors: 89
It reports 89 support vectors, the same as svm1.
我的问题是 kernlab 包中是否有任何已知错误可以解释这种异常行为。
(R 的 Kernlab 是一种 SVM 求解器,它允许使用几个预先打包的内核函数之一,或用户提供的内核矩阵。输出是对用户提供的支持向量机的估计超参数。)
查看部分代码,发现这是有问题的行:
https://github.com/cran/kernlab/blob/efd7d91521b439a993efb49cf8e71b57fae5fc5a/src/svm.cpp#L4205
也就是说,在用户提供的内核矩阵的情况下,ksvm
只是查看二维,而不是输入的维度。这看起来很奇怪,可能是某些测试或其他原因的延期。仅使用二维数据对线性内核进行测试会产生相同的结果:将上面的 1:4
替换为 1:2
并且输出和预测都一致。
我在 kernlab 包中发现了一些令人费解的行为:估计数学上相同的 SVM 在软件中会产生不同的结果。
为了简单起见,此代码片段仅获取鸢尾花数据并使其成为二元分类问题。如您所见,我在两个 SVM 中都使用了线性内核。
library(kernlab)
library(e1071)
data(iris)
x <- as.matrix(iris[, 1:4])
y <- as.factor(ifelse(iris[, 5] == 'versicolor', 1, -1))
C <- 5.278031643091578
svm1 <- ksvm(x = x, y = y, scaled = FALSE, kernel = 'vanilladot', C = C)
K <- kernelMatrix(vanilladot(), x)
svm2 <- ksvm(x = K, y = y, C = C, kernel = 'matrix')
svm3 <- svm(x = x, y = y, scale = FALSE, kernel = 'linear', cost = C)
然而,svm1 和 svm2 的摘要信息显着 不同:kernlab 报告完全不同的支持向量计数、训练错误率和 objective 函数值之间两个模型。
> svm1
Support Vector Machine object of class "ksvm"
SV type: C-svc (classification)
parameter : cost C = 5.27803164309158
Linear (vanilla) kernel function.
Number of Support Vectors : 89
Objective Function Value : -445.7911
Training error : 0.26
> svm2
Support Vector Machine object of class "ksvm"
SV type: C-svc (classification)
parameter : cost C = 5.27803164309158
[1] " Kernel matrix used as input."
Number of Support Vectors : 59
Objective Function Value : -292.692
Training error : 0.333333
为了比较,我还使用 e1071 计算了相同的模型,它为 libsvm 包提供了 R 接口。
svm3
Call:
svm.default(x = x, y = y, scale = FALSE, kernel = "linear", cost = C)
Parameters:
SVM-Type: C-classification
SVM-Kernel: linear
cost: 5.278032
gamma: 0.25
Number of Support Vectors: 89
It reports 89 support vectors, the same as svm1.
我的问题是 kernlab 包中是否有任何已知错误可以解释这种异常行为。
(R 的 Kernlab 是一种 SVM 求解器,它允许使用几个预先打包的内核函数之一,或用户提供的内核矩阵。输出是对用户提供的支持向量机的估计超参数。)
查看部分代码,发现这是有问题的行:
https://github.com/cran/kernlab/blob/efd7d91521b439a993efb49cf8e71b57fae5fc5a/src/svm.cpp#L4205
也就是说,在用户提供的内核矩阵的情况下,ksvm
只是查看二维,而不是输入的维度。这看起来很奇怪,可能是某些测试或其他原因的延期。仅使用二维数据对线性内核进行测试会产生相同的结果:将上面的 1:4
替换为 1:2
并且输出和预测都一致。