ImageVerifierCode 换一换
格式:DOCX , 页数:22 ,大小:728.79KB ,
资源ID:8193138      下载积分:10 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.docduoduo.com/d-8193138.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(R语言与机器学习(4)支持向量机.docx)为本站会员(hwpkd79526)主动上传,道客多多仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知道客多多(发送邮件至docduoduo@163.com或直接QQ联系客服),我们立即给予删除!

R语言与机器学习(4)支持向量机.docx

1、算法四:支持向量机说到支持向量机,必须要提到 july 大神的支持向量机通俗导论,个人感觉再怎么写也不可能写得比他更好的了。这也正如青莲居士见到崔颢的黄鹤楼后也只能叹“此处有景道不得”。不过我还是打算写写 SVM 的基本想法与 libSVM中 R 的接口。一、SVM 的想法回到我们最开始讨论的 KNN 算法,它占用的内存十分的大,而且需要的运算量也非常大。那么我们有没有可能找到几个最有代表性的点(即保留较少的点)达到一个可比的效果呢?要回答这个问题,我们首先必须思考如何确定点的代表性?我想关于代表性至少满足这样一个条件:无论非代表性点存在多少,存在与否都不会影响我们的决策结果。显然如果仍旧使用

2、 KNN 算法的话,是不会存在训练集的点不是代表点的情况。那么我们应该选择一个怎样的“距离”满足仅依靠代表点就能得到全体点一致的结果?我们先看下面一个例子:假设我们的训练集分为正例与反例两类,分别用红色的圆圈与蓝色的五角星表示,现在出现了两个未知的案例,也就是图中绿色的方块,我们如何去分类这两个例子呢?在 KNN 算法中我们考虑的是未知样例与已知的训练样例的平均距离,未知样例与正例和反例的“距离”谁更近,那么他就是对应的分类。同样是利用距离,我们可以换一个方式去考虑:假设图中的红线是对正例与反例的分类标准(记为 w x+b=0),那么我们的未知样例与红线的“距离”就成了一个表示分类信度的标准,

3、而 w y+b(y 为未知样例的数据)的符号则可以看成是分类的标识。但是遗憾的是我们不知道这样的一条分类标准(分类线)是什么,那么我们一个比较自然的想法就是从已知的分类数据(训练集)里找到离分割线最近的点,确保他们离分割面尽可能的远。这样我们的分类器会更稳健一些。从上面的例子来看,虚线穿过的样例便是离分割线最近的点,这样的点可能是不唯一的,因为分割线并不确定,下图中黑线穿过的训练样例也满足这个要求:所以“他们离分割面尽可能的远”这个要求就十分重要了,他告诉我们一个稳健的超平面是红线而不是看上去也能分离数据的黄线。这样就解决了我们一开始提出的如何减少储存量的问题,我们只要存储虚线划过的点即可(因

4、为在 w x+b=-1 左侧,w x+b=1 右侧的点无论有多少都不会影响决策)。像图中虚线划过的,距离分割直线(比较专业的术语是超平面)最近的点,我们称之为支持向量。这也就是为什么我们这种分类方法叫做支持向量机的原因。至此,我们支持向量机的分类问题转化为了如何寻找最大间隔的优化问题。二、SVM 的一些细节支持向量机的实现涉及许多有趣的细节:如何最大化间隔,存在“噪声”的数据集怎么办,对于线性不可分的数据集怎么办等。我这里不打算讨论具体的算法,因为这些东西完全可以参阅 july 大神的支持向量机通俗导论,我们这里只是介绍遇到问题时的想法,以便分析数据时合理调用 R 中的函数。几乎所有的机器学习

