4

在使用caret. 在不进行调整的情况下训练单个模型时,具有径向基核的 SVM 比具有线性核的 SVM 花费更多时间,这是意料之中的。然而,当在相同的惩罚网格上调整两个内核的 SVM 时,具有线性内核的 SVM 比具有径向基内核的 SVM 花费的时间要多得多。这种行为可以很容易地在 Windows 和 Linux 的 R 3.2 和caret6.0-47 中重现。有谁知道为什么调整线性 SVM 比径向基内核 SVM 需要更多时间?

SVM linear
   user  system elapsed 
   0.51    0.00    0.52 

SVM radial
   user  system elapsed 
   0.85    0.00    0.84 

SVM linear tuning
   user  system elapsed 
 129.98    0.02  130.08 

SVM radial tuning
   user  system elapsed 
   2.44    0.05    2.48 

玩具示例代码如下:

library(data.table)
library(kernlab)
library(caret)

n <- 1000
p <- 10

dat <- data.table(y = as.factor(sample(c('p', 'n'), n, replace = T)))
dat[, (paste0('x', 1:p)) := lapply(1:p, function(x) rnorm(n, 0, 1))]
dat <- as.data.frame(dat)

sigmas <- sigest(as.matrix(dat[, -1]), na.action = na.omit, scaled = TRUE)
sigma  <- mean(as.vector(sigmas[-2]))

cat('\nSVM linear\n')
print(system.time(fit1 <- train(y ~ ., data = dat, method = 'svmLinear', tuneLength = 1,
                                 trControl = trainControl(method = 'cv', number = 3))))

cat('\nSVM radial\n')
print(system.time(fit2 <- train(y ~ ., data = dat, method = 'svmRadial', tuneLength = 1,
                                 trControl = trainControl(method = 'cv', number = 3))))

cat('\nSVM linear tuning\n')
print(system.time(fit3 <- train(y ~ ., data = dat, method = 'svmLinear',
                                 tuneGrid = expand.grid(C = 2 ^ seq(-5, 15, 5)),
                                 trControl = trainControl(method = 'cv', number = 3))))

cat('\nSVM radial tuning\n')
print(system.time(fit4 <- train(y ~ ., data = dat, method = 'svmRadial',
                                 tuneGrid = expand.grid(C = 2 ^ seq(-5, 15, 5), sigma = sigma),
                                 trControl = trainControl(method = 'cv', number = 3))))
4

2 回答 2

3

看过之后,我认为问题不在于caret,而是在于幕后(背后)发生的事情kernlab
正如其他地方所说的堆栈溢出SVM本身是一个密集的算法。的时间复杂度SVM为 O(n*n)。SVM现在这并没有考虑到调用之间的差异。似乎正在发生的事情是在通过一个非常深的堆栈调用已编译的 C 代码之后SVM > .Local > .call..call调用已编译的 C 代码并且超出我的知识库)。R大多数情况下,您会看到意想不到的缓慢时间从C这是因为事情是如何传递的。由于您拉入矩阵,这有助于进一步假设命名或尺寸问题导致另一端的一些额外工作。
如果我们看看这段代码是如何分析的,瓶颈就会变得非常清楚。

对字体大小表示歉意——它的堆栈很深,我认为整体形状比单个功能更能说明问题。随意在下面发送垃圾邮件 Ctrl +。

nSVM_linear看起来像一个健康的配置文件和许多友好的 R 函数。

nSVM_linear

同样的交易nSVM radial

在此处输入图像描述

现在,一旦我们从“径向调整”开始,我们就会开始看到更平坦的结构,try-call堆栈开始倾斜,但一切似乎都在快速执行。

在此处输入图像描述

哇。C在某些情况下,线性调优​​调用需要超过 100 秒的完全不同的结构。

在此处输入图像描述

话虽如此,看起来您的瓶颈在于C来自kernlab. 由于包正在连接到libsvm似乎非常有效的包,我无法想象被调用的代码存在实际问题。实际上识别如何(基于安全的功能或来自 R 的输入问题)以及为什么在从一个移动到另一个时会发生问题对于比我更好的人来说是一项工作。

于 2015-05-22T03:23:51.630 回答
0

svmRadial我在 Linux 上遇到了非常糟糕的性能。事实证明,问题在于使用 multicore DoMCsvmRadial在单核上运行良好。这些函数是我见过kernlab的唯一表现出这种行为的函数。除了其他人提到的问题之外caret,还要添加一个问题。kernlab

于 2016-06-19T11:20:02.907 回答