R语言svm支持向量机分类与参数优化

首先构建数据集

x<-c(runif(50,0,1),runif(100,1,3),runif(50,3,4))

y<-runif(200,0,1)
z<-c(rep(0,50),rep(1,100),rep(0,50))

data<-cbind(x,y,z)

画出数据集的情况

plot(x,y,col=c(rep('red',50),rep('blue',100),rep('red',50)))


构建支持向量机

library(e1071)

svm.fit<-svm(z~x+y,data=data)
summary(svm.fit)
########
Call:
svm(formula = z ~ x + y, data = data)

Parameters:
   SVM-Type:  eps-regression 
 SVM-Kernel:  radial 
       cost:  1 
      gamma:  0.5 
    epsilon:  0.1 

Number of Support Vectors:  158

#########

SVM-Kernel:  radial表示此处使用的核函数为radial核函数,即径向基核函数,这是一个基于样本点之间的距离决定映射方式的函数。

Number of Support Vectors:  158 表示在这个模型中支持向量的数目是158

查看分类结果

predict(svm.fit)


预测值为正说明模型判断样本点属于类别1,为负说明属于类别0,且数值绝对值越大说明预测可靠性越大

svm.pre<-ifelse(predict(svm.fit)>0,1,0)
n<-ifelse(svm.pre==z,1,0)
sum(n)

[1] 131

131个分类正确,正确率为65.5%

col<-ifelse(svm.pre==0,'red','blue')
plot(x,y,col=col)

分类图像


下面尝试使用其他的核函数来分类

1.线性核函数

svm.line<-svm(z~x+y,data=data,kernel='linear')
svm.linepre<-ifelse(predict(svm.line)>0,1,0)
n<-ifelse(svm.linepre==z,1,0)
sum(n)
[1] 100

col<-ifelse(svm.linepre==0,'red','blue')
plot(x,y,col=col)



使用线性核函数的分类结果正确率是50%,而且把全部样本点判断为类别1

2.kernel设置为polynomial使用多项式核函数,结果与线性核函数一样

这是因为线性核函数和多项式核函数擅长解决线性分类,径向基核函数擅长解决非线性分类

3.同理可以试一下s型核函数,其正确率为56.5%,其分类结果散点图呈现倾斜带状,因为s型核函数对样本数据呈现带状规律过分敏感。实际上,他是神经网络核函数的首选。

支持向量机中比较重要的参数有三个:degree,cost,gamma

1.degree是仅用于多项式核函数中的参数,代表多项式核函数的次数,在本例中,经过实践发现degree为奇数时,degree越大模型表现越好,为偶数时,degree越大,模型越差,当degree足够大时,模型准确率趋于稳定。另外,当degree高于15时,R出现警告信息,而且当样本数据量较大时,设置过高的degree将非常危险(书上说的,我是想象不出来有什么危险)

2.cost是惩罚因子,可与任意核函数搭配,在本例中,分别取了1 2 3 4,发现cost越大越好。此外,cost与degree通常配合使用,在研究他们时,使用交叉验证法会得到更精确的结果。

3.gamma是选择径向基核函数作为kernel后,该函数自带的一个参数。隐含地决定了数据映射到新的特征空间后的分布,gamma越大,支持向量越少,gamma值越小,支持向量越多。支持向量的个数影响训练与预测的速度。本例也选取了1~20来测试,随着gamma的增加,准确度先增加后减小,在3处取最大值。

下面我们用穷举法来确定本例的最佳参数组合

a<-c()
for(i in 1:10){
for(j in 1:10){
for(k in 1:10){
svm.fit<-svm(z~x+y,data=data,degree=i,cost=j,gamma=k)
svm.pre<-ifelse(predict(svm.fit)>0,1,0)
n<-ifelse(svm.pre==z,1,0)
result<-c(i,j,k,sum(n))
a<-rbind(a,result)
}}}
a[which(a[,4]==max(a[,4])),]

结果如下

       [,1] [,2] [,3] [,4]
result    1    7    3  147
result    2    7    3  147
result    3    7    3  147
result    4    7    3  147
result    5    7    3  147
result    6    7    3  147
result    7    7    3  147
result    8    7    3  147
result    9    7    3  147
result   10    7    3  147

显然,degree的变化不影响径向基核函数的结果,所以最佳参数为cost=7,gamma=3,模型准确率可以达到73.5%