5、问题基本都可以写成这样的数学表达式:给定条件:n 个独立同分布观测样本(x1 , y1 ), (x2 , y2 ),(xn , yn )目标:求一个最优函数 f (x,w* )最理想的要求:最小化期望风险 R(w)不同的是我们如何选择 f,R。对于支持向量机来说,f(x,w*)=w x+b,最小化风险就是最大化距离|w x|/|w|,即 arg maxmin(label (w x+b)/|w| (也就是对最不 confidence 的数据具有了最大的 confidence)这里的推导涉及了对偶问题,拉格朗日乘子法与一堆的求导,我们略去不谈,将结果叙述如下:我们以鸢尾花数据来说说如何利用 svm

6、 做分类,由于 svm 是一个 2 分类的办法,所以我们将鸢尾花数据也分为两类,“setosa”与“versicolor”(将后两类均看做一类),那么数据按照特征:花瓣长度与宽度做分类,有分类:从上图可以看出我们通过最优化原始问题或者对偶问题就可以得到 w,b,利用 sign(w.x+b)就可以判断分类了。我们这里取 3, 10,56, 68,107, 120 号数据作为测试集,其余的作为训练集,我们可以看到:训练集 setosa virginicasetosa 48 0virginica 0 96测试集 setosa virginicasetosa 2 0virginica 0 4也就是完全

7、完成了分类任务。我们来看看鸢尾花后两类的分类 versicolor 和 virginica 的分类,我们将数据的散点图描绘如下:(我们把第一类“setosa“看做”versicolor“)不难发现这时无论怎么画一条线都无法将数据分开了,那么这么办呢?我们一个自然的办法就是允许分类有一部分的错误,但是错误不能无限的大。我们使用一个松弛项来分类数据。最优化问题转变为:当我们确定好松弛项 C 后,就可以得到分类:我们还是先来看看分类的效果:(C=10)训练集 versicolor virginicaversicolor 93 2virginica 3 46测试集 versicolor virgini

8、caversicolor 4 2virginica 0 0虽然分类中有一些错误,但是大部分还是分开了的,也就是说还是不错的,至少完成了分类这个任务。我们再来看看一个更麻烦的例子:假设数据是这样的:这时再用直线作为划分依据就十分的蹩脚了,我们这时需要引入核的方法来解决这个问题。在上图中,我们一眼就能看出用一个 S 型去做分类就可以把数据成功分类了(当然是在允许一点点错误的情况下),但是计算机能识别的只有分类器的分类结果是-1 还是 1,这时,我们需要将数据做出某种形式的转换,使得原来不可用直线剖分的变得可分,易分。也就是需要找到一个从一个特征空间到另一个特征空间的映射。我们常用的映射有:线性核:

9、u*v多项式核:(gamma*u*v+ coef0)degree高斯核:exp(-gamma*|u-v|2)Sigmoid 核:tanh(gamma*u*v + coef0)我们这里使用各种常见的核来看看分类效果:从图中我们可以看到正态核的效果是最好的,用数据说话,我们来看看分类错误率与折 10 交叉验证的结果(报告平均分类正确率):我们可以看到,无论从存储数据量的多少(支持向量个数)还是分类精确度来看,高斯核都是最优的。所以一般情况,特别是在大样本情况下,优先使用高斯核,至少可以得到一个不太坏的结果(在完全线性可分下,线性函数的支持向量个数还是少一些的)。三、libSVM 的 R 接口有许多

10、介绍 SVM 的书都有类似的表述“由于理解支持向量机需要掌握一些理论知识,而这对读者来说有一定的难度,建议直接下载 LIBSVM 使用。”确实,如果不是为了训练一下编程能力,我们没有必要自己用前面提到的做法自己实现一个效率不太高的 SVM。R 的函数包 e1071 提供了 libSVM 的接口,使用 e1071 的函数 SVM()可以得到 libSVM 相同的结果,write.svm()更是可以把R 训练得到的结果写为标准的 libSVM 格式供其他环境下的 libSVM 使用。在介绍 R 中函数的用法时,我们先简要介绍一下 SVM 的类型,以便我们更好地理解各个参数的设置。对于线性不可分时,

11、加入松弛项,折衷考虑最小错分样本和最大分类间隔。增加了算法的容错性,允许训练集不完全分类,以防出现过拟合。加入的办法有以下 3 类,写成最优化问题形式总结如上图:上图中 e 为所有元素都为 1 的列向量,Qij=yiyjK(xi; xj), K(xi; xj) =phi(xi) phi (xj), phi(.)为核函数,K(. ;.)表示对应元素核函数的内积。现在我们来看看 svm()函数的用法。# S3 method for class formulasvm(formula, data = NULL, ., subset,na.action =na.omit, scale = TRUE)#

12、Default S3 method:svm(x, y = NULL, scale = TRUE, type = NULL,kernel =“radial“, degree = 3, gamma = if(is.vector(x) 1 else 1 / ncol(x),coef0 = 0, cost = 1, nu = 0.5,class.weights = NULL, cachesize = 40,tolerance = 0.001, epsilon = 0.1,shrinking = TRUE, cross = 0, probability =FALSE, fitted = TRUE, se

13、ed = 1L,., subset, na.action = na.omit)主要参数说明:Formula:分类模型形式,在第二个表达式中使用的的 x,y 可以理解为 yx。Data:数据集Subset:可以指定数据集的一部分作为训练集Na.action:缺失值处理,默认为删除数据条目Scale:将数据标准化,中心化,使其均值为 0,方差为 1.默认自动执行。Type:SVM 的形式,使用可参见上面的 SVMformulation,type 的选项有:C-classification,nu-classification,one-classification (for novelty detec

14、tion),eps-regression,nu-regression。后面两者为利用 SVM 做回归时用到的,这里暂不介绍。默认为 C 分类器,使用 nu 分类器会使决策边界更光滑一些,单一分类适用于所有的训练数据提取自同一个类里,然后 SVM 建立了一个分界线以分割该类在特征空间中所占区域和其它类在特征空间中所占区域。Kernel:在非线性可分时,我们引入核函数来做非线性可分,R 提供的核介绍如下:线性核:u*v多项式核:(gamma*u*v + coef0)degree高斯核:exp(-gamma*|u-v|2)Sigmoid 核:tanh(gamma*u*v + coef0)默认为高斯核

15、(RBF),libSVM 的作者对于核的选择有如下建议:Ingeneral we suggest you to try the RBF kernel first. A recent result by Keerthiand Lin shows that if RBF is used with model selection, then there is no need to consider the linear kernel. The kernel matrix using sigmoid may not be positive definite and in general its acc

16、uracy is not better than RBF. (see thepaper by Lin and Lin. Polynomial kernels are ok but if a high degree is used,numerical difficulties tend to happen (thinking about dth power of (1) goes to infinity).顺带说一句,在 kernlab 包中,可以自定义核函数。Degree:多项式核的次数,默认为 3Gamma:除去线性核外,其他的核的参数,默认为 1/数据维数Coef0,:多项式核与 sigm

17、oid 核的参数,默认为 0Cost:C 分类的惩罚项 C 的取值Nu:nu 分类,单一分类中 nu 的取值Cross:做 K 折交叉验证,计算分类正确性。由于 svm 的编程确实过于复杂,还涉及到不少最优化的内容,所以在第二部分我的分类都是使用 svm 函数完成的(偷一下懒),现将部分 R 代码展示如下:dataSim 的函数:simData=function(radius,width,distance,sample_size)aa1=runif(sample_size/2)aa2=runif(sample_size/2)rad=(radius-width/2)+width*aa1theta

18、=pi*aa2x=rad*cos(theta)y=rad*sin(theta)label=1*rep(1,length(x)x1=rad*cos(-theta)+rady1=rad*sin(-theta)-distancelabel1=-1*rep(1,length(x1)n_row=length(x)+length(x1)data=matrix(rep(0,3*n_row),nrow=n_row,ncol=3)data,1=c(x,x1)data,2=c(y,y1)data,3=c(label,label1)datadataSim=simData(radius=10,width=6,dist

19、ance=-6,sample_size=3000)colnames(dataSim) 0,1, -1)polynomial.svm.fit 0, 1, -1)radial.svm.fit 0,1, -1)sigmoid.svm.fit 0,1, -1)df 0, 1, -1),PolynomialSVM = ifelse(predict(polynomial.svm.fit) 0, 1, -1),RadialSVM = ifelse(predict(radial.svm.fit) 0, 1, -1),SigmoidSVM = ifelse(predict(sigmoid.svm.fit) 0,

20、 1, -1)library(“reshape“)predictions - melt(df, id.vars = c(x, y)library(ggplot2)ggplot(predictions, aes(x = x, y = y, color = factor(value) +geom_point() +facet_grid(variable .)最后,我们回到最开始的那个手写数字的案例,我们试着利用支持向量机重做这个案例。(这个案例的描述与数据参见R 语言与机器学习学习笔记(分类算法)(1)运行代码:setwd(“D:/R/data/digits/trainingDigits“)nam

21、es-list.files(“D:/R/data/digits/trainingDigits“)data-paste(“train“,1:1934,sep=“)for(i in 1:length(names)assign(datai,as.vector(as.matrix(read.fwf(namesi,widths=rep(1,32)label-rep(0:9,c(189,198,195,199,186,187,195,201,180,204)data1-get(data1)for(i in 2:length(names)data1-rbind(data1,get(datai)m - svm

22、(data1,label,cross=10,type=“C-classification“)msummary(m)pred-fitted(m)table(pred,label)setwd(“D:/R/data/digits/testDigits“)names-list.files(“D:/R/data/digits/testDigits“)data-paste(“train“,1:1934,sep=“)for(i in 1:length(names)assign(datai,as.vector(as.matrix(read.fwf(namesi,widths=rep(1,32)data2-ge

23、t(data1)for(i in 2:length(names)data2-rbind(data2,get(datai)pred-predict(m,data2)labeltest-rep(0:9,c(87,97,92,85,114,108,87,96,91,89)table(pred,labeltest)模型摘要:Call:svm.default(x = data1, y = label, type =“C-classification“, cross =10)Parameters:SVM-Type: C-classificationSVM-Kernel: radialcost: 1gamm

24、a: 0.0009765625Number of Support Vectors: 1139 ( 78 130 101 124 109 122 87 93 135 160 )Number of Classes: 10Levels: 0 1 2 3 4 5 6 7 8 910-fold cross-validation on training data:Total Accuracy: 96.7425Single Accuracies:97.40933 98.96373 91.7525899.48187 94.84536 94.30052 97.40933 96.90722 98.96373 97

25、.42268当然,我们还可以通过 m$SV 查看支持向量的情况,m$index 查看支持向量的标签,m$rho 查看分类时的截距 b。训练集分类结果:我们拿测试数据来看:分类正确率为:0.9735729,误差率为 2.6%左右,确实达到了开篇提出的可比的目的,而需要储存的支持向量个数仅为 1139 个,比原来的训练数据 1934 个要少了近 50%,也达到了我们要求的节约存储的目的。当然值得一提的是线性分类的效果在实际中也没有那么糟糕,可以牺牲线性核函数的正确率来换取分类速度与存储空间。另外,支持向量的个数与训练集的出错率也没有特别必然的联系,而是与容错率 cost 有一定的联系。FurtherReading:在 R 中使用支持向量机:(3.e1071 包和 klaR 包)支持向量机: Maximum MarginClassifier

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报