使用e1071替代kernlab在caret中用R语言实现SVM

3

目前caret列车在内部使用kernlab svm功能,但对于我的当前目的来说速度较慢。但是e1071 svm训练器提供了所需的速度提升。因此,我想使用e1071的svm训练器来进行caret的cv过程。有没有办法做到这一点?基本上,我希望caret的svm引擎被默认的kernlab替换为e1071。

我目前使用以下代码进行培训。

svm使用kernlab

svmModel2 = train(factor(TopPick) ~. - Date , data = trainSet, method = 'svmRadial')
pred.svm2 = predict(svmModel2, testSet)

使用e1071进行支持向量机

svmModel = e1071::svm(factor(TopPick) ~ . - Date, data = trainSet)
pred.svm = predict(svmModel, testSet)

感谢您的帮助。

1
我没有尝试过这个,但看起来你可以使用caret的设施来定义一个自定义模型,从而在caret中使用e1071svm函数。 - eipi10
谢谢,我会尝试使用它。 - Frash
1个回答

3

如评论中建议的,您可以创建自己的自定义模型。

svmRadial2ModelInfo <- list(
  label   = "Support Vector Machines with Radial Kernel based on libsvm",
  library = "e1071",
  type    = c("Regression", "Classification"),
  parameters = data.frame(parameter = c("cost", "gamma"),
                          class = c("numeric", "numeric"),
                          label = c("Cost", "Gamma")),
  grid    = function(x, y, len = NULL, search = NULL) {
              sigmas <- kernlab::sigest(as.matrix(x), na.action = na.omit, scaled = TRUE)
              return( expand.grid(gamma = mean(as.vector(sigmas[-2])),
                                  cost  = 2 ^((1:len) - 3)) )
  },
  loop    = NULL,
  fit     = function(x, y, wts, param, lev, last, classProbs, ...) {
              if(any(names(list(...)) == "probability") | is.numeric(y))
              {
                out <- svm(x = as.matrix(x), y = y,
                           kernel = "radial",
                           cost  = param$cost,
                           gamma = param$gamma,
                           ...)
              } else {
                out <- svm(x = as.matrix(x), y = y,
                           kernel = "radial",
                           cost  = param$cost,
                           gamma = param$gamma,
                           probability = classProbs,
                           ...)
              }
              out
  },
  predict = function(modelFit, newdata, submodels = NULL) {
    predict(modelFit, newdata)
  },
  prob    = function(modelFit, newdata, submodels = NULL) {
    out <- predict(modelFit, newdata, probability = TRUE)
    attr(out, "probabilities")
  },
  varImp = NULL,
  predictors = function(x, ...){
    out <- if(!is.null(x$terms)) predictors.terms(x$terms) else x$xNames
    if(is.null(out)) out <- names(attr(x, "scaling")$x.scale$`scaled:center`)
    if(is.null(out)) out <-NA
    out
  },
  levels = function(x) x$levels,
  sort   = function(x) x[order(x$cost, -x$gamma),]
)

使用方法:

svmR <- caret::train(x = trainingSet$x,
                     y = trainingSet$y,
                     trControl = caret::trainControl(number=10),
                     method = svmRadial2ModelInfo,
                     tuneLength = 3)

为什么你还在这里使用kernlab而不是e1071来估计sigma?grid = function(x, y, len = NULL, search = NULL) { sigmas <- kernlab::sigest(as.matrix(x), na.action = na.omit, scaled = TRUE) return( expand.grid(gamma = mean(as.vector(sigmas[-2])), cost = 2 ^((1:len) - 3)) ) - Kashif

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接