草庐IT

你真的会用K折交叉吗? 对于K折交叉的思考| 防止K折交叉踩坑

51Ann 2023-03-28 原文

作者碎碎念

本文目的:

对于K折交叉,想必大家都知道是什么原理。但是在具体实践中让你写的时候,你可能就会突然疑惑:“咦?道理我都懂,可是这个玩意儿到底怎么用。”

本文就是为了探讨一下什么时候 怎么用 K折交叉验证


K折交叉(k-fold cross validation)

提到K折交叉,我想大部分人都了解其原理了。但是在这里还是先讲一下什么是K折交叉,防止有初学者是进来看什么是K折交叉的。

简言之,就是将数据随机分为K份,使用其中的K-1份依次进行训练,使用剩下的1份作为测试集,比较常见的有五折交叉、十折交叉。

但是实际写代码的时候遇到了问题,现有以下两种K折交叉方法:


方案1 不预先分出测试集

就是我们看书看博客最常见的说法。

  1. 将数据随机均分k份。
  2. 使用其中1份做测试集,剩余k-1份做训练集。
  3. 通过 k 次训练后,我们得到了 k 个不同的模型。
下图是一个五折交叉的例子:

数据量超级少,精度根本提不到85%。到最后以至于我觉得我的2折交叉方法是错的。

方案2 提前分出测试集

  1. 将数据集分为训练集和测试集
  2. 将训练集分为 k 份
  3. 每次使用 k 份中的 1 份作为验证集,其他k-1份作为训练集
  4. 通过 k 次训练后,我们得到了 k 个不同的模型
  5. 从中挑选效果最好的超参数
  6. 使用最好的超参数模型,然后将 k 份数据全部作为训练集重新训练模型,得到最终模型
  7. 使用测试集测试最终的效果
以下也是五折交叉的例子:

分析

看到这里是不是突然开始迷惑了?那我到底该用哪一种?

我们来分析一下:

  • 方案二,预先划分出测试集,训练之后也得到五个模型,但是取出其中较好的一个,测试集之外的所有数据合起来对其二次训练,训练之后作为最终的模型,并使用测试集评价其效果。
  • 方案一,不提前留出测试集,直接所有数据放入模型中一边训练一边测试。这样我们最终会获得5个不同的模型,其之间的效果也会存在差异。
所以这五个模型,你最后要选哪个作为最终方案?

答案是选不出来,因为你没有单独的测试集,五个模型的数据不用,你无法最终验证究竟哪个模型的实际效果更好。

那你可以说:那我也和方案2一样,选出5个中看起来最好的那个模型的参数,然后把所有的数据塞回去重新训练……


你清醒一点,你一开始就没划分测试集,所以你不能把所有的数据再组合起来塞回去训练。因为训练完了你也没测试集看你训练的结果。

那你又说:得到五个模型之后,我再把数据集划分出来,只取所有数据中的一部分作为训练集,剩下一部分测评模型。


清醒一点啊!!你怎么敢的!这属于学术作弊!!!你那五个模型怎么来的?所有数据训练出来的K-1份训练出来的!你这属于用训练集测试集混着用了!


第二波分析:

先说个题外话,我们需要注意数据划分的作用

  • 训练集:训练模型,获得模型参数
模型参数怎么来的?不就是通过反向传播自动调整参数?

  • 测试集:测试模型效果
最后测试你训练的模型效果如何。

  • 验证集:调整模型超参数
训练过程中,想知道模型设计的好不好,那我们直接使用测试集测试吗?如果你有全部的数据,你确实可以这么做。但是有时候你可能得不到测试集数据,所以你怎么调参?你就需要自己划分出来一个验证集,检验模型性能。

换句话说就是在训练过程中手动调参,调整模型的超参数。

现在有两个模型放在你面前:


  1. 使用训练集训练,使用测试集测试,效果不好再回去调一调模型超参数。
  2. 使用训练集训练,使用验证集测试,效果不好回去调一调,调好之后使用测试集测试。
如果上述两个模型最终的测试效果是一样的,现在让你选一个模型,你觉得哪个好?我觉得,直觉上第二个模型的泛化性可能会更好。


因为第二个模型是在完全陌生的数据上进行测试,达到了某个效果。

而第一个模型是在对应的测试集上进行调参得到的最终效果,他的“好”可能仅限于那块测试集的数据,在其他数据上效果不一定比得过第二个模型。

现在回到我们的K折交叉。

方案1中只划分了训练集和测试集,如果你要调参,直接使用测试集调。

方案2中划分了训练集、验证集、测试集,你调参用验证集调,测试集仅作为最终模型测试。

那现在我们就明白了:

  • 方案1中:使用测试集调整超参数的话,我们是尽力找到一个超参数能让所有的K-1个模型表现都更好一点,是为了找到比较好的一组超参数。
  • 方案2中:使用验证集调整超参数,选出五个模型中看起来最好的,再使用训练集之外的所有数据再训练,最终使用测试集测试效果,这是为了选出一个最终可用的模型。
那我们就可以得出结论了。

所以什么时候用哪种?

方案1 不预先分出测试集:适用于评价模型效果,但是你没办法选出一个具体参数的模型。

就是当你说:我这个模型好!

好在哪里?

我进行K折交叉!出来的五个模型在我设计的超参数之下准确率都不错,所以我这个模型设计的挺好。

那让我用用你这个模型,什么参数下效果最好?

那我就不知道了,选不出来。

方案2 提前留出测试:适用于选择合适的模型。

我需要最终得到一个模型,你必须得要一个具体的模型,不仅有超参数,还要有一组能让模型表现“最好”的参数。这时候你就需要用方案2。


作者碎碎念,本文的写作初衷

月初时候写大作业,要求使用2折交叉验证,

起初我用的方案1,就是提前分出来测试集。然后我闲着没事和师姐交流了一下,师姐说:

???我突然就开始怀疑人生,是我做错了吗?

然后我开始查资料,越查越迷惑。直到最后师哥给我解答了疑惑:

