-
2022-06-01 23:30:09
1.什么是训练集、验证集和测试集?
训练集,即:训练的集合,是用来训练模型的数据集合。通过这部分数据,
学习
得到一个模型。训练集可以当做高中刷题的题库,训练的过程可以比作高中生学习的过程。测试集,即:测试的集合,是用来检验或者说验证模型的数据集合。通过这部分数据,可以验证学习的好坏。测试集可以当做高考的试题,测试的过程可以比作参加高考。
理解上述两个概念以后,那学习的过程我们就可以捋清楚了:
通过学习(理解成“训练”的过程),让自己变得更好(把自己当成“模型”)。通过3年的学习(训练了3年),参加高考(理解成“测试”的过程),检验自己学得好不好。注意注意!此时此刻我其实隐含了一个假设条件,就是你参加完高考以后不能凭借着考场的回忆再去刷题,就是高考完以后你脑子就回到了高一入学的状态重新学习3年参加高考,高考如果不理想脑子又回到了高一入学的状态重新学习3年参加高考……在机器学习中,也就是说:“训练集”不能用于训练更新模型。当测试效果发现不行时,从头开始训练,不能含有一点记忆。
那么问题来了:我花了3年时间去训练,高考完了发现没学好、高考分数很低怎么办?时间都白白浪费了,但还没有学好。有的人可能说,那就再来3年呗。好,那咱们就再来3年,再来3年就一定会好吗?是不一定的,再来3年,再来10个3年也不是一定可以学好的。那训练不好就重新训练,那什么时候是个头呀?
所以,此时又有人想出了一个办法,我们每半年参加1次模拟考试,检验一下学习效果,及时调整学习策略。这,就是验证集(模拟考试的题库)
验证集,就是用来检验模型数据的集合。
此时可以适当总结下:验证集≠测试集(模拟成绩≠高考成绩,模拟成绩好可能高考大概率会好,但不代表高考成绩一定好)
2.什么是K折交叉验证?
K折交叉验证
,是一种动态的验证方式
。以 K 取10为例,将数据集(此数据集非机器学习中的数据集,而是指一种数据的集合,只是为了解释分组问题的一个概念)划分成10份,将每份数据分别标记为1号、2号、3号、4号、5号、6号、7号、8号、9号、10号。每次训练用1份
作为验证集,其余9份
作为验证集,如下表所示。1号 2号 3号 4号 5号 6号 7号 8号 9号 10号 第1次 训练 训练 训练 训练 训练 训练 训练 训练 训练 验证
第2次 训练 训练 训练 训练 训练 训练 训练 训练 验证
训练 第3次 训练 训练 训练 训练 训练 训练 训练 验证
训练 训练 第4次 训练 训练 训练 训练 训练 训练 验证
训练 训练 训练 第5次 训练 训练 训练 训练 训练 验证
训练 训练 训练 训练 第6次 训练 训练 训练 训练 验证
训练 训练 训练 训练 训练 第7次 训练 训练 训练 验证
训练 训练 训练 训练 训练 训练 第8次 训练 训练 验证
训练 训练 训练 训练 训练 训练 训练 第9次 训练 验证
训练 训练 训练 训练 训练 训练 训练 训练 第10次 验证
训练 训练 训练 训练 训练 训练 训练 训练 训练 问1: 那为什么要用验证集?
答1: 用来调整超参数的。问2: 比如分类问题中用到了激活函数,但不知道使用relu还是tanh函数的准确率更高,该怎么办?
答2: 那就用relu函数来训练10次得到10份验证集上的准确率,将10份准确率取个均值作为relu函数的代表。再用tanh函数来训练10次得到10份验证集上的准确率,将10份准确率取个均值作为tanh函数的代表。将这两个准确率进行比较,哪个准确率高,就说明哪个激活函数更好。
当确定好某个函数的准确率好时,就是用该激活函数,再将全部数据
作为训练集
训练,然后在测试集
上进行测试
即可。这么做的优点是:
- 使用了
验证集
,可以检验学习的好坏。 - 每份数据都当过验证集、也都当过训练集,不会存在因数据问题带来模型偏差。
- 充分训练了模型(毕竟每份数据被用来训练了9次),当数据量小时起到了“扩充”训练数据的作用。
- 可以挑选出最佳的超参数。
3.数据集划分过程
- 将数据集分为训练集和测试集,将测试集放在一边先不管。
- 已知目前有 N 组超参数组合(将从 N 组中挑选出最好的1组)。
- 对每个超参数组而言,将训练集分为 K 份。每次使用 K 份中的 1 份作为验证集,其他 K-1 份作为训练集。通过 K 次训练后,我们得到了 K 个不同的评价指标。将 K 个评价指标取均值作为该超参数组的代表。
- 循环 N 次,获得 N 个超参数组对应的评价指标的均值,取其中最好的一个超参数组。
- 使用最优的超参数,然后将 K 份数据全部作为训练集重新训练模型,得到最终模型,然后直接在测试集上测试即可。
3.应用场景及注意事项
3.1.应用场景
- 数据量较小时,会使用 K 折交叉验证。K 折交叉验证可以起到“扩充”数据的作用。
- 超参数多,不知道该选哪个合适,会用到K折交叉验证。
3.2.注意事项
- K 折交叉验证,不是 K 折交叉测试(这在好多文章中都搞混了),测试集是不能用来更新模型和调整超参数的。我们将数据分成K份的目的是来验证数据的,不是来测试数据的。验证≠测试。
- 可以将 K 折交叉验证,概括为 N 次 K 折交叉验证。N 是指超参数组的数量,需要从 N 个超参数组中选出最好的一个来;K 是指交叉验证划分的数量,一般取5或者10。
更多相关内容 - 使用了
-
Python实现K折交叉验证法的方法步骤
2020-12-31 13:05:08常用的方法有两种,k折交叉验证法和自助法。介绍这两种方法的资料有很多。下面是k折交叉验证法的python实现。 ##一个简单的2折交叉验证 from sklearn.model_selection import KFold import numpy as np X=np.array... -
多层感知机(MLP)(三层)(UCI乳腺癌数据库)(k折交叉验证)(反向传递)(机器学习,神经网络)
2020-05-28 21:24:09多层感知机(MLP)(三层)(UCI乳腺癌数据库)(k折交叉验证)(反向传递)(机器学习,神经网络) -
K折交叉验证:传统的求准确度的方法是将整个数据分为训练集和测试集,并根据测试数据计算出准确度,但这并...
2021-02-09 16:42:24K折交叉验证:传统的求准确度的方法是将整个数据分为训练集和测试集,并根据测试数据计算出准确度,但这并不是最佳方法,因此我们采用K折交叉验证是许多精度的平均值,并且它还提供了精度的标准偏差,这是评估模型的... -
matlab-K折交叉验证与分层K折交叉验证
2020-10-12 21:21:09K折交叉验证的要点:(文字版)如何实现K折交叉验证(图片版)如何实现K折交叉验证(matlab版)为啥我们需要分层K折交叉验证?如何实现分层k折交叉验证如何实现分层k折交叉验证(文字版)如何实现分层k折交叉验证(图片...文章目录
很多论文都会用到K折交叉验证,但是我以前实验一直没有做这个步骤,最近整理了一下关于这个方面的资料,其实就是把看到的文字资料整理一下,有些文字自己进行了突出和调整,感谢所有博主,最后是我的matlab版的分层交叉验证,通过这一段的学习,最大的感受就是 python 好,python好,python 好,真是令人忧伤啊。。。
分层K折交叉验证是K折交叉验证的一个变种, 适用于不平衡的数据集,所以先介绍K折交叉验证,之后再介绍分层K折交叉验证。K折交叉验证有什么用?
用法1:常用的精度测试方法主要是交叉验证,例如10折交叉验证(10-fold cross validation,CV),将数据集分成平均分成互斥的十份,轮流将其中9份做训练1份做验证,10次的结果的均值作为对算法精度的估计,一般还需要进行多次10折交叉验证求均值,例如:10次10折交叉验证,以求更精确一点。
来源——参考博客1: https://blog.csdn.net/Dream_angel_Z/article/details/47110077?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-6.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-6.channel_param用法2:一般情况将K折交叉验证用于模型调优,找到使得模型泛化性能最优的超参值。找到后,在全部训练集上重新训练模型,并使用独立测试集对模型性能做出最终评价。
来源——参考博客2:https://blog.csdn.net/ChenVast/article/details/79257097?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160249987519725222451761%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=160249987519725222451761&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v2~rank_blog_v1-1-79257097.pc_v2_rank_blog_v1&utm_term=k%E6%8A%98&spm=1018.2118.3001.4187
关于这两种用法,我目前看到的论文中,几乎都是第1种,我也是为了精度测试方法来学习k折交叉验证的,第2种用法没怎么看到过,所以记录一下啊,仅供参考。如何实现K折交叉验证?
K折交叉验证的要点:(文字版)
1:数据集划分为K个相同大小的互斥子集。
2:每次用K-1个集合训练,剩下的1个做测试集,得到结果。
3:循环K次,得到K个结果,至此1次完整的K折交叉验证结束
来源——参考博客3(有改动):https://baijiahao.baidu.com/s?id=1677821446173455536&wfr=spider&for=pc
这个是博主:桔子的算法之路写的,,但是我觉得他原文比较像是分层K折交叉验证,所以我就改了一点点如何实现K折交叉验证(图片版)
图片比文字直观,下面的图很清楚地告诉我们,大小相同、互斥、以及具体的过程,图片来源,依旧是参考博客2:https://blog.csdn.net/ChenVast/article/details/79257097?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160249987519725222451761%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=160249987519725222451761&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v2~rank_blog_v1-1-79257097.pc_v2_rank_blog_v1&utm_term=k%E6%8A%98&spm=1018.2118.3001.4187
如何实现K折交叉验证(matlab版)
这个之前有特地整理过了,代码来自博主:野狗汪汪汪,这里再贴一下mattlab代码,博客地址:https://blog.csdn.net/weixin_41274837/article/details/90169268
data=double(xtrain'); label=double(ytrain'); %要求数据集每一行代表一个样本 ;label每行为标签 [M,N]=size(data); % M:总样本量; N:一个样本的元素总数 indices=crossvalind('Kfold',data(1:M,N),5); %进行随机分包 for k=1:5 %交叉验证k=10,10个包轮流作为测试集 test = (indices == k); %获得test集元素在数据集中对应的单元编号 train = ~test; %train集元素的编号为非test元素的编号 train_data=data(train,:);%从数据集中划分出train样本的数据 train_label=label(train,:); test_data=data(test,:); %test样本集 test_label=label(test,:); end
这个代码的具体原理可以参考这个博客,来源——参考博客7:https://blog.csdn.net/IT_flying625/article/details/102995537
至此,k折交叉验证的内容全部介绍完毕,下面是分层交叉验证的内容为啥我们需要分层K折交叉验证?
K折交叉验证和分层k折交叉验证的区别,字面上看就是多了个分层,那么为啥要分层呢,前面有说到,分层k折交叉验证是适用于不平衡的数据集的,依然是参考博客2写道:
K折交叉验证改进成的分层K折交叉验证:
获得偏差和方差都低的评估结果,特别是类别比例相差较大时。
那么为什么类别比例相差比较大的时候(就是数据集不平衡时),不分层的k折交叉验证得到的结果不准确呢?请参考这个回答http://sofasofa.io/forum_main_post.php?postid=1000505&:
对于非平衡分类,stratified CV(这里指分层的k折交叉验证)的优点就更加明显了。如果二元分类中分类A只占有0.01%,分类B占有99.99%,当你使用常规的交叉验证的时候,可能你的训练集里甚至都没有足够的A来训练,或者测试集里A的数量极少,严重影响了验证结果的可靠性。
怎么理解这个影响可靠性,换句话来说,假设整个数据集100张图,进行5折交叉验证,那么一折就有20张图,假设两个类A和B比例是1:9,运气非常差的情况下,某一折的过程中,所有的A(10个样本)全部分为测试集,训练集中一张都没有A,那么相当于老师讲课没有说这个类型题(训练),考试(测试)还考到了,考的差(评估结果差)就说你水平(这个模型效果不好),这个说法一看就知道不对劲。而越是不平衡的数据集,越有可能出现这种情况,所以我们要通过分层,来让每一折的——不管是训练集还是测试集——每个类的比例都尽量和原来的数据集保持一样,这就类似于,老师平时讲的多的东西,考试占的分也多,然后我们考很多次试,取评分,这个才能比较客观地体现出你的能力,如果是一个平衡的数据集,如果你某一次考试考的特别好或者特别差,这都不是你的真实水平,K折交叉验证通过让你考很多次,取平均分可以避免这种情况,但是不平衡的数据集,K折交叉就好像你参加的考试本身就有些问题,考很多次也不能体现你的真实水平,而分层K折交叉验证就可以解决这个问题。如何实现分层k折交叉验证
如何实现分层k折交叉验证(文字版)
分层交叉验证(Stratified k-fold cross validation):首先它属于交叉验证类型,分层的意思是说在每一折中都保持着原始数据中各个类别的比例关系,比如说:原始数据有3类,比例为1:2:1,采用3折分层交叉验证,那么划分的3折中,每一折中的数据类别保持着1:2:1的比例,这样的验证结果更加可信。
来源——参考博客5:https://www.cnblogs.com/ysugyl/p/8707887.html如何实现分层k折交叉验证(图片版)
这张图可以直观感受一下啥叫分层k折交叉验证,这是我找到的最好的一张图了,只看下面那个部分就好了,图片来源——参考博客4:https://blog.csdn.net/ssswill/article/details/85267864
因此正如原博客所说的:分层保证了每个折中类别之间的比例与整个数据集中的比例相同。如何实现分层K折交叉验证(matlab版)
看了一圈,好像程序都是python的,难过,以后要自学python啊!!!感觉python开源,资料比较丰富,matlab闭源再加上之前哈工大那个新闻,哎,好麻烦啊…
我没找到分层k折交叉验证的代码,所以自己改了一下,基础代码就是之前那个很工整但是没跑过的代码,转载的时候没跑过,但是现在跑过了,果然很漂亮啊,和他的程序比起来,我的这个程序一点也不智能,类别数还要自己写,而且也没有抽象成函数,但是记录一下吧,毕竟这个地方卡了这么久。
思路就是用上面的k折交叉验证把每个类单独分成k份,然后再合并在一起。Data有两种,一个是特征,一个是标签,两种都进行类似的操作。
下面这个是程序,我的是8分类,在k折交叉验证的基础上改的,原来的代码来源——参考博客6:https://blog.csdn.net/u010513327/article/details/80560750?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.channel_param
人家写得好工整啊,为啥我的就显得很乱呢…
程序中有一个num_in_class
,我的是8分类问题,所以是这样一个东西,这个变量代表了每一类有多少个样本,前提是你的样本数据集要同一个类都放在一起,然后第1类,第2类,第3类这样一直排下去。
%需要先载入特征和标签,没有对应的mat文件的话会报错,所以要根据自己的情况改 clc clear all tic load features1%第一种特征 load features2%第2种特征 load Labels features=[features1,features2];%把两个矩阵横向拼起来起来,注意中间是逗号,不是分号 num_in_class=[713,1343,1165,728,1217,713,1378,795];%说明第一类有713张图片,第2类有1343张图片,以此类推,需要改成自己的数据。 classnums=length(num_in_class);%类别数为classnums,这一步是为了把每一类都取出来,注释掉的是手动的,下面是自动的,功能一样,我觉得我的自动的没有错...但是不敢打包票.... % features_lei1=features(1:713,:);%这个步骤不是自动化的,是自己把num_in_class的东西用excel累计求和,features矩阵第一行到第713行的所有数据数据是类别1 % features_lei2=features(713+1:2056,:);%features矩阵第713+1行到第2056行的所有数据数据是类别2,2026=713+1343 % features_lei3=features(2056+1:3221,:); % features_lei4=features(3221+1:3949,:); % features_lei5=features(3949+1:5166,:); % features_lei6=features(5166+1:5879,:); % features_lei7=features(5879+1:7257,:); % features_lei8=features(7257+1:8052,:); features_lei1=features(1:num_in_class(1),:);%这个步骤是自动化的,其实是确定上面的没问题后,改出来的 lei2_end=num_in_class(1)+num_in_class(2); features_lei2=features(num_in_class(1)+1:lei2_end,:); lei3_end=lei2_end+num_in_class(3); features_lei3=features(lei2_end+1:lei3_end,:); lei4_end=lei3_end+num_in_class(4); features_lei4=features(lei3_end+1:lei4_end,:); lei5_end=lei4_end+num_in_class(5); features_lei5=features(lei4_end+1:lei5_end,:); lei6_end=lei5_end+num_in_class(6); features_lei6=features(lei5_end+1:lei6_end,:); lei7_end=lei6_end+num_in_class(7); features_lei7=features(lei6_end+1:lei7_end,:); lei8_end=lei7_end+num_in_class(8); features_lei8=features(lei7_end+1:lei8_end,:); % Labels_lei1=Labels(1:713,:);%这个步骤不是自动化的,是自己把num_in_class的东西用excel累计求和 % Labels_lei2=Labels(713+1:2056,:); % Labels_lei3=Labels(2056+1:3221,:); % Labels_lei4=Labels(3221+1:3949,:); % Labels_lei5=Labels(3949+1:5166,:); % Labels_lei6=Labels(5166+1:5879,:); % Labels_lei7=Labels(5879+1:7257,:); % Labels_lei8=Labels(7257+1:8052,:); Labels_lei1=Labels(1:num_in_class(1),:);%这个步骤是自动化的,其实是确定上面的没问题后,改出来的 Labels_lei2=Labels(num_in_class(1)+1:lei2_end,:); Labels_lei3=Labels(lei2_end+1:lei3_end,:); Labels_lei4=Labels(lei3_end+1:lei4_end,:); Labels_lei5=Labels(lei4_end+1:lei5_end,:); Labels_lei6=Labels(lei5_end+1:lei6_end,:); Labels_lei7=Labels(lei6_end+1:lei7_end,:); Labels_lei8=Labels(lei7_end+1:lei8_end,:); %% k折交叉验证 %交叉验证 k =5;%预将数据分成5份 sum_accuracy_svm = 0; %% 类别1 [m,n] = size(features_lei1); %交叉验证,使用k折交叉验证 Kfold %indices为 m 行一列数据,表示每个训练样本属于k份数据的哪一份 indices_1 = crossvalind('Kfold',m,k); %% 类别2 [m,n] = size(features_lei2); %交叉验证,使用k折交叉验证 Kfold %indices为 m 行一列数据,表示每个训练样本属于k份数据的哪一份 indices_2 = crossvalind('Kfold',m,k); %% 类别3 [m,n] = size(features_lei3); %交叉验证,使用k折交叉验证 Kfold %indices为 m 行一列数据,表示每个训练样本属于k份数据的哪一份 indices_3 = crossvalind('Kfold',m,k); %% 类别4 [m,n] = size(features_lei4); %交叉验证,使用k折交叉验证 Kfold %indices为 m 行一列数据,表示每个训练样本属于k份数据的哪一份 indices_4 = crossvalind('Kfold',m,k); %% 类别5 [m,n] = size(features_lei5); %交叉验证,使用k折交叉验证 Kfold %indices为 m 行一列数据,表示每个训练样本属于k份数据的哪一份 indices_5 = crossvalind('Kfold',m,k); %% 类别6 [m,n] = size(features_lei6); %交叉验证,使用k折交叉验证 Kfold %indices为 m 行一列数据,表示每个训练样本属于k份数据的哪一份 indices_6 = crossvalind('Kfold',m,k); %% 类别7 [m,n] = size(features_lei7); %交叉验证,使用k折交叉验证 Kfold %indices为 m 行一列数据,表示每个训练样本属于k份数据的哪一份 indices_7 = crossvalind('Kfold',m,k); %% 类别8 [m,n] = size(features_lei8); %交叉验证,使用k折交叉验证 Kfold %indices为 m 行一列数据,表示每个训练样本属于k份数据的哪一份 indices_8 = crossvalind('Kfold',m,k); for i = 1:k % 针对第1类划分训练集和测试集 test_indic_1 = (indices_1 == i); train_indic_1 = ~test_indic_1; train_datas_1 = features_lei1(train_indic_1,:);%找出训练数据与标签 train_labels_1 = Labels_lei1(train_indic_1,:); test_datas_1 = features_lei1(test_indic_1,:);%找出测试数据与标签 test_labels_1 = Labels_lei1(test_indic_1,:); % 针对第2类划分训练集和测试集 test_indic_2 = (indices_2 == i); train_indic_2 = ~test_indic_2; train_datas_2 = features_lei2(train_indic_2,:);%找出训练数据与标签 train_labels_2 = Labels_lei2(train_indic_2,:); test_datas_2 = features_lei2(test_indic_2,:);%找出测试数据与标签 test_labels_2 = Labels_lei2(test_indic_2,:); % 针对第3类划分训练集和测试集 test_indic_3 = (indices_3 == i); train_indic_3 = ~test_indic_3; train_datas_3 = features_lei3(train_indic_3,:);%找出训练数据与标签 train_labels_3 = Labels_lei3(train_indic_3,:); test_datas_3 = features_lei3(test_indic_3,:);%找出测试数据与标签 test_labels_3 = Labels_lei3(test_indic_3,:); % 针对第4类划分训练集和测试集 test_indic_4 = (indices_4 == i); train_indic_4 = ~test_indic_4; train_datas_4 = features_lei4(train_indic_4,:);%找出训练数据与标签 train_labels_4 = Labels_lei4(train_indic_4,:); test_datas_4 = features_lei4(test_indic_4,:);%找出测试数据与标签 test_labels_4 = Labels_lei4(test_indic_4,:); % 针对第5类划分训练集和测试集 test_indic_5 = (indices_5 == i); train_indic_5 = ~test_indic_5; train_datas_5 = features_lei5(train_indic_5,:);%找出训练数据与标签 train_labels_5 = Labels_lei5(train_indic_5,:); test_datas_5 = features_lei5(test_indic_5,:);%找出测试数据与标签 test_labels_5 = Labels_lei5(test_indic_5,:); % 针对第6类划分训练集和测试集 test_indic_6 = (indices_6 == i); train_indic_6 = ~test_indic_6; train_datas_6 = features_lei6(train_indic_6,:);%找出训练数据与标签 train_labels_6 = Labels_lei6(train_indic_6,:); test_datas_6 = features_lei6(test_indic_6,:);%找出测试数据与标签 test_labels_6 = Labels_lei6(test_indic_6,:); % 针对第7类划分训练集和测试集 test_indic_7 = (indices_7 == i); train_indic_7 = ~test_indic_7; train_datas_7 = features_lei7(train_indic_7,:);%找出训练数据与标签 train_labels_7 = Labels_lei7(train_indic_7,:); test_datas_7 = features_lei7(test_indic_7,:);%找出测试数据与标签 test_labels_7 = Labels_lei7(test_indic_7,:); % 针对第8类划分训练集和测试集 test_indic_8 = (indices_8 == i); train_indic_8 = ~test_indic_8; train_datas_8 = features_lei8(train_indic_8,:);%找出训练数据与标签 train_labels_8 = Labels_lei8(train_indic_8,:); test_datas_8 = features_lei8(test_indic_8,:);%找出测试数据与标签 test_labels_8 = Labels_lei8(test_indic_8,:); % 合并 train_datas = [train_datas_1;train_datas_2;train_datas_3;train_datas_4;train_datas_5;train_datas_6;train_datas_7;train_datas_8]; train_labels =[train_labels_1;train_labels_2;train_labels_3;train_labels_4;train_labels_5;train_labels_6;train_labels_7;train_labels_8]; test_datas = [test_datas_1;test_datas_2;test_datas_3;test_datas_4;test_datas_5;test_datas_6;test_datas_7;test_datas_8]; test_labels =[test_labels_1;test_labels_2;test_labels_3;test_labels_4;test_labels_5;test_labels_6;test_labels_7;test_labels_8]; % 开始svm多分类训练,fitcsvm用于二分类,fitcecoc用于多分类, classifer = fitcecoc(train_datas,train_labels);%训练模型 predict_label = predict(classifer, test_datas);%测试 fprintf('第%d折\n',i) disp('分类正确率:'); accuracy_svm = length(find(predict_label == test_labels))/length(test_labels)%正确率 sum_accuracy_svm = sum_accuracy_svm + accuracy_svm; end mean_accuracy_svm = sum_accuracy_svm / k; disp('平均准确率:'); disp( mean_accuracy_svm); toc
再次感谢以上所有的博主们!!!
-
K折交叉验证
2021-10-23 15:51:42用鸢尾花数据来展示k折验证效果 # 导入鸢尾花数据集 from sklearn.datasets import load_iris from sklearn.model_selection import cross_val_score # 导入用于分类的svc分类器 from sklearn.svm import SVC iris ...首先要讲的就是k折交叉验证的目的(即为什么要用k折交叉验证?)
根本原因:数据有限,单一的把数据都用来做训练模型,容易导致过拟合。(反过来,如果数据足够多,完全可以不使用交叉验证。)较小的k值会导致可用于建模的数据量太小,所以小数据集的交叉验证结果需要格外注意,建议选择较大的k值。k一般取2-10,在样本数量不是很多的情况下,想要检验拟合一个完美的模型,最常见的方法就是K折交叉检验。附代码
用鸢尾花数据来展示k折验证效果
# 导入鸢尾花数据集 from sklearn.datasets import load_iris from sklearn.model_selection import cross_val_score # 导入用于分类的svc分类器 from sklearn.svm import SVC iris = load_iris() x, y = iris.data, iris.target svc = SVC(kernel='linear') # cv 为迭代次数, 这里设置为5 scores = cross_val_score(svc, x, y, cv=5) # 5次,每次的结果 print("交叉验证得分: %.4f %.4f %.4f %.4f %.4f" % (scores[0], scores[1], scores[2], scores[3], scores[4])) # 用得分均值作为最终得分 print("res: %.4f" % (scores.mean()))
-
1.K-Fold 交叉验证概念
在机器学习建模过程中,通行的做法通常是将数据分为训练集和测试集。测试集是与训练独立的数据,完全不参与训练,用于最终模型的评估。在训练过程中,经常会出现过拟合的问题,就是模型可以很好的匹配训练数据,却不能很好在预测训练集外的数据。如果此时就使用测试数据来调整模型参数,就相当于在训练时已知部分测试数据的信息,会影响最终评估结果的准确性。通常的做法是在训练数据再中分出一部分做为验证(Validation)数据,用来评估模型的训练效果。
验证数据取自训练数据,但不参与训练,这样可以相对客观的评估模型对于训练集之外数据的匹配程度。模型在验证数据中的评估常用的是交叉验证,又称循环验证。它将原始数据分成K组(K-Fold),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型。这K个模型分别在验证集中评估结果,最后的误差MSE(Mean Squared Error)加和平均就得到交叉验证误差。交叉验证有效利用了有限的数据,并且评估结果能够尽可能接近模型在测试集上的表现,可以做为模型优化的指标使用。 -
2.举例说明
下面举一个具体的例子来说明K-Fold的过程,比如如下的数据
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
分为K=3组后
Fold1: [0.5, 0.2]
Fold2: [0.1, 0.3]
Fold3: [0.4, 0.6]
交叉验证的时会使用如下三个模型,分别进行训练和测试,每个测试集误差MSE加和平均就得到了交叉验证的总评分
Model1: Trained on Fold1 + Fold2, Tested on Fold3
Model2: Trained on Fold2 + Fold3, Tested on Fold1
Model3: Trained on Fold1 + Fold3, Tested on Fold2 -
3.应用讲解
– 1、 将全部训练集S分成k个不相交的子集,假设S中的训练样例个数为m,那么每一个子集有m/k个训练样例,相应的子集称作{clip_image024}。
– 2、 每次从模型集合M中拿出来一个clip_image010[3],然后在训练子集中选择出k-1个 -
{clip_image026}(也就是每次只留下一个clip_image028),使用这k-1个子集训练clip_image010[4]后,得到假设函数clip_image030。最后使用剩下的一份clip_image028[1]作测试,得到经验错误clip_image032。
– 3、 由于我们每次留下一个clip_image028[2](j从1到k),因此会得到k个经验错误,那么对于一个clip_image010[5],它的经验错误是这k个经验错误的平均。
– 4、 选出平均经验错误率最小的clip_image010[6],然后使用全部的S再做一次训练,得到最后的clip_image012[4]。 -
核心内容:
通过上述1,2,3步进行模型性能的测试,取平均值作为某个模型的性能指标
根据性能指标来挑选出最优模型,再进行上述第4步重新进行训练,获得最终模型
- 疑问解答:
1.为什么不直接拆分训练集与数据集,来验证模型性能,反而采用多次划分的形式,岂不是太麻烦了?
我们为了防止在训练过程中,出现过拟合的问题,通行的做法通常是将数据分为训练集和测试集。测试集是与训练独立的数据,完全不参与训练,用于最终模型的评估。这样的直接划分会导致一个问题就是测试集不会参与训练,这样在小的数据集上会浪费掉这部分数据,无法使模型达到最优(数据决定了程性能上限,模型与算法会逼近这个上限)。但是我们又不能划分测试集,因为需要验证网络泛化性能。采用K-Fold 多次划分的形式就可以利用全部数据集。最后采用平均的方法合理表示模型性能。
2.为什么还要进行所有数据集重新训练,是否太浪费时间?
我们通过K-Fold 多次划分的形式进行训练是为了获取某个模型的性能指标,单一K-Fold训练的模型无法表示总体性能,但是我们可以通过K-Fold训练的训练记录下来较为优异的超参数,然后再以最优模型最优参数进行重新训练,将会取得更优结果。
3.何时使用K-Fold
我认为,数据总量较小时,其他方法无法继续提升性能,可以尝试K-Fold。其他情况就不太建议了,例如数据量很大,就没必要更多训练数据,同时训练成本也要扩大K倍(主要指的训练时间)。
-
-
neural-network-light:具有 k 折交叉验证的随机反向传播
2021-07-17 09:11:26特征监督学习: 随机反向传播交叉验证k折交叉验证虹膜分类示例见交叉验证.sh phil@Eris: ~ /neural-network-light$ ./cross-validation.sh[1418301930132 DataLoader main] loaded 150 training instances in 6ms.... -
深度学习工具箱:该工具箱提供了使用k折交叉验证的卷积神经网络(CNN),这很容易实现。-matlab开发
2021-05-28 23:16:34Jx-DLT:深度学习工具箱 *此工具箱包含卷积神经网络(CNN) * 显示了如何使用带有基准数据集的CNN程序的示例。 请注意,我们使用一到三个卷积层设置来演示CNN。 ...*************************************************... -
Python实现K折交叉验证
2022-05-09 23:17:32当我们的模型训练好之后,我们并不知道模型表现的怎么样,这个时候就可以使用验证集(Validation Dataset)来看看模型在新数据(验证集和测试集是不用的数据)上的表现如何。同时通过调整超参数,让模型处于最好...训练集
训练集(Training Dataset)是用来训练模型使用的,在机器学习的7个步骤中,训练集主要在训练阶段使用。
验证集
当我们的模型训练好之后,我们并不知道模型表现的怎么样,这个时候就可以使用验证集(Validation Dataset)来看看模型在新数据(验证集和测试集是不用的数据)上的表现如何。同时通过调整超参数,让模型处于最好的状态。
验证集有2个主要的作用:
①评估模型效果,为了调整超参数而服务
②调整超参数,使得模型在验证集上的效果最好
验证集不像训练集和测试集,它是非必需的。如果不需要调整超参数,就可以不使用验证集,直接用测试集来评估效果。验证集评估出来的效果并非模型的最终效果,主要是用来调整超参数的,模型最终的效果以测试集的评估结果为准。
测试集
我们通过测试集(Test Dataset)来做最终的评估。通过测试集的评估,我们会得到一些最终的评估指标:准确率、精确率、召回率、F1值等。
三种数据集之间的关系好比:训练集相当于上课学知识;验证集相当于课后的练习题,用来纠正和强化学到的知识;测试集相当于期末考试,用来最终评估学习效果的。
数据划分
- 对于小规模样本集(几万量级),常用的分配比例是 60% 训练集、20% 验证集、20% 测试集
- 对于大规模样本集(百万级以上),只要验证集和测试集的数量足够即可,例如有 100w 条数据,那么留 1w 验证集,1w 测试集即可。1000w 的数据,同样留 1w 验证集和 1w 测试集
- 超参数越少,或者超参数很容易调整,那么可以减少验证集的比例,更多的分配给训练集
k 折交叉验证(k-fold cross validation)
静态的“留出法”对数据的划分方式比较敏感,有可能不同的划分方式得到了不同的模型。“k 折交叉验证”是一种动态验证的方式,这种方式可以降低数据划分带来的影响。具体步骤如下:
- 将数据集分为训练集和测试集,将测试集放在一边
- 将训练集分为 k 份
- 每次使用 k 份中的 1 份作为验证集,其他全部作为训练集
- 通过 k 次训练后,我们得到了 k 个不同的模型
- 评估 k 个模型的效果,从中挑选效果最好的超参数
- 使用最优的超参数,然后将 k 份数据全部作为训练集重新训练模型,得到最终模型
代码
from sklearn.model_selection import KFold kf = KFold(n_splits = 5, shuffle=True, random_state=0) for train_index, test_index in kf.split(data): clt = model.fit(data[train_index], four_label[train_index]) curr_score = curr_score + clt.score(data[test_index], four_label[test_index]) print(clt.score(data[test_index], four_label[test_index])) avg_score = curr_score / 5 print("平均准确率为:", avg_score)
其中data为训练集数据,four_label为标签。n_splits = 5,表示进行5折交叉验证,分别计算每一次的准确率,最后求得平均准确率
-
python中sklearnk折交叉验证
2021-04-26 17:20:29python中sklearnk折交叉验证发布时间:2018-06-10 11:09,浏览次数:492, 标签:pythonsklearnk1.模型验证回顾进行模型验证的一个重要目的是要选出一个最合适的模型,对于监督学习而言,我们希望模型对于未知数据的... -
机器学习基础|K折交叉验证与超参数搜索
2021-07-07 10:12:38文章目录交叉验证交叉验证的概念K的取值为什么要用K折交叉验证Sklearn交叉验证API超参数搜索超参数的概念超参数搜索的概念超参数搜索的原理Sklearn超参数搜索API实例 交叉验证 交叉验证的概念 交叉验证是一种通过... -
K折交叉验证代码
2022-04-01 19:19:50K折交叉验证代码部分 文章目录K折交叉验证代码部分一、K折交叉验证是什么?二、代码1.代码部分2.keras的便捷功能 一、K折交叉验证是什么? 通过每个epoch,将数据划分为K等分,将K-1份作为训练集,其中1份作为验证... -
sklearn的k折交叉验证的详细过程(数据和模型的角度)
2022-07-12 11:03:43前提: 一般博客大家都是介绍K折在数据上的拆分,再加一个sklearn代码的demo,就没...sklearn有现成的k折交叉验证代码,只要看懂了sklearn的流程,体会了它的思路,那么在神经网络上也是一样应用的。分析: 进入,第行 -
威斯康星州诊断-大师:我使用“对数回归模型”来查看肿瘤是良性还是恶性的,并且已经通过k折交叉验证计算了...
2021-02-12 01:16:11乳腺癌威斯康星州诊断大师我已经使用“对数回归和主成分模型”来查看肿瘤是良性还是恶性的,并且已经通过k折交叉验证计算了模型的准确性。 -
Keras入门(八)K折交叉验证
2021-01-24 20:43:19本文将在此基础上介绍如何在Keras中实现K折交叉验证。 什么是K折交叉验证? K折交叉验证是机器学习中的一个专业术语,它指的是将原始数据随机分成K份,每次选择K-1份作为训练集,剩余的1份作为测试集。交叉... -
机器学习笔记 - 基于pytorch和tensorflow的K折交叉验证
2022-05-27 14:17:04K-fold交叉验证是一种更强大的评估技术。 它将原始数据分成K组(K-Fold),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型。使用训练批次,您可以训练您的模型,然后使用测试批次... -
pytorch - K折交叉验证过程说明及实现
2020-02-22 19:09:48以200条数据,十折交叉验证为例子,十折也就是将数据分成10组,进行10组训练,每组用于测试的数据为:数据总条数/组数,即每组20条用于valid,180条用于train,每次valid的都是不同的。 (1)将200条数据,分成按照... -
k折交叉验证
2018-06-14 19:21:04一般情况将K折交叉验证用于模型调优,找到使得模型泛化性能最优的超参值。,找到后,在全部训练集上重新训练模型,并使用独立测试集对模型性能做出最终评价。 K折交叉验证使用了无重复抽样技术的好处:每次迭代过程... -
k折交叉验证(k-fold Cross-validation)
2022-07-25 09:54:35k折交叉验证(k-fold Cross-validation) -
k折交叉验证(R语言)
2020-12-24 21:35:27”k折交叉验证K折交叉验证(k-foldcross-validation)首先将所有数据分割成K个子样本,不重复的选取其中一个子样本作为测试集,其他K-1个样本用来训练。共重复K次,平均K次的结果或者使用其它指标,最终得到一个单一... -
k折交叉验证(原理+python实现)
2022-04-30 13:36:16k折交叉验证的原理及python代码实现,以5折为例 -
R中的 K折交叉验证
2022-05-25 18:24:56一种常用的方法称为k 折交叉验证,它使用以下方法: 1.将数据集随机分成 大小大致相等的k 组或“折叠”。 2.选择一个折叠作为保留集。将模型拟合到剩余的 k-1 个折叠处。计算对折叠中的观察结果的测试 MSE。 3.重复... -
sklearn - k折交叉验证简单使用
2022-01-12 10:54:10k折交叉验证中如何创建自己的评价函数 Sklearn version is 0.24.2 -
K折交叉验证的原理以及实战
2021-12-01 10:03:50目录前言一、交叉验证(Cross-Validation)1-1、LOOCV(Leave-One-Out Cross Validation)1-2、K-fold Cross Validation1-3、k的选取二、K折交叉验证实战。总结 前言 交叉验证的由来:在机器学习的过程中,我们不能...