繁体   English   中英

R: e1071 svm function - 是否有必要将分类转换为假人?

[英]R: e1071 svm function - is it necessary to convert categorical to dummies?

我知道svm model 需要将分类变量转换为虚拟变量的预处理。 但是,当我使用e1071svm function 来拟合带有未转换数据的 model 时(请参阅traintest ),不会弹出错误。 我假设 function 会自动转换它们。

但是,当我使用转换后的数据(参见train2test2 )来拟合 svm model 时,这个 function 给了我不同的结果(如所示, p1p2不相同)。

谁能告诉我未转换的数据发生了什么? function 是否只是忽略了分类变量,还是发生了其他事情?

library(e1071)
library(dummies)

set.seed(0)
x = data.frame(matrix(rnorm(200, 10, 10), ncol = 5))   #fake numerical predictors
cate = factor(sample(LETTERS[1:5], 40, replace=TRUE))  #fake categorical variables
y = rnorm(40, 50, 10)             #fake response

data = cbind(y,cate,x)
ind = sample(40, 30, replace=FALSE)
train = data[ind, ]
test = data[-ind, ]

#without dummy 
data = cbind(y,cate,x)
svm.model = svm(y~., train)
p1 = predict(svm.model, test)

#with dummy
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)

从文档中可以清楚地看出,它的处理方式至少略有不同,因此评论“如果预测变量包含因子,则必须使用公式接口来获得正确的 model 矩阵。 ”。

个人预感差异与缩放有关( svm中的默认值)。 注意两者之间的区别...

> svm.model$x.scale$`scaled:center`
       X1        X2        X3        X4        X5 
10.091157  8.739654 10.395121  7.856475 11.660454 
> svm.model2$x.scale$`scaled:center`
        X1         X2         X3         X4         X5          A          B          C          D      X.NA. 
10.0911569  8.7396541 10.3951208  7.8564754 11.6604540  0.2000000  0.1333333  0.1333333  0.2333333  0.3000000 

您所观察到的确实如您所说,假人是自动转换的。 事实上,我们可以很容易地重现svm.model1svm.model2

mf <- model.frame(y ~ . - 1, train) # - 1 because the intercept is unused in 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) 现在我们实际上重新创建了哪个 model? 让我们比较一下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

看来我们已经用我们的手动假人重新创建了 model 2。 现在复制svm.model2而不是svm.model1的原因是由于scale参数。 来自help(svm) (注意粗体部分)

指示要缩放的变量的逻辑向量。 如果 scale 的长度为 1,则该值将根据需要循环多次 默认情况下,数据在内部(x 和 y 变量)被缩放到零均值和单位方差。 返回中心值和比例值并用于以后的预测。

从这里我们可以看到,差异(和真正的问题)可能来自svm没有正确地将二进制列识别为虚拟列,但显然在执行自动转换时足够聪明地做到这一点。 我们可以通过手动设置scale参数来测试这个理论

#labels(mt) = 'cate', 'X1', 'X2', ... 
#names(attr(X, 'constrasts')) = 'cate' 
#eg: scale = Anything but '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] TRUE
all.equal(p2, predict(svm.model4, newdata = Xtest))
# [1] "Mean relative difference: 0.03124989"

所以我们看到的是

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

2) 但是,在提供假人的情况下,不检查这些,如果手动创建这些,可能会导致意外行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM