用一个简单的例子比较SVM,MARS以及BRUTO(R语言)
背景重述
本文是ESL: 12.3 支持向量机和核中表12.2的重现过程。具体问题如下:
在两个类别中产生100个观测值。第一类有4个标准正态独立特征\(X_1,X_2,X_3,X_4\)。第二类也有四个标准正态独立特征,但是条件为\(9\le \sum X_j^2\le 16\)。这是个相对简单的问题。同时考虑第二个更难的问题,用6个标准高斯噪声特征作为增广特征。
生成数据
## #####################################
## generate dataset
##
## `No Noise Features`: num_noise = 0
## `Six Noise Features`: num_noise = 6
## #####################################
genXY <- function(n = 100, num_noise = 0)
{
## class 1
m1 = matrix(rnorm(n*(4+num_noise)), ncol = 4 + num_noise)
## class 2
m2 = matrix(nrow = n, ncol = 4 + num_noise)
for (i in 1:n) {
while (TRUE) {
m2[i, ] = rnorm(4 + num_noise)
tmp = sum(m2[i, 1:4]^2)
if(tmp >= 9 & tmp <= 16)
break
}
}
X = rbind(m1, m2)
Y = rep(c(1, 2), each = n)
return(data.frame(X = X, Y = as.factor(Y)))
}
模型训练
- SVM直接调用
e1071
包中的svm
函数 - BRUTO和MARS都是调用
mda
包,且由于两者都是用于回归,所以转换为分类时,是比较拟合值与类别标签的距离,划分到越靠近的那一类 - 原书中提到实验中MARS不限定阶数,但实际编程时,设置阶数为10
交叉验证选择合适的\(C\)
我分两步进行选择:
- 粗选:在较大范围内寻找最优的\(C\)
- 细分:在上一步选取的最优值附近进行细分
注意避免最优值取在边界值。以SVM/poly5为例进行说明,其他类似
## SVM/poly5
set.seed(123)
poly5 = tune.svm(Y~., data = dat, kernel = "polynomial", degree = 5, cost = 2^(-4:8))
summary(poly5)
此时选取的最优\(C\)为32,进一步细化
set.seed(1234)
poly5 = tune.svm(Y~., data = dat, kernel = "polynomial", degree = 5, cost = seq(16, 64, by = 2))
summary(poly5)
所以\(C\)取28。
类似地,得到其它方法的最优\(C\),比如某次实验结果如下:
Method | best cost |
---|---|
SV Classifier | 2.6 |
SVM/poly 2 | 1 |
SVM/poly 5 | 28 |
SVM/poly 10 | 0.5 |
当然,实际中我们并不需要重新设置参数来训练模型,因为tune.svm()
的返回结果就包含了最优模型,直接调用,比如poly5$best.model
计算测试误差
predict.mars2 <- function(model, newdata)
{
pred = predict(model, newdata)
ifelse(pred < 1.5, 1, 2)
}
calcErr <- function(model, n = 1000, nrep = 50, num_noise = 0, method = "SVM")
{
err = sapply(1:nrep, function(i){
dat = genXY(n, num_noise = num_noise)
datX = dat[, -ncol(dat)]
datY = dat[, ncol(dat)]
if (method == "SVM")
pred = predict(model, newdata = datX)
else if (method == "MARS")
pred = predict.mars2(model, newdata = datX)
else if (method == "BRUTO")
pred = predict.mars2(model, newdata = as.matrix(datX))
sum(pred != datY)/(2*n) # Attention!! The total number of observations is 2n, not n
})
return(list(TestErr = mean(err),
SE = sd(err)))
}
值得说明的是,对于BRUTO和MARS,因为程序是将其视为回归模型处理的,需要进一步转换为类别标签。因为程序中类别用1和2编号,所以判断拟合值是否大于1.5,大于则划为第二类,否则第一类。
结果
将之与表12.2进行比较,可以看出各个方法的误差率及标准差的相对大小都比较一致。
贝叶斯误差率
对于类别1,
\]
对于类别2,
\]
其中\(f(t)\)是\(\chi^2(4)\)的密度函数。
于是贝叶斯误差率为
\]
完整代码可以参见skin-of-the-orange.R
本文永久链接:模拟:Tab. 12.2
用一个简单的例子比较SVM,MARS以及BRUTO(R语言)的更多相关文章
- 扩展Python模块系列(二)----一个简单的例子
本节使用一个简单的例子引出Python C/C++ API的详细使用方法.针对的是CPython的解释器. 目标:创建一个Python内建模块test,提供一个功能函数distance, 计算空间中两 ...
- 用一个简单的例子来理解python高阶函数
============================ 用一个简单的例子来理解python高阶函数 ============================ 最近在用mailx发送邮件, 写法大致如 ...
- Spring-Context之一:一个简单的例子
很久之前就想系统的学习和掌握Spring框架,但是拖了很久都没有行动.现在趁着在外出差杂事不多,就花时间来由浅入深的研究下Spring框架.Spring框架这几年来已经发展成为一个巨无霸产品.从最初的 ...
- 关于apriori算法的一个简单的例子
apriori算法是关联规则挖掘中很基础也很经典的一个算法,我认为很多教程出现大堆的公式不是很适合一个初学者理解.因此,本文列举一个简单的例子来演示下apriori算法的整个步骤. 下面这个表格是代表 ...
- fitnesse - 一个简单的例子(slim)
fitnesse - 一个简单的例子(slim) 2017-09-30 目录1 编写测试代码(Fixture code)2 编写wiki page并运行 2.1 新建wikiPage 2.2 运行 ...
- Struts2的配置和一个简单的例子
Struts2的配置和一个简单的例子 笔记仓库:https://github.com/nnngu/LearningNotes 简介 这篇文章主要讲如何在 IntelliJ IDEA 中使用 Strut ...
- 一个简单的例子搞懂ES6之Promise
ES5中实现异步的常见方式不外乎以下几种: 1. 回调函数 2. 事件驱动 2. 自定义事件(根本上原理同事件驱动相同) 而ES6中的Promise的出现就使得异步变得非常简单.promise中的异步 ...
- 一个简单的例子了解states
在大规模的配置管理工作中,我们要编写大量的states.sls文件.top.sls是states系统的入口文件,它负责指定哪些设备调用哪些states.sls文件.statse的默认工作目录是在/sr ...
- 跨站脚本功攻击,xss,一个简单的例子让你知道什么是xss攻击
跨站脚本功攻击,xss,一个简单的例子让你知道什么是xss攻击 一.总结 一句话总结:比如用户留言功能,用户留言中写的是网页可执行代码,例如js代码,然后这段代码在可看到这段留言的不同一户的显示上就会 ...
随机推荐
- python3 第六章 - 条件判断
Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 条件语句的执行过程,如下图: 条件语句,又称为if语句,它的完整语法如下: if 条件1: 语句块1 ...
- python_如何使用临时文件
案例: 某项目中,从传感器中获得采集数据,每收集到1G的数据后做是数据分析,最终只保留数据分析的结果,收集到的数据放在内存中,将会消耗大量内存,我们希望把这些数据放到一个临时的文件中 临时文件不能命名 ...
- CSS深入理解学习笔记之float
1.float的历史 float设计的初衷仅仅是为了文字环绕效果. 示例代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transit ...
- lambda高级进阶--返回函数
在函数式编程语言中,函数是一级公民.如同你可以将数字传递给方法,也可以让方法产生数字一样,函数不仅可以作为参数,也可以作为返回值.这听起来好像有点抽象,在JAVA编码中,我们好像也很少这样子写到,但是 ...
- Web应用基础
B-S架构 架构的发展 1,c/s架构 (client客户端-server服务端) (胖客户端:要求客户端运行业务:把业务放到服务器端,则是瘦客户端) 典型的c/s应用 ...
- spring的jar各包作用
http://yjwen337.blog.163.com/blog/static/3625847820106132949858/[转]spring.jar是包含有完整发布的单个jar 包,spring ...
- docker基础及安装
Docker介绍: Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制 ...
- java编码GBK的不可映射字符
编译java文件时,提示编码GBK的不可映射字符. 主要原因:windows 默认编码方式为GBK,用javac编译时,中文按照GBK解析,但是文件内容编码格式不是GBK. 解决:若编译单个文件指定编 ...
- java对象引用-要掌握的细节
hello ,好久没来了. 今天我来和大家分享一下有关引用变量的注意事项,一是加深一下自己的理解,二是对这块不太理解的同学可以看看. 大神可飘过,有什么不对或不足的地方请多多指教,谢谢. 假设场景: ...
- js 面向对象 继承
继承方式有四种: 1.call 2.apply 3.prototype 4.for in call 和 apply 的主要区别: call 传参数只能一个一个的传, apply 因为是用数组,所以可以 ...