有关你真的会用K折交叉吗? 对于K折交叉的思考| 防止K折交叉踩坑的更多相关文章

  1. ruby-on-rails - Rails 3.2 防止使用错误保存对象 - 2

    我有一个ActiveRecord对象,我想在不对模型进行永久验证的情况下阻止它被保存。您过去可以使用errors.add执行类似的操作,但它看起来不再有效了。user=User.lastuser.errors.add:name,"namedoesn'trhymewithorange"user.valid?#=>trueuser.save#=>true或user=User.lastuser.errors.add:base,"myuniqueerror"user.valid?#=>trueuser.save#=>true如何在不修改用户对象模型的情况下防止将用户对象保存在Rails3.2中

  2. ruby-on-rails - 我真的需要在 Rails 中使用 csv gem 吗? - 2

    我的问题很简单:我是否必须在使用RubyonRails的类上require'csv'?如果我打开一个railsconsole并尝试使用CSVgem它可以工作,但我必须在文件中这样做吗? 最佳答案 CSVlibrary是ruby​​标准库的一部分;它不是gem(即第三方库)。与所有标准库(与核心库不同)一样,csv不会由ruby​​解释器自动加载。所以是的,在您的应用程序中某处您确实需要要求它:irb(main):001:0>CSVNameError:uninitializedconstantCSVfrom(irb):1from/Us

  3. ruby - 防止SQL注入(inject)/好的Ruby方法 - 2

    Ruby中防止SQL注入(inject)的好方法是什么? 最佳答案 直接使用ruby?使用准备好的语句:require'mysql'db=Mysql.new('localhost','user','password','database')statement=db.prepare"SELECT*FROMtableWHEREfield=?"statement.execute'value'statement.fetchstatement.close 关于ruby-防止SQL注入(inject

  4. ruby-on-rails - ruby 真的是一种完全面向对象的语言吗? - 2

    Ruby是完全面向对象的语言。在ruby​​中,一切都是对象,因此属于某个类。例如5属于Objectclass1.9.3p194:001>5.class=>Fixnum1.9.3p194:002>5.class.superclass=>Integer1.9.3p194:003>5.class.superclass.superclass=>Numeric1.9.3p194:005>5.class.superclass.superclass.superclass=>Object1.9.3p194:006>5.class.superclass.superclass.superclass.su

  5. ruby-on-rails - 如何防止错误 "code converter not found (UTF-8)"? - 2

    我在生产环境(CentOS5.6)中遇到此错误,但在开发环境(Ubuntu11.04)中运行良好。在这两种环境中,该应用程序都使用Ruby1.9.3和Rails3.0.9,并由passenger和nginx提供服务。我的Mechanizegem版本是2.3。未找到代码转换器(UTF-8)此代码的最后一行触发它:mech=Mechanize.newpage=mech.get("http://myurl.com/login.php?login_name=a&password=b")form=page.form_with(:name=>"loginForm")form.field_with(

  6. ruby-on-rails - 对于 Ruby 应用程序,是否有比 Sanitize 更好的替代方案? - 2

    我爱Sanitize.这是一个了不起的实用程序。我遇到的唯一问题是,它需要永远准备一个开发环境,因为它使用Nokogiri,这对编译时间来说是一种痛苦。是否有任何程序可以在不使用Nokogiri的情况下执行Sanitize的操作(如果没有别的,只是温和地执行它的操作)?这将以指数方式提供帮助! 最佳答案 Rails有自己的SanitizeHelper。根据http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html,它将Thissanitizehe

  7. ruby-on-rails - Rails 3 Cli 执行命令真的很慢吗? - 2

    有人知道为什么我的rails3.0.7cli这么慢吗?当我运行railss或railsg时,他大约需要5秒才能真正执行命令...有什么建议吗?谢谢 最佳答案 更新:我正在将我的建议从rrails切换到rails-sh,因为前者支持REPL,而rrails不是用例。此外,当与ruby​​环境结合使用时,修补似乎确实可以提高性能变量,现在反射(reflect)在答案中。一个可能的原因可能是这个performancebuginruby每当在ruby​​代码中使用“require”时,它就会调用一些代码(更多详细信息here)。在使用Rai

  8. ruby-on-rails - 对于诸如libyaml之类的已编译库,Ruby(或RVM)在文件系统中搜索哪些位置以加载或解析它们? - 2

    操作系统:CentOS6.2x86_64很抱歉缩进太古怪了。这是我的第一篇SO帖子,我是新来设置服务器的。不过,我正在学习,并将详细说明我尝试解决此问题所采取的步骤以及寻求帮助的地方。我是一位有抱负的年轻Web开发人员,并且我在其他人配置的服务器上工作,因此,这对我来说是全新的。我正在准备我最近购买的用于运行Rails应用程序的linode。我遵循了此处http://blog.blenderbox.com/2011/01/07/installing-rvm-ruby-rails-passenger-nginx-on-centos/提供的初始安装指南,并更改了步骤:sudobash反射(

  9. 最近火热的“数字藏品”,你真的了解吗? - 2

    最近火热的“数字藏品”,你真正了解吗?其实有很多人会把数字藏品跟NFT混为一谈,但其实这两者还是有差别的。数字藏品并不等同于NFT数字藏品是什么?直观来看,它可能就是一张数字化照片或视频,甚至就只是一串数字。但它却是一件对应特定作品、艺术品生成的包含着大量数字信息且拥有唯一加密信息的可以买卖交易的收藏品。NFT则是指一种基于以太坊区块链的“非同质化代币”。它在百度百科里的释义是“用于表示数字资产(包括jpg和视频剪辑形式)的唯一加密货币令牌,可以买卖”。比如已被很多人认识的比特币就是NFT的一种。NFT在元宇宙中发挥的作用是巨大的,目前正是它在支撑着元宇宙中的经济体系。数字藏品其实也是NFT的

  10. 企业大数据发展面临问题之存算分离技术思考 - 2

    文章目录概述背景为何要存算分离优势**应用场景**存算分离产品技术流派华为JuiceFSHashDataXSKY概述背景Hadoop一出生就是奔存算一体设计,当时设计思想就是存储不动而计算(code也即是代码程序)动,负责调度Yarn会把计算任务尽量发到要处理数据所在的实例上,这也是与传统集中式存储最大的不同。为何当时Hadoop设计存算一体的耦合?要知道2006年服务器带宽只有100Mb/s~1Gb/s,但是HDD也即是磁盘吞吐量有50MB/s,这样带宽远远不够传输数据,网络瓶颈尤为明显,无奈之举只好把计算任务发到数据所在的位置。众观历史常言道天下分久必合合久必分,随着云计算技术的发展,数据

随机推荐