支持向量机
支持向量机(SVM)是在统计学习理论基础上发展起来的一种数据挖掘方法,1992 年由Boser, Guyon和Vapnik提出,在解决小样本、非线性、高维的回归和分类问题上, 有许多优势。
1 支持向量分类概述
支持向量分类以训练样本集为数据对象,通过分析输入变量和二分类输出变量之间的数量关系,对新样本的输出变量类别值进行分类预测。
1.1 基本思路:确保把握程度
可将训练样本中n 个观测看成p维特征空间上的n 个点,以点的不同形状( 或颜色)代表输出变量的不同类别取值。支持向量分类的建模目的,就是以训练样本为研究对象, 在p 维特征空间中找到一个超平面,能将两类样本有效分开。
参数的确定可按照神经网络的一般方法:通过不断迭代找到最优解。 然而,这样的超平面确定方式可能出现的问题是:
如果训练样本中的两类观测点能够被超平面分开,而且建模的唯二目标就是将两类分开,那么可能找到多个这样的超平面。
其中的哪个超平面应是支持向量分类的超平面?答案是:最大边界超平面是支持向量分类的超平面。
最大边界超平面,简单讲就是距两个类别( -1 类和1 类)的边界观测点最远的超平面。
1.2 支持向量分类的三种情况
1.2.1 线性可分样本
-
完全线性可分:说明可以找到一个超平面将两类样本完全线性分开
-
无法完全线性可分:存在样本点彼此交融
1.2.1 线性不可分样本
2 线性可分问题的支持向量分类
在完全线性可分的情况下,以二维空间为例,可通过以下途径确定并求解超平面:
- 分别将两类的最外围样本观测点连线,形成两个多边形,它是关于各类样本点集的凸包 , 也就是最小凸多边形,各自类的样本点均在多边形内或边上。
- 以一类的凸包边界作为基准线,找到另一类边界上的点,过该点做基准线的平行线,得到一对平行线
可以有多条这样的基准线和平行线,找到能正确分割两类且距离最远的一对平行线,并且做平行线的垂线。最大超平面就是垂线的垂直平分线
支持向量是位于平行边界上的样本观测点,决定了最大边界超平面。支持向量分类能够有效避免过拟合问题,原因是:过拟合表现在模型过分依赖训练样本。训练样本的微小变动,便会导致模型参数的较大变动,在支持向量分类中、即表现为超平面出现较大移动。由于最大边界超平面仅依赖于少数的支持向量,所以只有当增加或除去支持向量时,最大边界超平面才会移动,否则不发生变化。相对于其他分类预测模型,最大边界超平面的预测稳健性较高。
分类依据是
3 广义线性可分问题的支持向量分类
此时超平面的确定应采用“宽松”策略
4 复杂条件下的分类
解决线性不可分问题的一般方式是:特征空间的非线性转换。其核心思想为:低维空间中的线性不可分问题,通过非线性转换,可转化为高维空间中的线性可分问题,即通过适当的非线性空间转换变成线性可分问题。
但是高维度将导致计算的复杂度急剧增加,且模型的参数估计在小样本下几乎是无法实现的,这就是所谓的维灾难问题。
支持向盘分类的特色在于通过核函数克服维灾难问题。
5 支持向量机的R语言实现
5.1 svm函数
5.2 tune.svm函数
损失惩罚参数C 以及核函数的参数,都是支持向量机中的重要参数。可通过交叉验证方式帮助确定参数。tune. svm 函数可自动实现10 折交叉验证,并给出预测误差最小时的参数值。tune. svm 函数的基本书写格式为:
5.3 模拟线性可分情况下的支持向量机
#############模拟线性可分下的SVM
set.seed(12345)
x<-matrix(rnorm(n=40*2,mean=0,sd=1),ncol=2,byrow=TRUE)
y<-c(rep(-1,20),rep(1,20))
x[y==1,]<-x[y==1,]+1.5
data_train<-data.frame(Fx1=x[,1],Fx2=x[,2],Fy=as.factor(y)) #生成训练样本集
x<-matrix(rnorm(n=20,mean=0,sd=1),ncol=2,byrow=TRUE)
y<-sample(x=c(-1,1),size=10,replace=TRUE)
x[y==1,]<-x[y==1,]+1.5
data_test<-data.frame(Fx1=x[,1],Fx2=x[,2],Fy=as.factor(y)) #生成测试样本集
plot(data_train[,2:1],col=as.integer(as.vector(data_train[,3]))+2,pch=8,cex=0.7,main="训练样本集-1和+1类散点图")
library("e1071")
SvmFit<-svm(Fy~.,data=data_train,type="C-classification",kernel="linear",cost=10,scale=FALSE)
summary(SvmFit)
SvmFit$index
plot(x=SvmFit,data=data_train,formula=Fx1~Fx2,svSymbol="#",dataSymbol="*",grid=100)
SvmFit<-svm(Fy~.,data=data_train,type="C-classification",kernel="linear",cost=0.1,scale=FALSE)
summary(SvmFit)
##############10折交叉验证选取损失惩罚参数C
set.seed(12345)
tObj<-tune.svm(Fy~.,data=data_train,type="C-classification",kernel="linear",
cost=c(0.001,0.01,0.1,1,5,10,100,1000),scale=FALSE)
summary(tObj)
BestSvm<-tObj$best.model
summary(BestSvm)
yPred<-predict(BestSvm,data_test)
(ConfM<-table(yPred,data_test$Fy))
(Err<-(sum(ConfM)-sum(diag(ConfM)))/sum(ConfM))
-
在线性可分的原则下,随机生成训练样本集和测试样本集。其中的输人变量有2个,输出变量类别为-1和+1,应为因子
-
采用线性核函数,比较当损失惩罚参数较大和较小下的支持向量个数和最大边界超平面。
-
利用10 折交叉验证找到预测误差最小下的损失惩罚参数
-
利用最优模型对测试样本集做预测
5.4 模拟线性不可分的支持向量机
##############模拟线性不可分下的SVM
set.seed(12345)
x<-matrix(rnorm(n=400,mean=0,sd=1),ncol=2,byrow=TRUE)
x[1:100,]<-x[1:100,]+2
x[101:150,]<-x[101:150,]-2
y<-c(rep(1,150),rep(2,50))
data<-data.frame(Fx1=x[,1],Fx2=x[,2],Fy=as.factor(y))
flag<-sample(1:200,size=100)
data_train<-data[flag,]
data_test<-data[-flag,]
plot(data_train[,2:1],col=as.integer(as.vector(data_train[,3])),pch=8,cex=0.7,main="训练样本集散点图")
library("e1071")
set.seed(12345)
tObj<-tune.svm(Fy~.,data=data_train,type="C-classification",kernel="radial",
cost=c(0.001,0.01,0.1,1,5,10,100,1000),gamma=c(0.5,1,2,3,4),scale=FALSE)
plot(tObj,xlab=expression(gamma),ylab="损失惩罚参数C",
main="不同参数组合下的预测错误率",nlevels=10,color.palette=terrain.colors)
BestSvm<-tObj$best.model
summary(BestSvm)
plot(x=BestSvm,data=data_train,formula=Fx1~Fx2,svSymbol="#",dataSymbol="*",grid=100)
yPred<-predict(BestSvm,data_test)
(ConfM<-table(yPred,data_test$Fy))
(Err<-(sum(ConfM)-sum(diag(ConfM)))/sum(ConfM))
5.5 模拟多分类的支持向量机
##############模拟多类别的SVM
set.seed(12345)
x<-matrix(rnorm(n=400,mean=0,sd=1),ncol=2,byrow=TRUE)
x[1:100,]<-x[1:100,]+2
x[101:150,]<-x[101:150,]-2
x<-rbind(x,matrix(rnorm(n=100,mean=0,sd=1),ncol=2,byrow=TRUE))
y<-c(rep(1,150),rep(2,50))
y<-c(y,rep(0,50))
x[y==0,2]<-x[y==0,2]+3
data<-data.frame(Fx1=x[,1],Fx2=x[,2],Fy=as.factor(y))
plot(data[,2:1],col=as.integer(as.vector(data[,3]))+1,pch=8,cex=0.7,main="训练样本集散点图")
library("e1071")
set.seed(12345)
tObj<-tune.svm(Fy~.,data=data,type="C-classification",kernel="radial",
cost=c(0.001,0.01,0.1,1,5,10,100,1000),gamma=c(0.5,1,2,3,4),scale=FALSE)
BestSvm<-tObj$best.model
summary(BestSvm)
plot(x=BestSvm,data=data,formula=Fx1~Fx2,svSymbol="#",dataSymbol="*",grid=100)
SvmFit<-svm(Fy~.,data=data,type="C-classification",kernel="radial",cost=5,gamma=1,scale=FALSE)
head(SvmFit$decision.values)
yPred<-predict(SvmFit,data)
(ConfM<-table(yPred,data$Fy))
(Err<-(sum(ConfM)-sum(diag(ConfM)))/sum(ConfM))
n",kernel=“radial”,cost=5,gamma=1,scale=FALSE)
head(SvmFit
d
e
c
i
s
i
o
n
.
v
a
l
u
e
s
)
y
P
r
e
d
<
−
p
r
e
d
i
c
t
(
S
v
m
F
i
t
,
d
a
t
a
)
(
C
o
n
f
M
<
−
t
a
b
l
e
(
y
P
r
e
d
,
d
a
t
a
decision.values) yPred<-predict(SvmFit,data) (ConfM<-table(yPred,data
decision.values)yPred<−predict(SvmFit,data)(ConfM<−table(yPred,dataFy))
(Err<-(sum(ConfM)-sum(diag(ConfM)))/sum(ConfM))
``