附注:不要问我为什么写这么快,是16年写的。
1.名词解释
支持向量机中的机:在机器学习领域,常把一些算法看做一个机器,如分类机(也叫作分类器)
2.问题描述
空间中有很多已知类别的点,现在想用一个面分开他们,并能对未知类别的点很好的识别类别。
3.算法思想
由问题描述可知,现在算法要解决两个问题:
找到一个平面,可以很好的区分不同类别的点,即使分类器的训练误差小,线性可分时要求训练误差为0。
很好的识别未知类别样本的类别,即多大程度上信任该分类器在未知样本上分类的效果。
令满足以上两点的超平面方程为:
图1 画图展示
4.公式推导
这里接着上一步,公式推导如何求w和b,下图2所示。
图2 公式推导
5.程序实现(案例)
案例介绍:用体重和心脏重量来预测一只猫的性别。
语言:R语言,可在线安装e1071包,亦可在libsvm网站下载后安装程序包。
网址:http://www.csie.ntu.edu.tw/~cjlin/libsvm/
#数据集来自MASS包的cats数据集 #下面的程序将实现用体重和心脏重量来预测一只猫的性别 library(e1071) data(cats,package="MASS") summary(cats) inputData=data.frame(cats[, c (2,3)], Sex= as.factor(cats$Sex)) train=inputData[1:108,]#训练集 test=inputData[109:144,]#测试集 #初步建模 x=train[,-3] y=train[,3] #核函数选择高斯核函数 model1=svm(x,y,kernel='radial',gamma=if(is.vector(x)) 1 else1/ncol(x)) #计算训练误差,结果显示有14个样本类别错误 z=test[,-3] zy=test[,3] zy=as.integer(zy) pred1=predict(model1,x) table(pred1,y) #优化模型 attach(train)#将数据集train按列单独确认为向量 type=c("C-classification","nu-classification","one-classification") kernel=c("linear","polynomial","radial","sigmoid") pred2=array(0,dim=c(108,3,4)) accuracy=matrix(0,3,4) yy=as.integer(y) for(i in 1:3) { for(j in 1:4) { pred2[,i,j]=predict(svm(x,y,type=type[i],kernel=kernel[j]),x) if(i>2) accuracy[i,j]=sum(pred2[,i,j]!=1) else accuracy[i,j]=sum(pred2[,i,j]!=yy) } } #12种组合算法在训练集上的误差 wrong=matrix(0,3,4) for(i in 1:3) { for(j in 1:4) { wrong[i,j]=mean(yy != pred2[,i,j])#错误率占比 } } #选择训练集上误差最小的三种组合,计算在测试集上的误差,三种组合在训练集上的错误率分别为0.241,0.259,0.278;三种组合分别是nu-classification+radial、C-classification+linear组合和C-classification+radial组合。 pred3=array(0,dim=c(108,3,4)) for(i in 1:3) { for(j in 1:4) { pred3[,i,j]=predict(svm(x,y,type=type[i],kernel=kernel[j]),z) if(i>2) accuracy[i,j]=sum(pred3[,i,j]!=1) else accuracy[i,j]=sum(pred3[,i,j]!=yy) } } mean(zy != pred3[,2,3]) mean(zy != pred3[,1,1]) mean(zy != pred3[,1,3]) #计算结果分别为0.417,0,0 #在测试集上错误率为0的两种算法分别是C-classification+linear组合和C-classification+radial组合。
end!