predict.svm无法预测新数据。

9

很不幸,我在以下简单示例中使用predict()时遇到了问题:

library(e1071)

x <- c(1:10)
y <- c(0,0,0,0,1,0,1,1,1,1)
test <- c(11:15)

mod <- svm(y ~ x, kernel = "linear", gamma = 1, cost = 2, type="C-classification")

predict(mod, newdata = test)

以下是结果:
> predict(mod, newdata = test)
   1    2    3    4 <NA> <NA> <NA> <NA> <NA> <NA> 
   0    0    0    0    0    1    1    1    1    1 

有人能解释一下为什么predict()只给出训练样本(x,y)的拟合值,而不关心测试数据吗?

非常感谢您的帮助!

Richard


使用 test <- c(11:25) 会出现错误 "Error in names(ret2) <- rowns : 'names' attribute [15] must be the same length as the vector [10]"。 - Richard
2个回答

11

看起来这是因为您误用了svm()的公式接口。通常,您会提供一个数据框或类似对象,在其中搜索公式中的变量。如果不这样做,通常也没关系,即使这不是最佳实践,但当您想预测时,不将变量放入数据框中会导致麻烦。它返回训练数据的原因是因为您没有向newdata提供一个名为x的组件的对象。因此,它找不到新数据x,因此返回拟合值。这对我所知道的大多数 R predict 方法都很常见。

解决方案是:i)将您的训练数据放入一个数据框中,并将其作为data参数传递给svm,ii)提供一个新的数据框,其中包含x(来自test)以用于predict()。例如:

> DF <- data.frame(x = x, y = y)
> mod <- svm(y ~ x, data = DF, kernel = "linear", gamma = 1, cost = 2,
+ type="C-classification")
> predict(mod, newdata = data.frame(x = test))
1 2 3 4 5 
1 1 1 1 1 
Levels: 0 1

6

您需要保证newdata与原数据形式相同,即使用data.frame有助于解决问题:

R> library(e1071)
Loading required package: class
R> df <- data.frame(x=1:10, y=sample(c(0,1), 10, rep=TRUE))
R> mod <- svm(y ~ x, kernel = "linear", gamma = 1, 
+             cost = 2, type="C-classification", data=df)
R> newdf <- data.frame(x=11:15)
R> predict(mod, newdata=newdf)
1 2 3 4 5
0 0 0 0 0
Levels: 0 1
R>

顺便提一下,这也展示了svm()的帮助页面:

 ## density-estimation

 # create 2-dim. normal with rho=0:
 X <- data.frame(a = rnorm(1000), b = rnorm(1000))
 attach(X)

 # traditional way:
 m <- svm(X, gamma = 0.1)

 # formula interface:
 m <- svm(~., data = X, gamma = 0.1)
 # or:
 m <- svm(~ a + b, gamma = 0.1)

 # test:
 newdata <- data.frame(a = c(0, 4), b = c(0, 4))
 predict (m, newdata)

因此,总的来说,在R中使用公式接口并提供数据框 --- 这就是基本上所有建模函数的工作方式。

你为什么要为线性SVM定义一个gamma参数?这是在e1071中线性SVM的标准做法吗?我只看到过RBF SVMs使用这个参数。 - Jack Armstrong
我将去找我的时间机器询问我年轻时为什么会在九年前写下那个东西,但从上下文来看,我只是引用了帮助页面,这个页面可能已经发生了变化。 - Dirk Eddelbuettel
我没意识到已经九年了,抱歉。我看到用户也使用了gamma。我只是好奇,因为我的问题是为什么我们通常要为线性SVM定义gamma。 - Jack Armstrong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接