R语言各种核函数的支持向量机分类、回归与参数优化

多种核函数分类及参数优化

分类数据集采用iris,先用ggplot画出其分布情况,这里用了花萼宽度和花瓣长度作为输入,标签是花的种类

library(ggplot2)
ggplot(iris,aes(x=Sepal.Width,y=Petal.Length,col=Species))+geom_point()

 

可以看出其属于近似线性可分的情况,接下来用svm进行拟合,首先用默认的径向基核函数作为核函数进行模型拟合

library(e1071)
svm.fit<-svm(Species~Sepal.Width+Petal.Length,data=iris)#默认径向基核函数
summary(svm.fit)

可以看到cost默认为1,有59个支持向量。

接下来我们来算一下我们的模型预测对了多少数据

pre<-predict(svm.fit)
pre

n<-nrow(iris)
num = 0
for(i in 1:n){
  if(pre[i]==iris[i,'Species']) num<-num+1
}
num
num/n

得到的结果是num=142,准确率为0.9466667。然后我们来查看分类的结果

myiris<-cbind(iris,pre)
head(myiris)
tf<-c()
for(i in 1:n){
  if(pre[i]==iris[i,'Species']) tf[i]<-as.character(iris[i,'Species'])
  else tf[i]<-'fasle'
}

myiris$tf<-factor(tf)
ggplot(myiris)+geom_point(aes(x=Sepal.Width,y=Petal.Length,col=tf))
 

同样的方法也可以得到线性核函数、多项式核函数和sigmoid核函数的结果分别如下:

他们三个分别预测正确143、136、135个,sigmoid效果最差,甚至犯了一些很明显的错误,这是由于sigmoid更适合非线性较强数据集的原因。接下来我们对参数进行优化,先单个参数优化,再整体优化。

首先是多项式核函数的degree,也就是他的最高次数,这里选了1:20来算准确率画出曲线

cur<-c()
for(i in 1:20){
  svm.poly<-svm(Species~Sepal.Width+Petal.Length,data=iris,
                kernel='polynomial',degree=i)
  pre<-predict(svm.poly)
  n<-nrow(iris)
  num = 0
  for(j in 1:n){
    if(pre[j]==iris[j,'Species']) num<-num+1
  }
  cur[i]<-num/n
}
plot(cur,type='l')

可以看出次数越高,效果越差,而且奇次数比偶次数要好。

接下来针对径向基核函数分别优化正则项系数cost和核函数中的参数gamma

cur<-c()
for(i in 1:10){
  svm.poly<-svm(Species~Sepal.Width+Petal.Length,data=iris,cost=i)
  pre<-predict(svm.poly)
  n<-nrow(iris)
  num = 0
  for(j in 1:n){
    if(pre[j]==iris[j,'Species']) num<-num+1
  }
  cur[i]<-num/n
}
plot(cur,type='l')

cur<-c()
for(i in seq(0.5,10,0.5)){
  svm.poly<-svm(Species~Sepal.Width+Petal.Length,data=iris,gamma=i)
  pre<-predict(svm.poly)
  n<-nrow(iris)
  num = 0
  for(j in 1:n){
    if(pre[j]==iris[j,'Species']) num<-num+1
  }
  cur[i]<-num/n
}
plot(cur,type='l')

以上都是单个参数的优化,下面针对径向基核函数的svm,同时优化cost和gamma,并划分训练集测试集进行检验。

set.seed(1)
id<-sample(150,120)
train<-iris[id,]
test<-iris[-id,]

res<-data.frame(matrix(NA,nrow=400,ncol=3))
names(res)<-c('cost','gamma','cur')
for(i in 1:20){
  for(j in seq(0.5,10,0.5)){
    svmfit<-svm(Species~Sepal.Width+Petal.Length,data=train,cost=i,gamma=j)
    pre<-predict(svmfit)
    n<-nrow(train)
    num = 0
    for(k in 1:n){
      if(pre[k]==train[k,'Species']) num<-num+1
    }
    res[(i-1)*20+j*2,]<-c(i,j,num)
  }
}
maxres<-res[which(res[,3]==max(res[,3])),]

上面的代码构造了一个参数和预测正确个数的数据框,并把最高正确率的参数挑选了出来

然后我们用上面得到的第一组最优参数在测试集上进行预测,输出正确个数和准确率并画出结果图

svmbest<-svm(Species~Sepal.Width+Petal.Length,data=test,
             cost=maxres[1,1],gamma=maxres[1,2])
summary(svmbest)
pre<-predict(svmbest)

n<-nrow(test)
num = 0
for(i in 1:n){
  if(pre[i]==test[i,'Species']) num<-num+1
}
num
num/n

myiris<-cbind(test,pre)
tf<-c()
for(i in 1:n){
  if(pre[i]==test[i,'Species']) tf[i]<-as.character(test[i,'Species'])
  else tf[i]<-'fasle'
}
myiris$tf<-factor(tf)
head(myiris)
ggplot(myiris)+geom_point(aes(x=Sepal.Width,y=Petal.Length,col=tf))

得到的正确个数是30,也就是全部预测正确,结果图如下,可以看到没有false(突然发现前面的false都拼错了)类别

回归

回归采用的数据集是macars,用hp做自变量,mpg为因变量,核函数采用默认的径向基核函数,结果如下

head(mtcars)
attach(mtcars)
svr<-svm(mpg ~ hp)
pre<-predict(svr,hp)
summary(svr)
mycar<-cbind(mtcars,pre)
ggplot(mycar)+geom_point(aes(hp,mpg))+geom_line(aes(hp,pre),col='red')

  • 8
    点赞
  • 126
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值