R语言第八讲 评估模型之交叉验证法分析案例

题目

      评估Auto数据集上拟合多个线性模型所产生的测试错误率。Auto数据集是存在与ISLR程序包中的一个摩托车相关数据的数据集,读者可自行下载ISLR程序包,并将Auto数据集加载。

相关资料

      交叉验证是在机器学习建立模型和验证模型参数时常用的办法。交叉验证,顾名思义,就是重复的使用数据,把得到的样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测试集来评估模型预测的好坏。在此基础上可以得到多组不同的训练集和测试集,某次训练集中的某样本在下次可能成为测试集中的样本,即所谓“交叉”。

那么什么时候才需要交叉验证呢?交叉验证用在数据不是很充足的时候。比如在我日常项目里面,对于普通适中问题,如果数据样本量小于一万条,我们就会采用交叉验证来训练优化选择模型。如果样本大于一万条的话,我们一般随机的把数据分成三份,一份为训练集(Training Set),一份为验证集(Validation Set),最后一份为测试集(Test Set)。用训练集来训练模型,用验证集来评估模型预测的好坏和选择模型及其对应的参数。把最终得到的模型再用于测试集,最终决定使用哪个模型以及对应参数。

回到交叉验证,根据切分的方法不同,交叉验证分为下面三种:

第一种是简单交叉验证,所谓的简单,是和其他交叉验证方法相对而言的。首先,我们随机的将样本数据分为两部分(比如: 70%的训练集,30%的测试集),然后用训练集来训练模型,在测试集上验证模型及参数。接着,我们再把样本打乱,重新选择训练集和测试集,继续训练数据和检验模型。最后我们选择损失函数评估最优的模型和参数。

第二种是S折交叉验证(S-Folder Cross Validation)。和第一种方法不同,S折交叉验证会把样本数据随机的分成S份,每次随机的选择S-1份作为训练集,剩下的1份做测试集。当这一轮完成后,重新随机选择S-1份来训练数据。若干轮(小于S)之后,选择损失函数评估最优的模型和参数。

第三种是留一交叉验证(Leave-one-out Cross Validation),它是第二种情况的特例,此时S等于样本数N,这样对于N个样本,每次选择N-1个样本来训练数据,留一个样本来验证模型预测的好坏。此方法主要用于样本量非常少的情况,比如对于普通适中问题,N小于50时,我一般采用留一交叉验证。

通过反复的交叉验证,用损失函数来度量得到的模型的好坏,最终我们可以得到一个较好的模型。那这三种情况,到底我们应该选择哪一种方法呢?一句话总结,如果我们只是对数据做一个初步的模型建立,不是要做深入分析的话,简单交叉验证就可以了。否则就用S折交叉验证。在样本量少的时候,使用S折交叉验证的特例留一交叉验证。

此外还有一种比较特殊的交叉验证方式,也是用于样本量少的时候。叫做自助法(bootstrapping)。比如我们有m个样本(m较小),每次在这m个样本中随机采集一个样本,放入训练集,采样完后把样本放回。这样重复采集m次,我们得到m个样本组成的训练集。当然,这m个样本中很有可能有重复的样本数据。同时,用没有被采样到的样本做测试集。这样接着进行交叉验证。由于我们的训练集有重复数据,这会改变数据的分布,因而训练结果会有估计偏差,因此,此种方法不是很常用,除非数据量真的很少,比如小于20个。

        随机抽样函数sample介绍:

 

> x=1:10> sample(x=x)
[1]  3  5  9  6 10  7  2  1  8  4

        第一行代码表示给x向量x赋值,第二行代码表示对x向量进行随机抽样。结果输出为每次抽样抽得的结果,可以看出该抽样为无放回抽样-最多抽n次,n为向量中元素的个数。

       如果想指定在该向量中抽取元素的个数,需要加一个参数size:

> x=1:1000> sample(x=x,size=20)[1]  66 891 606 924 871 374 879 573 284 305 914 792 398 497 721 897 324 437[19] 901  33

       这是在1~1000的正整数中抽样,其中size指定抽样的次数,抽了20次,结果如上所示。

       这些都是无放回抽样。所谓无放回抽样,也就是说某个元素一旦被选择,该总体中就不会再有该元素。如果是有放回抽样,则需添加一个参数repalce=T:

