使用 e1071 和插入符号的 SVM 模型的结果截然不同

Posted

技术标签:

【中文标题】使用 e1071 和插入符号的 SVM 模型的结果截然不同【英文标题】:Vastly different results for SVM model using e1071 and caret 【发布时间】:2013-09-25 12:30:32 【问题描述】:

我正在对我的数据使用两个不同的包来训练两个 SVM 模型,并得到截然不同的结果。这是意料之中的事情吗?

model1 使用 e1071

library('e1071')
model1 <- svm(myFormula, data=trainset,type='C',kernel='linear',probability = TRUE)
outTrain <- predict(model1, trainset, probability = TRUE)
outTest <- predict(model1, testset, probability = TRUE)
train_pred <- attr(outTrain, "probabilities")[,2]
test_pred <- attr(outTest, "probabilities")[,2]
calculateAUC(train_pred,trainTarget)
calculateAUC(test_pred,testTarget)

model2 使用插入符号

model2 <- train(myFormula,data=trainset,method='svmLinear')
train_pred <- predict(model2, trainset)
test_pred  <- predict(model2, testset)
calculateAUC(train_pred,trainTarget)
calculateAUC(test_pred,testTarget)

calculateAUC() 是我定义的一个函数,用于计算 AUC 值,给定目标的预测值和实际值。 我将这些值视为:

模型1 (e1071)

1 0.8567979

model2(插入符号)

0.9910193 0.758201

这是可能的吗?还是我做错了?

如果有帮助,我可以提供示例数据

【问题讨论】:

【参考方案1】:

是的,有可能,例如:

不同的C值,在e1071默认值为1,也许caret使用其他? 数据缩放,e1071 默认缩放您的输入,插入符号默认不缩放(尽管 kernlab 的 svm 可以缩放,而且它是“幕后”模型,因此需要进行源检查才能确定)李> 不同的eps/maxiteration或其他优化相关阈值

学习后简单显示模型参数并检查它们是否相同,您可能会发现这两个库之间默认情况下有些参数不同。

【讨论】:

我确实打印了模型并检查了这些: >两者中的 C 值都是 1。 > 我的变量已经缩放。优化阈值可能不同 规模如何? e1071 将维度归一化为均值 = 0 和方差 = 1,而不是通过简单的线性压缩到 [0,1],因此缩放 很重要。尝试手动关闭两者的缩放。 caret 使用kernlab。尝试打印出model2$finalModel 以查看有什么区别和/或在e1071kernlab 中安装相同的模型以进行检查。 另外,您的train 代码必须比这更复杂。 caret 的最新版本不会自动生成类概率,并且上面缺少 trainControl 以及 predict, type = "prob")。另外,calculateAUC 是从哪里来的?您应该提供一个可重现的示例和sessoinInfo() 的结果。【参考方案2】:

我观察到 kernlab 使用 rbfkernel 作为,

rbf(x,y) = exp(-sigma * euclideanNorm(x-y)^2)

但是根据这个wiki link,rbf内核应该是

rbf(x,y) = exp(-euclideanNorm(x-y)^2/(2*sigma^2))

这也更直观,因为两个具有较大 sigma 值的接近样本会导致更高的相似度匹配。

我不确定e1071 svm 使用什么(本机代码 libsvm?)

我知道这是一个旧线程,但希望有人能告诉我为什么会有区别? 一个比较小的例子

set.seed(123)
x <- rnorm(3)
y <- rnorm(3)
sigma <- 100

rbf <- rbfdot(sigma=sigma)
rbf(x, y)
exp( -sum((x-y)^2)/(2*sigma^2) )

我希望内核值接近 1(因为 x,y 来自 sigma=1,而内核 sigma=100)。这仅在第二种情况下观察到。

【讨论】:

【参考方案3】:

首先请注意svmLinear 依赖于kernlab。您可以直接使用caret 中的e1071,只需将svmLinear 参数替换为svmLinear2(请参阅模型的详细列表以及它们所依赖的库in the docs)。

现在,请注意,如果您向它们传递正确的参数,这两个库会产生相同的结果。我最近benchmarked these methods 并注意到传递以下参数可确保相同的结果:

model_kernlab <-
  kernlab::ksvm(
      x = X,
      y = Y,
      scaled = TRUE,
      C = 5,
      kernel = "rbfdot",
      kpar = list(sigma = 1),
      type = "eps-svr",
      epsilon = 0.1
      )

model_e1071 <- e1071::svm(x = X,
      y = Y,
      cost = 5,
      scale = TRUE, 
      kernel = "radial",
      gamma = 1,
      type = "eps-regression",
      epsilon = 0.1)

注意不同的名称: - C /成本 - 西格玛/伽玛 - 每股收益/ε - rbfdot / 径向 ...

【讨论】:

以上是关于使用 e1071 和插入符号的 SVM 模型的结果截然不同的主要内容,如果未能解决你的问题,请参考以下文章

svm e1071 predict 创建的预测值数组比预期的要大

R语言e1071包中的支持向量机:螺旋线型线性不可分数据集RBF核函数支持向量机SVM(验证模型在测试集上的表现可视化模型预测的结果添加超平面区域与原始数据标签进行对比分析)

R语言使用e1071包中的svm函数构建支持向量机SVM模型使用tune.svm函数基于网格搜索(10折交叉验证)对RBF核函数的gamma参数和cost参数进行参数寻优使用最优参数构建最终模型

R语言使用e1071包中的svm函数构建支持向量机SVM模型使用tune.svm函数基于网格搜索(10折交叉验证)对RBF核函数的gamma参数和cost参数进行参数寻优使用最优参数构建最终模型

R语言e1071包中的支持向量机:仿真数据(螺旋线性不可分数据集)简单线性核的支持向量机SVM(模型在测试集上的表现可视化模型预测的结果添加超平面区域与原始数据标签进行对比分析)如何改进核函数

e1071 的基本 SVM 问题:测试错误率与 tune 的结果不匹配