R: e1071 svm函数 – 是否需要将分类变量转换为虚拟变量?

我知道svm模型需要预处理,将分类变量转换为虚拟变量。然而,当我使用e1071包中的svm函数来拟合未转换数据的模型时(见traintest),没有出现错误。我假设该函数会自动进行转换。

然而,当我使用已转换的数据(见train2test2)来拟合svm模型时,该函数给我不同的结果(如所示,p1p2并不相同)。

能否有人告诉我未转换数据发生了什么?该函数是忽略了分类变量,还是发生了其他情况?

library(e1071)library(dummies)set.seed(0)x = data.frame(matrix(rnorm(200, 10, 10), ncol = 5))   #假数值预测变量cate = factor(sample(LETTERS[1:5], 40, replace=TRUE))  #假分类变量y = rnorm(40, 50, 10)             #假响应变量data = cbind(y,cate,x)ind = sample(40, 30, replace=FALSE)train = data[ind, ]test = data[-ind, ]#未使用虚拟变量data = cbind(y,cate,x)svm.model = svm(y~., train)p1 = predict(svm.model, test)#使用虚拟变量train2 = cbind(train[,-2], dummy(train[,2]))colnames(train2) = c('y', paste0('X',1:5), LETTERS[1:4])test2 = cbind(test[,-2], dummy(test[,2]))colnames(test2) = c('y', paste0('X',1:5), LETTERS[1:4])svm.model2 = svm(y~., train2)p2 = predict(svm.model2, test2)

回答:

你观察到的现象确实如你所说,虚拟变量是自动转换的。实际上,我们可以很容易地重现svm.model1svm.model2

mf <- model.frame(y ~ . - 1, train) # - 1 因为svm中不使用截距项mt <- terms(mf)X <- model.matrix(mt, mf)Xtest <- model.matrix(mt, test)Y <- model.response(mf)svm.model3 <- svm(X, Y)

请注意,我没有使用svm(formula, data),而是使用了svm(x, y)。那么我们到底重建了哪个模型?让我们与p1p2进行比较

all.equal(p1, predict(svm.model3, newdata = Xtest))# [1] "Mean relative difference: 0.03064692"all.equal(p2, predict(svm.model3, newdata = Xtest))# [1] TRUE

看起来我们重建了模型2,使用了手动创建的虚拟变量。现在,为什么这会重现svm.model2而不是svm.model1,原因在于scale参数。从help(svm)中(注意加粗部分)

一个逻辑向量,表示需要缩放的变量。如果scale长度为1,该值将根据需要重复使用。默认情况下,数据(x和y变量)在内部进行缩放,以达到零均值和单位方差。中心和缩放值将被返回并用于后续的预测。

从中我们可以看出,可能的差异(以及问题所在)来自于svm无法正确识别二进制列为虚拟变量,但显然在执行自动转换时足够聪明。我们可以通过手动设置scale参数来测试这一理论

#labels(mt) = 'cate', 'X1', 'X2', ... #names(attr(X, 'constrasts')) = 'cate' #例如:scale = 除'cate'之外的任何值not_dummies <- !(labels(mt) %in% names(attr(X, 'contrasts')))n <- table(attr(X, 'assign'))scale <- rep(not_dummies, n)svm.model4 <- svm(X, Y, scale = scale)all.equal(p1, predict(svm.model4, newdata = Xtest))# [1] TRUEall.equal(p2, predict(svm.model4, newdata = Xtest))# [1] "Mean relative difference: 0.03124989"

所以我们看到的是,

1) 如前所述,svm会自动将因子转换为虚拟变量。

2) 然而,如果提供了虚拟变量,它并不会检查这些变量,这可能会导致手动创建这些变量时出现意外的行为。

Related Posts

神经网络反向传播代码不工作

我需要编写一个简单的由1个输出节点、1个包含3个节点的…

值错误:y 包含先前未见过的标签:

我使用了 决策树分类器,我想将我的 输入 作为 字符串…

使用不平衡数据集进行特征选择时遇到的问题

我正在使用不平衡数据集(54:38:7%)进行特征选择…

广义随机森林/因果森林在Python上的应用

我在寻找Python上的广义随机森林/因果森林算法,但…

如何用PyTorch仅用标量损失来训练神经网络?

假设我们有一个神经网络,我们希望它能根据输入预测三个值…

什么是RNN中间隐藏状态的良好用途?

我已经以三种不同的方式使用了RNN/LSTM: 多对多…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注