首页 > 其他 > 详细

谈一谈支持向量机分类器

时间:2015-10-08 20:11:20      阅读:468      评论:0      收藏:0      [点我收藏+]
技术分享

支持向量机(Support Vector Machine) 名字听起来很炫,功能也很炫,但公式理解起来常有眩晕感。所以本文尝试不用一个公式来说明SVM的原理,以保证不吓跑一个读者。理解SVM有四个关键名词: 分离超平面、最大边缘超平面、软边缘、核函数 。 

  • 分离超平面  separating hyperplane  :处理分类问题的时候需要一个决策边界,好象楚河汉界一样,在界这边我们判别A,在界那边我们判别B。这种决策边界将两类事物相分离,而线性的决策边界就是分离超平面。
  • 最大边缘超平面(Maximal Margin Hyperplane) :分离超平面可以有很多个,怎么找最好的那个呢,SVM的作法是找一个“最中间”的。换句话说,就是这个平面要尽量和两边保持距离,以留足余量,减小泛化误差,保证稳健性。或者用中国人的话讲叫做“执中”。以江河为国界的时候,就是以航道中心线为界,这个就是最大边缘超平面的体现。在数学上找到这个最大边缘超平面的方法是一个二次规划问题。
  • 软边缘(Soft Margin) :但世界上没这么美的事,很多情况下都是“你中有我,我中有你”的混杂状态。不大可能用一个平面完美的分离两个类别。在线性不可分情况下就要考虑软边缘了。软边缘可以破例允许个别样本跑到其它类别的地盘上去。但要使用参数来权衡两端,一个是要保持最大边缘的分离,另一个要使这种破例不能太离谱。这种参数就是对错误分类的惩罚程度C。
  • 核函数(Kernel Function), 为了解决完美分离的问题,SVM还提出一种思路,就是将原始数据映射到高维空间中去,直觉上可以感觉高维空间中的数据变的稀疏,有利于“分清敌我”。那么映射的方法就是使用“核函数”。如果这种“核技术”选择得当,高维空间中的数据就变得容易线性分离了。而且可以证明,总是存在一种核函数能将数据集映射成可分离的高维数据。看到这里各位不要过于兴奋,映射到高维空间中并非是有百利而无一害的。维数过高的害处就是会出现过度拟合。

所以 选择合适的核函数以及软边缘参数C就是训练SVM的重要因素 。一般来讲,核函数越复杂,模型越偏向于拟合过度。在参数C方面,它可以看作是 Lasso算法中的lambda的倒数,C越大模型越偏向于拟合过度,反之则拟合不足。实际问题中怎么选呢?用人类最古老的办法,试错。 

常用的核函数有如下种类: 

  • Linear:使用它的话就成为线性向量机,效果基本等价于Logistic回归。但它可以处理变量极多的情况,例如文本挖掘。
  • polynomial:多项式核函数,适用于图像处理问题。
  • Radial basis,高斯核函数,最流行易用的选择。参数包括了sigma,其值若设置过小,会有过度拟合出现。
  • sigmoid:反曲核函数,多用于神经网络的激活函数。

好吧,理论说了一大堆,关键得在R里面出手。R语言中可以用 e1071包 中的 svm函数 建模,而另一个 kernlab包 中则包括了更多的核方法函数,本例用其中的 ksvm函数 ,来说明参数C的作用和核函数的选择。我们先人为构造一个线性不可分的数据,先用线性核函数来建模,其参数C取值为1。然后我们用图形来观察建模结果,下图是根据线性SVM得到各样本的判别值等高线图(判别值decision value相当于Logistic回归中的X,X取0时为决策边界)。可以清楚的看到决策边界为线性,中间的决策边缘显示为白色区域,有相当多的样本落入此区域。 

技术分享

下面为了更好的拟合,我们加大了C的取值,这样如下图所示。可以预料到,当加大惩罚参数后决策边缘缩窄,也使训练误差减少,但仍有个别样本未被正确的分类。 

技术分享

最后我们换用高斯核函数,这样得到的非线性决策边界。所有的样本都得到了正确的分类。 

技术分享

在实际运用中,为了寻找最优参数我们还可以用caret包来配合建模,并且使用多重交叉检验来评价模型。还需要注意一点SVM建模最好先标准化处理。最后来总结一下SVM的优势: 

  • 可用于分类、回归和异常检验
  • 可以发现全局最优解
  • 可以用参数来控制过度拟合问题


代码如下: 

library(caret)
library(kernlab)
library(e1071)
# 构造数据
x1 <- seq(0,pi,length.out=100)
y1 <- sin(x1) + 0.1*rnorm(100)
x2 <- 1.5+ seq(0,pi,length.out=100)
y2 <- cos(x2) + 0.1*rnorm(100)
data <- data.frame(c(x1,x2),c(y1,y2),c(rep(1, 100), rep(-1, 100)))
names(data) <- c(‘x1‘,‘x2‘,‘y‘)
data$y <- factor(data$y) 
# 使用线性核函数,不能很好的划分数据
model1 <- ksvm(y~.,data=data,kernel=‘vanilladot‘,C=0.1)
plot(model1,data=data)
# 加大惩罚参数,决策边缘缩窄,使训练误差减小
model2 <- ksvm(y~.,data=data,kernel=‘vanilladot‘,C=100)
plot(model2,data=data)
# 使用高斯核函数,正确的分类
model3 <- ksvm(y~.,data=data,kernel=‘rbfdot‘)
plot(model3,data=data) 
# 10折交叉检验训练iris数据,选择最优参数C为0.5
fitControl <- trainControl(method = "repeatedcv", number = 10, repeats = 3,returnResamp = "all")
model <- train(Species~., data=iris,method=‘svmRadialCost‘,trControl = fitControl)


谈一谈支持向量机分类器

原文:http://my.oschina.net/dfsj66011/blog/514420

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!