我正在尝试从一组代表多于另一组的训练数据构建一个 SVM。但是,这些组将在最终的测试数据中得到同等的代表。因此,我想使用R包接口的class.weights参数来平衡两组在训练数据中的影响。e1071libsvm
由于我不确定应该如何指定这些权重,所以我设置了一个小测试:
- 生成一些空数据(随机特征;组标签之间的比例为 2:1)
class.weights用参数集拟合 svm 。- 预测一堆新的空数据集并查看类比例。
- 针对不同的空训练集多次复制整个过程。
这是我正在使用的 R 代码:
nullSVM <- function(n.var, n.obs) {
# Simulate null training data
vars = matrix(rnorm(n.var*n.obs), nrow=n.obs)
labels = rep(c('a', 'a', 'b'), length.out=n.obs)
data = data.frame(group=labels, vars)
# Fit SVM
fit = svm(group ~ ., data=data, class.weights=c(a=0.5, b=1))
# Calculate the average fraction of 'a' we would predict from null test data
mean(replicate(50, table(predict(fit, data.frame(matrix(rnorm(n.var*n.obs), nrow=n.obs))))[1])) / n.obs
}
library(e1071)
set.seed(12345)
mean(replicate(50, nullSVM(50, 300)))
从这整件事中,我期望输出 ~ 0.5,但是,这不是我得到的:
> mean(replicate(50, nullSVM(50, 300)))
[1] 0.6429987
该class.weights参数起作用,有点像,因为 I weighta越低,它在此模拟中表示的越低(如果我省略class.weights它返回接近 1)......但我不明白为什么只使用 1:2 的权重(对于 2:1 的训练数据)并没有让我一路下降到 50%。
如果我误解了 SVM,有人可以解释这一点吗?(或发送一些参考?)
如果我做错了,有人可以告诉我使用class.weights参数的正确方法吗?
它可能是一个错误吗?(我认为不会,因为我理解这个软件和底层的 libsvm 已经相当成熟了)