我使用以下调参代码来寻找我的SVM模型的最佳情况和epsilon值。
tuneResult <- tune( svm, labels ~ ., data = dataset, ranges = list(epsilon = seq(-5.0, 5, 0.1), cost = 2^(0:3)))
但令人惊讶的是,它建议cost = 4
和 epsilon = -5
!
然后我使用这些参数训练了模型,并用confusionMatrix
进行了测试。不幸的是,使用这些参数的模型不如没有这些参数的模型准确。
model1 <- svm(labels ~ ., data = dataset, kernel = "linear", cost = 4 , epsilon = -5)model2 <- svm(labels ~ ., data = dataset, kernel = "linear")
我是不是错过了什么?
回答:
tldr;
问题出在你的tuneResult
命令中,你允许epsilon
在[-5, +5]
范围内变化,这没有意义,因为epsilon
定义为大于等于0的值。tuneResult
返回epsilon = -5
的事实表明,在尝试找到一组最优的(超)参数时出现了收敛失败/问题。不幸的是,没有(样本)数据,很难感受到分类模型中任何(潜在的)计算挑战。
epsilon
的作用/解释
重申一下:在SVM中,epsilon
描述了容忍边界(“不敏感区”),在该边界内,分类错误不会被惩罚(你应该查看?e1071::svm
来了解epsilon
的默认值)。当epsilon
从右侧趋近于零时,所有分类错误都会被惩罚,导致支持向量的数量最大化(作为epsilon
的函数)。例如,参见这里,了解更多关于各种SVM(超)参数的解释/定义的详细信息。
超参数优化和收敛
让我们回到为什么优化收敛失败的问题:我认为问题出在试图同时优化cost
和epsilon
参数。当epsilon
越来越小时,你会越来越多地惩罚误分类(减少支持向量的数量);与此同时,通过允许更大和更大的cost
参数,你允许包括更多的支持向量来抵消小epsilon
值引起的误分类。在交叉验证过程中,这基本上会使模型趋向于越来越小的epsilon
和越来越大的cost
超参数。
一个例子
我们可以使用一些模拟数据来重现这种行为,用于SVM分类问题。
-
让我们生成一些样本数据
# Sample dataset.seed(1)x <- rbind(matrix(rnorm(10 * 2, mean = 0), ncol = 2), matrix(rnorm(10 * 2, mean = 2), ncol = 2))y <- c(rep(-1, 10), rep(1, 10))df <- data.frame(x = x, y = as.factor(y))
-
让我们同时调整epsilon和cost超参数。我们使用与你原始帖子中相同的范围,包括无意义的(即负的)epsilon值。
# tune epsilon and cost hyper-parameterslibrary(caret)tuneResult <- tune( svm, y ~ ., data = df, ranges = list(epsilon = seq(-5, 5, 0.01), cost = 2^(0:3)))##Parameter tuning of ‘svm’:##- sampling method: 10-fold cross validation##- best parameters:# epsilon cost# -5 4##- best performance: 0.1
你可以看到
epsilon
和cost
参数是如何趋向于它们各自的最小/最大极值的。