> x=1:10> sample(x=x,size=5,replace=T)[1] 4 7 2 4 8

       “replace”就是重复的意思。即可以重复对元素进行抽样,也就是所谓的有放回抽样。我们看上面的结果,元素4在5次随机抽样的过程中被抽取了两次。

       如果我们输入代码的位置与某个函数中参数的位置一一对应的话,我们可以不写该函数的参数,如:

> x=1:10> sample(x,20,T)[1] 1 2 2 1 5 5 5 9 9 5 2 9 8 3 4 8 8 8 1 1

      简单运用:对于掷骰子,投硬币(这可能是介绍抽样必介绍的内容),都属于有放回抽样。

       这里要说明,对于sample函数,参数x可以是数值,也可以是字符,实际上参数x代表任意一个向量:

> a=c("A","B")> sample(x=a,size=10,replace=T)[1] "B" "A" "A" "A" "B" "A" "A" "B" "A" "A"

      上述代码可以理解为掷硬币,抛了10次,其中正面(A)与反面(B)出现的次数是可以重复的。

     上述抽样过程,每一个元素被抽取的概率相等,称为随机抽样。

     有时候我们的抽取元素的概率未必相等(如常见的二项分布概率问题),此时我们需要添加一个参数prob,即:“probability”(概率)的缩写。假设一名医生给患者做某手术成功的概率是80%,那么现在他给20例病人做手术,可能有哪几次是成功的呢?代码如下:

> x=c("S","F")> sample(x,size=20,replace=T,prob=c(0.8,0.2))[1] "F" "S" "S" "S" "S" "S" "S" "S" "S" "S" "S" "S" "F" "S" "S" "F" "S" "S"[19] "F" "S"

     其中“S”代表成功,“F”代表失败。

> x=c(1,3,5,7)> sample(x,size=20,replace=T,prob=c(0.1,0.2,0.3,0.9))[1] 3 5 7 3 7 3 7 5 3 7 7 7 1 5 7 5 7 7 3 7

      这些代码告诉我们,对每一个元素都可以给定一个概率,且每个概率是独立的,即在参数prob中,不一定所有元素的概率加起来等于1,它只代表某元素被抽取的概率而已。

     对于sample函数,其参数x可以是R中任意一个对象(如上述对字符的抽样)。其中还有一个功能相同的函数sample.int,“int”即“intger”的缩写,也就是“整数”。它的参数n必须是正整数:

> x=-10.5:7.5> sample(x=x,size=3)> sample.int(n=x,size=3)[1] -5.5 -7.5  0.5Error in sample.int(x, size = 3) : invalid first argument

        第一行代码生成了-10.5到7.5的等差数列,结果输出的第一行是sample的结果;第二行是sample.int的结果,提示错误:“第一个自变量无效”,因为它不是正整数。其余的用法与ample是一样的。

 

实验

      在开始之前,用 set. seed ()函数来为 R 的随机数生成器设定一个种子 (seed) .这样就就可以得到与下面展示的完全相同的结果。通常来说,使用一种如同交叉验证法这样包含随机性的分析方法时,可以设定一个随机种子,这样下次就可以得到完全相同的结果。

       首先用 sample()函数把观测集分为两半,从原始的 392 个观测中随机地选取一个有 196 个观测的子集,作为训练集。

> library(ISLR)
> set.seed(1)
#产生从1-392中抽样出196个数。
> train=sample(392,196)
[1] 324 167 129 299 270 187 307  85 277 362 330 263 329  79 213  37 105
[18] 217 366 165 290 383  89 289 340 326 382  42 111  20  44 343  70 121
[35]  40 172  25 248 198  39 298 280 160  14 130  45  22 206 230 193 104
[52] 367 255 341 342 103 331  13 296 375 176 279 110  84  29 141 252 221
[69] 108 304  33 347 149 287 102 145 118 323 107  64 224 337  51 325 372
[86] 138 390 389 282 143 285 170  48 204 295  24 181 214 225 163  43   1
[103] 328  78 284 116 233  61  86 374  49 242 246 247 239 219 135 364 363
[120] 310  53 348  65 376 124  77 218  98 194  19  31 174 237  75  16 358
[137]   9  50  92 122 152 386 207 244 229 350 355 391 223 373 309 140 126
[154] 349 344 319 258  15 271 388 195 201 318  17 212 127 133  41 384 392
[171] 159 117  72  36 315 294 157 378 313 306 272 106 185  88 281 228 238
[188] 368  80  30  93 234 220 240 369 164

         用 lm() 函数中的 subset 选项,只用训练集中的观测来拟合一个线性回归模型。

