来自e1071的svm会产生错误的结果

时间:2016-05-11 11:42:27

标签: r svm

我正在尝试使用svm中的e1071,在使用大量数据时,我打算使用玩具示例。

这就是我在做什么,而且我不明白为什么它显然不起作用。

# generate some silly 2D data
X = data.frame(x1 = runif(10), x2 = runif(10))
# attach a label according to position above/below diagonal x+y=1
X$y <- rep(1, 10)
X$y[(X$x1 + X$x2)<1] = -1
X$y <- factor(X$y)
# train svm model
require(e1071)
meta <- svm(y~., data = X, kernel = "linear", scale = FALSE)
# visualize the result
plot(meta, X)

plot.svm

所以从这一点开始,图形误差已经可见,因为存在一些错误分类的点,而且分类器不是我期望的(所有向量都是支持)。

如果我想预测,那也是错误的:

predict(meta, newdata = X[,-3])==X$y
[1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE

如果我想进行手动预测,我也无法正常工作:

omega <- t(meta$coefs)%*%meta$SV
pred <- c(-sign(omega%*%t(X[,-3]) - meta$rho))
pred==X$y
 [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE

我确定我遗失了一些东西,但无法弄清楚是什么!

1 个答案:

答案 0 :(得分:2)

我认为这里有两个不同的问题,你的模型和你的情节。该模型很容易解决,但情节更加混乱。

支持向量太多,预测不正确

SVM通常适用于缩放输入(均值= 0,sd = 1)。请参阅this explanation of why SVM takes scaled inputs

您可以先使用基础R scale功能缩放输入,也可以在调用scale=TRUE时设置svm。我建议手动缩放,以便更好地控制:

X <- as.data.frame(scale(data.frame(x1 = runif(10), x2 = runif(10))))
X$y <- rep(1, 10)
X$y[(X$x1 + X$x2)<0] <- -1
X$y <- factor(X$y)
require(e1071)
meta <- svm(y~., data = X, kernel = "linear")

您现在应该拥有合理数量的支持向量:

meta

  Call:
  svm(formula = y ~ ., data = X, kernel = "linear")


  Parameters:
     SVM-Type:  C-classification 
   SVM-Kernel:  linear 
         cost:  1 
        gamma:  0.5 

  Number of Support Vectors:  4

预测现在也应该是完美的:

predict(meta, newdata = X[,-3])==X$y
 [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

绘制SVM

当我绘制SVM时,我仍然遇到与你相同的问题:几个“x”和“o”标签位于决策边界的错误一侧。

然而,如果我使用ggplot手动绘制它,结果看起来是正确的:

plotgrid <- expand.grid(seq(-2, 2, 0.1), seq(-2, 2, 0.1))
names(plotgrid) <- c("x1", "x2")
plotgrid$y <- predict(meta, newdata=plotgrid)
library(ggplot2)
ggplot(plotgrid) +
    geom_point(aes(x1, x2, colour=y)) +
    geom_text(data=X, aes(x1, x2, label=ifelse(y==-1, "O", "X"))) +
    ggtitle("Manual SVM Plot")

Manual SVM Plot

所以至少我们知道底层的SVM模型是正确的。实际上,plot.svm正确绘制了决策边界(您可以通过在ggplot调用中交换x1和x2轴来确认这一点,以匹配plot.svm默认使用的轴标签)

问题似乎是plot.svm错误地标记了这些点。我不知道为什么。如果有人知道,请发表评论,我会更新这个答案。与此同时,我希望ggplot解决方法就足够了。