在上一篇“数据挖掘: R, Python,Machine Learning,一起学起来!”中,我们介绍了用R进行线性回归的例子。
这次我们来看看,同样一份简单的无噪声数据,用线性模型和支持向量模型分别进行回归,得出的结果是否一致。
数据我们仍然用上次的y = x + 2的那份lrdata_1.csv。要用SVR模型,我们需要安装一个新的package —— e1071。
打开R后操作如下:
> install.packages("e1071", dep = TRUE)
> library(e1071)
> mydata = read.csv(".\\lrdata_1.csv")
> x<-mydata[,1]
> y<-mydata[,2]
先用svm function进行回归,所有的参数都使用默认值:
> svm.r=svm(y~x,mydata); svm.r
Call:
svm(formula = y ~ x, data = mydata)
Parameters:
SVM-Type: eps-regression
SVM-Kernel: radial
cost: 1
gamma: 1
epsilon: 0.1
从模型输出结果我们可以看出,具体回归方法是eps-regression,核函数为radial函数。
这个模型的结果如何呢?我们来看看:
> predictedY <- predict(svm.r, mydata)
> predictedY
1 2 3 4 5 6 7
3.968246 4.273861 5.133763 6.115467 7.000000 7.884533 8.866237
8 9
9.726139 10.031754
好像和实际值差得挺远啊。我们也可以通过画图来做可视化的展示:
> plot(x,y)
> points(x,predictedY, col = "red")
图中黑点是实际值,红点是根据svm.r回归模型计算的的预测值。不难看出,红点是一条曲线,而黑点是一条直线。
我们之前用的核函数(kernel)是默认的radial函数,那如果我们把核函数换做线性核函数,是否会提高预测准确率呢?我们来试试:
> svm.r2=svm(y~x, kernel = "linear"); svm.r2
Call:
svm(formula = y ~ x, kernel = "linear")
Parameters:
SVM-Type: eps-regression
SVM-Kernel: linear
cost: 1
gamma: 1
epsilon: 0.1
Number of Support Vectors: 2
> predictedY2 <- predict(svm.r2, mydata);predictedY2
1 2 3 4 5 6 7
3.273861 4.205396 5.136931 6.068465 7.000000 7.931535 8.863069
8 9
9.794604 10.726139
再尝试一下将esp-regression改为nu-regression试试:
> svm.r3=svm(y~x, type = "nu-regression",kernel = "linear"); svm.r3
Call:
svm(formula = y ~ x, type = "nu-regression",kernel = "linear")
Parameters:
SVM-Type: nu-regression
SVM-Kernel: linear
cost: 1
gamma: 1
nu: 0.5
Number of Support Vectors: 2
> predictedY3 <- predict(svm.r3, mydata); predictedY3
1 2 3 4 5 6 7 8 9
3 4 5 6 7 8 9 10 11
svm.r3的结果和实际一致!我们再用可视化图形展示一下这个结果:
> points(x,predictedY2, col = "blue")
> points(x,predictedY3, col ="green")
图中的绿色点已经和最初的黑色点重合了!
如果我们的数据不这么简单,结果也不这么直观,靠人工或者可视化读取预测值无法判断到底哪个模型的预测准确率更高,那该怎么办?我们可以引入一个均方误差的概念来评估一个模型的准确率。
均方误差的计算公式如下,即样本各个点预测值和实际值的差的平方的总和除以样本个数。
相应的,均方根误差的为:
均方根误差越小,则说明一个模型的整体准确性越高。
我们下面就来计算一下svm.r2 和svm.r3的RMSE:
> rmse <- function(error)
+ {
+ sqrt(mean(error^2))
+ }
>
> error2 <- svm.r2$residuals; #same as mydata$Y – predictedY3
> error2
1 2 3 4 5 6
-0.27386138 -0.20539603 -0.13693069 -0.06846534 0.00000000 0.06846534
7 8 9
0.13693069 0.20539603 0.27386138
> predictionRMSE2 <- rmse(error2); predictionRMSE2
[1] 0.1767768
> error3 <- svm.r3$residuals; error3
1 2 3 4 5
-5.757728e-08 -5.027875e-08 -4.298022e-08 -3.568169e-08-2.838316e-08
6 7 8 9
-2.108464e-08 -1.378611e-08 -6.487580e-09 8.109495e-10
> predictionRMSE3 <- rmse(error3); predictionRMSE3
[1] 3.406945e-08
很明显predictionRMSE3 < predictionRMSE2。可见svm.r3是svm.r,svm.r2, svm.r3中最适合训练数据的模型。