> lm.fit=lm(mpg~horsepower,data=Auto,subset=train)

       现在用 predict ()函数来估计全部 392 个观测的响应变量,再用 mean() 函数来计算验证集中 196 个观测的均方误差。注意一下,下面的 -train 指标意味着只选取不在训练集中的观测。(说明:‘-’就是subset)

> attach(Auto)
> mean((mpg-predict(lm.fit,Auto))[-train]^2)
[1] 23.26601

     从以上数据可以看出用线性回归拟合模型所产生的测试的均方误差估计为 23.26601。下面用 poly ()函数来估计用二次和三次多项式回归所产生的测试误差。

> lm.fit2=lm(mpg~poly(horsepower,2),data=Auto,subset=train)#poly函数估计二次
> mean((mpg-predict(lm.fit2,Auto))[-train]^2)
[1] 18.71646
> lm.fit3=lm(mpg~poly(horsepower,3),data=Auto,subset=train)#和三次
> mean((mpg-predict(lm.fit3,Auto))[-train]^2)
[1] 18.79401

       这两个错误率分别为 18.71646 和 18.79401。如果选择了一个不同的训练集的话,那就会在验证集上 得到一个不同的误差。

> set.seed(2)
> train=sample(392,196)
> lm.fit=lm(mpg~horsepower,subset=train)
> mean((mpg-predict(lm.fit,Auto))[-train]^2)
[1] 25.72651
> lm.fit2=lm(mpg~poly(horsepower,2),data=Auto,subset=train)
> mean((mpg-predict(lm.fit2,Auto))[-train]^2)
[1] 20.43036
> lm.fit3=lm(mpg~poly(horsepower,3),data=Auto,subset=train)
> mean((mpg-predict(lm.fit3,Auto))[-train]^2)
[1] 20.38533

        案例分析完毕,小伙伴们学到了没有(*^_^*)
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/474139.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux中UDP程序流程、客户端、服务端

UDP--- 用户数据报协议(User Datagram Protocol),是一个无连接的简单的面向数据报的运输层协议。 优点:传输速度快 缺点:不可靠 socket的中文意思是接插件: 创建socket 在 Python 中 使用socket 模块的类 …

LeetCode 1041. 困于环中的机器人

文章目录1. 题目2. 解题1. 题目 在无限的平面上,机器人最初位于 (0, 0) 处,面朝北方。机器人可以接受下列三条指令之一: “G”:直走 1 个单位“L”:左转 90 度“R”:右转 90 度 机器人按顺序执行指令 ins…

Javascript实现合并单元格

Web上的报表或表格应用,较为复杂的表格操作一般都比较难实现,这里介绍一下用ComponentOne Studio for ASP.NET Wijmo中的SpreadJS,可以实现一些较为复杂的表格操作,个人认为他模仿桌面应用的操作体验非常不错,虽然我并…

R语言第八讲续 评估模型之自助法分析案例

题目 今天来用自助法评估一下ISLR 程序包中的 Portfolio (金融资产)数据集的预测函数 相关资料 自助法(Bootstraping)是另一种模型验证(评估)的方法(之前已经介绍过单次验证和交叉验证)。其以自助采样&…

python中常见的15中面试题

下面这些问题涉及了与Python相关的许多技能,问题的关注点主要是语言本身,不是某个特定的包或模块。每一个问题都可以扩充为一个教程,如果可能的话。某些问题甚至会涉及多个领域。 我之前还没有出过和这些题目一样难的面试题,如果你…

LeetCode 1039. 多边形三角剖分的最低得分(区间DP)

文章目录1. 题目2. 解题1. 题目 给定 N,想象一个凸 N 边多边形,其顶点按顺时针顺序依次标记为 A[0], A[i], ..., A[N-1]。 假设您将多边形剖分为 N-2 个三角形。 对于每个三角形,该三角形的值是顶点标记的乘积,三角剖分的分数是…

CentOS6.4安装包初识

LiveCD 一般用来修复系统使用,有容量很小,不用安装,可以自启动等特性。bin DVD也具有同 样的功能,但是体积较大,所以会有live DVD。   LiveDVD 与LiveCD 相同是不需要安装就直接使用的,要安装的话还是要安…

R语言第九讲 验证集法

目的 为了更好的熟悉分析定性变量的逻辑斯谛回归分析的应用和验证集法(评估拟合拟合模型的一种方法),用一个简单的示例来介绍一下它们在分析数据中的应用。 题目 在 Default 数据集上用income 和 balance 做逻辑斯谛回归来预测 default的概率。现…

总结python中基本的面试题

1.Python是如何进行内存管理的? 答:从三个方面来说,一对象的引用计数机制,二垃圾回收机制,三内存池机制 一、对象的引用计数机制 Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数。 引用计数增加的情况: 1&a…

02.改善深层神经网络:超参数调试、正则化以及优化 W1.深度学习的实践层面

文章目录1. 训练,验证,测试集2. 偏差,方差3. 机器学习基础4. 正则化5. 为什么正则化预防过拟合6. dropout(随机失活)正则化7. 理解 dropout8. 其他正则化9. 归一化输入10. 梯度消失 / 梯度爆炸11. 神经网络权重初始化1…

动态规划 POJ 1088 滑雪

Description Michael 喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个 区域中最长底滑坡。区域由一个二维数组…

R语言第十讲 逻辑斯蒂回归

模型函数介绍 Logistic Regression 虽然被称为回归,但其实际上是分类模型,并常用于二分类。Logistic Regression 因其简单、可并行化、可解释强深受工业界喜爱。 Logistic 回归的本质是:假设数据服从这个Logistic 分布,然后使用极…

网络上总结python中的面试题

【题目:001】| 说说你对zen of python的理解,你有什么办法看到它? Python之禅,Python秉承一种独特的简洁和可读行高的语法,以及高度一致的编程模式,符合“大脑思维习惯”,使Python易于学习、理解和记忆。Python同时采用了一条极简…

阿里云 超级码力在线编程大赛初赛 第3场 题目4. 完美字符串

文章目录1. 题目2. 解题1. 题目 描述 定义若一个字符串的每个字符均为’1’,则该字符串称为完美字符串。 给定一个只由’0’和’1’组成的字符串s和一个整数k。 你可以对字符串进行任意次以下操作 选择字符串的一个区间长度不超过k的区间[l, r],将区间…

(译)Windows Azure的7月更新:SQL数据库,流量管理,自动缩放,虚拟机

Windows Azure的7月更新:SQL数据库,流量管理,自动缩放,虚拟机 今早我们释出一些很棒的Windows Azure更新。这些新的提升包括:SQL数据库:支持SQL自动导出和一个新的高级层SQL数据库选项流量管理:在HTML门户的…

R语言第十一讲 决策树与随机森林

概念 决策树主要有树的回归和分类方法,这些方法主要根据分层和分割 的方式将预测变量空间划分为一系列简单区域。对某个给定待预测的观 测值,用它所属区域中训练集的平均值或众数对其进行预测。 基于树的方法简便且易于解释。但预测准确性通常较低。如图…

python面试题汇总(1)

1. (1)python下多线程的限制以及多进程中传递参数的方式   python多线程有个全局解释器锁(global interpreter lock),这个锁的意思是任一时间只能有一个线程使用解释器,跟单cpu跑多个程序一个意思,大家都是轮着用的&…

阿里云 超级码力在线编程大赛初赛 第3场 题目1. 最大公倍数

文章目录1. 题目2. 解题1. 题目 来源:https://tianchi.aliyun.com/oj/15179470890799741/85251759933690467 2. 解题 看的大佬的解题,很强! class Solution { public:/*** param a: Left margin* param b: Right margin* return: return t…

Javascript:前端利器 之 JSDuck

背景 文档的重要性不言而喻,对于像Javascript这种的动态语言来说就更重要了,目前流行的JDoc工具挺多的,最好的当属JSDuck,可是JSDuck在Windows下的安装非常麻烦,这里就写下来做个备忘。 JSDuck生成的文档效果 JSDuck安…

Ubuntu 扩展内存或断电之后卡在 /dev/sda1 clean 和 /dev/sda1 recovering journal

当ubuntu虚拟机硬盘空间不够用的时候,往往会出现新增扩展硬盘空间之后,出现开机卡死的现象。 通过查阅相关资料,排坑如下: 一、原VM硬盘空间已满 当原VM硬盘空间已满的情况下,千万不要重启或者关机操作,极…