精华内容
下载资源
问答
  • 交叉代表的意思
    千次阅读 多人点赞
    2020-10-12 21:21:09


    很多论文都会用到K折交叉验证,但是我以前实验一直没有做这个步骤,最近整理了一下关于这个方面的资料,其实就是把看到的文字资料整理一下,有些文字自己进行了突出和调整,感谢所有博主,最后是我的matlab版的分层交叉验证,通过这一段的学习,最大的感受就是 python 好,python好,python 好,真是令人忧伤啊。。。
    分层K折交叉验证是K折交叉验证的一个变种, 适用于不平衡的数据集,所以先介绍K折交叉验证,之后再介绍分层K折交叉验证。

    K折交叉验证有什么用?

    用法1:常用的精度测试方法主要是交叉验证,例如10折交叉验证(10-fold cross validation,CV),将数据集分成平均分成互斥的十份,轮流将其中9份做训练1份做验证,10次的结果的均值作为对算法精度的估计,一般还需要进行多次10折交叉验证求均值,例如:10次10折交叉验证,以求更精确一点。
    来源——参考博客1https://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折交叉验证用于模型调优,找到使得模型泛化性能最优的超参值。找到后,在全部训练集上重新训练模型,并使用独立测试集对模型性能做出最终评价。
    来源——参考博客2https://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折交叉验证(图片版)

    图片比文字直观,下面的图很清楚地告诉我们,大小相同、互斥、以及具体的过程图片来源,依旧是参考博客2https://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
    

    这个代码的具体原理可以参考这个博客,来源——参考博客7https://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的比例,这样的验证结果更加可信。
    来源——参考博客5https://www.cnblogs.com/ysugyl/p/8707887.html

    如何实现分层k折交叉验证(图片版)

    这张图可以直观感受一下啥叫分层k折交叉验证,这是我找到的最好的一张图了,只看下面那个部分就好了,图片来源——参考博客4https://blog.csdn.net/ssswill/article/details/85267864
    在这里插入图片描述
    因此正如原博客所说的:分层保证了每个折中类别之间的比例与整个数据集中的比例相同。

    如何实现分层K折交叉验证(matlab版)

    看了一圈,好像程序都是python的,难过,以后要自学python啊!!!感觉python开源,资料比较丰富,matlab闭源再加上之前哈工大那个新闻,哎,好麻烦啊…
    我没找到分层k折交叉验证的代码,所以自己改了一下,基础代码就是之前那个很工整但是没跑过的代码,转载的时候没跑过,但是现在跑过了,果然很漂亮啊,和他的程序比起来,我的这个程序一点也不智能,类别数还要自己写,而且也没有抽象成函数,但是记录一下吧,毕竟这个地方卡了这么久。
    思路就是用上面的k折交叉验证把每个类单独分成k份,然后再合并在一起。Data有两种,一个是特征,一个是标签,两种都进行类似的操作。
    在这里插入图片描述

    下面这个是程序,我的是8分类,在k折交叉验证的基础上改的,原来的代码来源——参考博客6https://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
    

    再次感谢以上所有的博主们!!!

    更多相关内容
  • 信号交叉口通行能力计算方法探讨,张桂梅,李国文,介绍目前国内外常用的两种计算信号交叉口通行能力的方法(停车线法、冲突点法),以某个具有代表性的信号交叉口为例,通过用两种方�
  • 交叉口分析软件SIDRA INTERSECTION 使用体验 作者李瑞敏 清华大学交通研究所博士 讲师 国家道路交通管理工程技术研究中心副秘书长 Tranbbs 论坛交通图库版...转摘注明出处 作为一款比较有代表性的交叉口分析软件SIDRA
  • 如果你知道如何交叉引用,可以直接跳转到第2节; 如果你知道如何定义编号格式,但是不会交叉引用,可以直接跳转到 1.2 节。 目录1. 交叉引用1.1 定义有序列表1.2 如何交叉引用1.3 为什么要交叉引用2. 交叉引用多个...

    如果你知道如何交叉引用,可以直接跳转到第2节;
    如果你知道如何定义编号格式,但是不会交叉引用,可以直接跳转到 1.2 节。

    1. 交叉引用

    交叉引用只能引用有序列表,所以我们需要先定义参考文献的有序列表。

    1.1 定义有序列表

    如果没有参考文献有序列表 (i.e. [x]) 的朋友,首先先选择下图红框的按钮旁边的向下箭头,选择定义新编号格式

    有序列表

    在定义新编号格式的时候,将编号格式改为下图这样,点击确定即可添加参考文献的编号格式,就可以在上图的红框位置选择该编号格式。

    在这里插入图片描述

    1.2 如何交叉引用

    当我们采用上面的方法添加好编号格式后,我们将光标放到需要插入参考文献的位置,然后执行以下几步:

    1. 点击插入;
    2. 点击交叉引用;
    3. 检查引用类型是不是编号项
    4. 检查引用内容是不是段落编号
    5. 检查插入为超链接是否打钩 (如果打钩了,将鼠标放在插入位置,按住 ctrl 再点击鼠标左键可以直接跳转);
    6. 选择需要插入的参考文献;
    7. 点击插入。

    交叉引用
    (这里第一篇论文是我的处女作 [手动狗头],第二三篇是我很喜欢的两篇论文 [手动狗头])

    如果需要上标的话,选中添加的参考文献,点击如下图所示的按钮即可 (快捷键 ctrl + shift + +,这里第二个 + 就是数字这一排的加号)。

    上标

    1.3 为什么要交叉引用

    交叉引用最大的好处就是,当我们对参考文献的顺序进行改变的时候,我们不需要手动去调整文章中的序号。比如下面的例子,我们先引用了文献 [2]。

    交叉引用1
    但是我们在文献 [1] 和文献 [2] 之间又插入了一个参考文献,那么这时候之前在文章中引用的 [2] 就废弃了,变成了 [3]。

    交叉引用2
    最原始的做法就是,我们手动将之前的 [2] 删除,然后改为 [3]。但是如果我们采用了交叉引用,那么就没有这么麻烦,我们只需要进行以下几步:

    1. 选中我们需要更改的部分 (这里我比较推荐选择全文,如果你更改的参考文献太多了,有可能会导致更新不全面);
    2. 右键点击选中的部分;
    3. 点击更新域即可。

    更新域

    (由于这个环节没法截图,我用手机拍的)

    2. 交叉引用多个参考文献后使用逗号等

    当我们某一句话可能要引用多个参考文献时,如果不作处理就会成为下面这样。

    多个引用
    然而我们发现别人的论文里面都是类似于 [1, 2, 3] 或者 [1-3] 这样优美简练,所以我们也需要进行这样的操作。

    2.1 两篇参考文献

    如果要对两篇参考文献进行操作,我以逗号为例,采用以下几个步骤即可:

    1. 采用交叉引用的方式插入我们需要的参考文献;

    2. 选中插入的参考文献, 右键点击,选择切换域代码
      切换域代码

    3. 在第一个花括号最后添加上 \#"[0",第二个花括号最后添加上 \#"0]" (这里不能用单引号);
      域代码

    4. 选中两个花括号,右键点击,再点击更新域,然后会变为 [xy] (这里 x 和 y 分别代表两个不同的参考文献);
      更新域后

    5. [xy] 中添加上逗号变为 [x, y] 即可。
      两篇参考文献

    2.2 多篇参考文献

    如果要对多篇参考文献进行操作,与上一小节唯一不同的地方在于步骤3。假设我们有4篇参考文献,切换为域代码后,我们同样在第一个花括号的最后添加上 \#"[0",在最后一个花括号的最后添加上 \#"0]",不同的是,对于中间的花括号,每个后面要添加上 \#"0"

    多篇参考文献

    展开全文
  • 现在的训练可能很少用到交叉验证(cross-validate), 因为我现在处理的数据集规模庞大,如果使用交叉验证则会花费很长的时间。但是交叉验证的重要性有目共睹的,无论你是在使用小数据集做算法的改进,还是在Kaggle...

    现在的训练可能很少用到交叉验证(cross-validate), 因为我现在处理的数据集规模庞大,如果使用交叉验证则会花费很长的时间。但是交叉验证的重要性有目共睹的,无论你是在使用小数据集做算法的改进,还是在Kaggle上打比赛,交叉验证都能够帮助我们防止过拟合,交叉验证的重要性已经不止一次的在kaggle的比赛中被证明了,所以请记住这句话:In CV we trust。

    为什么要交叉验证?

    如果不使用交叉验证,我们在训练时会将数据拆分为单个训练集和测试集。模型从训练数据中学习,然后通过预测测试集中所谓看不见的数据来测试其性能。如果对分数不满意,则可以使用相同的集合对模型进行调优,直到 GridSearch(或 Optuna)喊出“够了!”为止。

    以下是此过程可能出现严重错误的多种方式中的两种:

    • 过拟合:这些集合不能很好地代表整体数据。作为一个极端的例子,在具有三个类别(a、b、c)的行中,所有 a 和 b 类别可能最终都在训练集中,而所有 c 都挂在测试集中。或者一个数值变量被拆分,使得某个阈值左侧和右侧的值在训练和集合中分布不均匀。或者接近于两个集合中变量的新分布与原始分布不同以至于模型从不正确的信息中学习。
    • 数据泄漏:在超参数调整期间,可能会将有测试集的信息泄漏到模型中。也就是说我们的使用了未知的数据进行了而训练,那么结果肯定会非常的好,但是在模型应用到真正的未知数据时就会变得很差,这也是过拟合的一种表现。

    如果我们使用 CV ,所有这些问题都迎刃而解。这就是 CV 的神奇之处,如 Sklearn 用户指南中的介绍:

    上面是一个 5 折交叉验证过程的例子,它需要五次训练过程才能完成。 模型使用4折进行训练,并在最后1折进行测试。 模型就可以在所有数据上进行训练和测试,而不会浪费任何数据。

    接下来,用它们的标准偏差作为置信区间报告平均分。这样才能通过所选参数真正判断模型的性能,因为平均分数将代表模型有效地从数据中学习并准确预测未见样本的真正潜力。

    现在,让我们开始介绍5种常用的交叉验证方法,在介绍之前,我们先编写一个快速函数来可视化 CV 的工作方式:

    def visualize_cv(cv, X, y):
        fig, ax = plt.subplots(figsize=(10, 5))
    
        for ii, (tr, tt) in enumerate(cv.split(X, y)):
            p1 = ax.scatter(tr, [ii] * len(tr), c="#221f1f", marker="_", lw=8)
            p2 = ax.scatter(tt, [ii] * len(tt), c="#b20710", marker="_", lw=8)
            ax.set(
                title=cv.__class__.__name__,
                xlabel="Data Index",
                ylabel="CV Iteration",
                ylim=[cv.n_splits, -1],
            )
            ax.legend([p1, p2], ["Training", "Validation"])
    
        plt.show()
    

    使用上面的函数我们可以轻松的可视化我们的分折策略

    KFold

    最简单的是 KFold,如上图所示。 它在 Sklearn 中以相同的名称实现。 让我们将一个具有七个分割的 KFold 传递给可视化函数:

    from sklearn.datasets import make_regression
    from sklearn.model_selection import KFold
    
    X, y = make_regression(n_samples=100)
    
    # Init the splitter
    cv = KFold(n_splits=7)
    
    visualize_cv(cv, X, y)
    

    这就是经典的 KFold 的样子。

    另一个经常使用方式是在执行拆分之前打乱数据。 这通过打乱样本的原始顺序进一步降低了过度拟合的风险:

    cv = KFold(n_splits=7, shuffle=True)
    
    visualize_cv(cv, X, y)
    

    验证样本的索引是以随机的方式选择的。 但是样本总数仍然是整个数据的七分之一,因为我们在做 7 折的 CV。

    KFold 是最常用的 CV ,它很容易理解而且非常有效。 但是根据数据集的特征,有时需要对要使用的 CV 程序有着不同的要求,下面让我们讨论替代方案。

    StratifiedKFold

    StratifiedKFold是为分类问题设计的 KFold 版本 。

    在分类问题中,即使将数据拆分为多个集合,也必须保留目标分布。 简单的说就是分类目标的比例在进行分折后应该与原始数据相同,例如原始数据种A类占比30%,B类占比35%,C类占比35%,在我们分折以后,这个比例是不应该变化的。

    在KFold 它不关心分类比例并且会进行打乱,所以无法保证这个比例与原始数据相同。所以我们使用 Sklearn 中的另一个分折器——StratifiedKFold:

    from sklearn.datasets import make_classification
    from sklearn.model_selection import StratifiedKFold
    
    X, y = make_classification(n_samples=100, n_classes=2)
    
    cv = StratifiedKFold(n_splits=7, shuffle=True, random_state=1121218)
    
    visualize_cv(cv, X, y)
    

    它看起来和KFold一样,但现在在所有折中都保留了与原始数据相同的比例。

    LeavePOut

    有时数据非常有限,甚至无法将其划分为训练集和测试集。 在这种情况下也是可以执行 CV的,我们在每次拆分中只保留几行数据。 这称为 LeavePOut CV,其中 p 是您选择的参数,用于指定每个保持集中的行数。

    最极端的情况是LeaveOneOut分割器,其中只使用单行作为测试集,迭代次数等于完整数据中的行数。我们甚至可以为一个100行数据集构建100个模型(当然效果不一定好)。

    即使是更大的p,拆分次数也会随着数据集大小的增加而呈指数增长。想象一下,当p为5且数据只有50行时,将构建多少模型(提示—使用排列公式)。

    所以,你很少在实践中看到这种情况,但它却经常出现,所以Sklearn将这些过程作为单独的类来实现:

    from sklearn.model_selection import LeaveOneOut, LeavePOut
    

    ShuffleSplit

    我们根本不做 CV 而只是重复多次重 train/test split过程会是什么样的结果? 根据逻辑,使用不同的随机种子生成多个训练/测试集,如果进行足够多的迭代,应该类似于稳健的CV过程。这就是为什么在Sklearn中有一个分割器来执行这个过程:

    from sklearn.model_selection import ShuffleSplit
    
    cv = ShuffleSplit(n_splits=7, train_size=0.75, test_size=0.25)
    
    visualize_cv(cv, X, y)
    

    ShuffleSplit 的优点是可以完全控制每个折中训练和集合的大小。 集合的大小不必与拆分的数量成反比。

    但是与其他拆分器相反,不能保证在每次随机拆分中生成不同的折。 因此,这是可以尝试交叉验证的另一种方式,但不建议这样做。

    顺便说一下,ShuffleSplit 也有Stratified版本用于分类:

    from sklearn.model_selection import StratifiedShuffleSplit
    
    cv = StratifiedShuffleSplit(n_splits=7, test_size=0.5)
    
    visualize_cv(cv, X, y)
    

    TimeSeriesSplit

    最后,时间序列数据是一个非常特殊的情况,因为其中样本的顺序很重要。

    我们不能使用任何传统的 CV 类,因为它们会导致很多问题。最常见的就是很有可能会在未来的样本上进行训练并预测过去的样本。

    为了解决这个问题,Sklearn 提供了另一个拆分器 — TimeSeriesSplit,它可以确保上述情况不会发生:

    rom sklearn.model_selection import TimeSeriesSplit
    
    cv = TimeSeriesSplit(n_splits=7)
    
    visualize_cv(cv, X, y)
    

    用于非 IID 数据的其他 CV 拆分器

    到目前为止,我们一直在处理 IID(独立同分布)数据。换句话说,生成数据的过程没有过去样本的记忆。

    但是,在某些情况下,数据不是 IID — 某些样本组相互依赖。例如,在 Kaggle 上的 Google Brain Ventilator Pressure 竞赛中,参赛者应该使用非 IID 数据。

    数据记录了人工肺进行的数千次呼吸(吸气、呼气),并以几毫秒的间隔记录每次呼吸的气压。因此,每次呼吸的数据包含大约 80 行,并且这些行相互依赖。

    在这里,传统的 CV 分路器无法按预期工作,因为拆分点很有可能产生在“呼吸的中间”。这是 Sklearn 用户指南中的另一个示例:

    这种数据分组是特定于领域的。一个例子是从多个患者收集医疗数据,从每个患者采集多个样本。而这样的数据很可能取决于个体群体。在我们的示例中,每个样本的患者 ID 是其组标识符。

    在那之后,它还说明了解决方案:

    在这种情况下,我们想知道在特定组上训练的模型是否能很好地泛化到看不见的组。为了衡量这一点,我们需要确保验证折叠中的所有样本都来自配对训练折叠中根本没有代表的组。

    Sklearn 列出了五个可以处理分组数据的不同CV类。如果您掌握了前几种拆分的思想并理解了非 IID 数据是什么,那么使用它们就不会遇到问题:

    • GroupKFold
    • StratifiedGroupKFold
    • LeaveOneGroupOut
    • LeavePGroupsOut
    • GroupShuffleSplit

    这些拆分器中的每一个都有一个groups 参数,您应该在其中传递存储组 ID 的列。这告诉该拆分其如何区分每个组。

    总结

    在本篇文章中可能没有回答的一个问题是,“你应该总是使用交叉验证吗?”。 答案是应该是肯定的。 当您的数据集足够大时,任何随机拆分都可能与两组中的原始数据非常相似。 在这种情况下,CV起不到很好的作用。

    但是无论数据大小,你都应该执行至少 2 或 3 倍的交叉验证。 这样才是最保险的。

    作者:Bex T.

    展开全文
  • CODE XREF代表这是一个代码交叉引用,后面的地址(这里为_main+2A)是交叉引用的源头地址,即_main+2A处调用了该方法,交叉引用中使用的地址提供
  • 前言交叉验证是帮助机器学习模型选择最优超参数的有用程序。它对于较小的数据集特别有用,因为这些数据集没有足够的数据来创建具有代表性的训练集、验证集和测试集。简单地说,交叉验证将单个训练数据集...

    前言

    交叉验证是帮助机器学习模型选择最优超参数的有用程序。它对于较小的数据集特别有用,因为这些数据集没有足够的数据来创建具有代表性的训练集、验证集和测试集。

    简单地说,交叉验证将单个训练数据集拆分为训练和测试数据集的多个子集。

    最简单的形式是k-fold交叉验证,它将训练集拆分为k个较小的集合。对于每个分割,使用k-1个集合的训练数据训练模型。然后使用剩余数据对模型进行验证。然后,对于每一次拆分,模型都会在剩余集合上打分。分数是各部分的平均值。

    然而,这种超参数调整方法不适用于时间序列预测!

    下图说明了为什么标准k折交叉验证(以及其他非时间数据分割)不适用于时间序列机器学习。该图显示了分为五个窗口的单变量序列,并指示序列中的哪些日期指定给哪个折。

    有三个突出的问题:

    1. 预测/测试数据出现在训练数据之前。在0号窗口中,测试数据出现在训练数据之前!

    2. 数据泄漏。在窗口2–4中,某些训练数据出现在测试数据之后。这是有问题的,因为模型能够预见“未来”。

    3. 一序列的空白。在窗口2–4中,由于测试数据取自序列的中间部分,因此训练序列中存在差距。

    有关交叉验证的更多背景信息,请参阅scikit-learn文档:

    https://scikit-learn.org/stable/modules/cross_validation.html

    sktime

    scikit learn提供了使用model_selection.KFold之类的类将数据拆分为折的方法。sktime提供了相应的类“窗口拆分器”,它们的工作方式类似。

    窗口拆分器有两个可配置的参数:

    • window_length -每个折的训练窗口长度

    • fh——预测范围;指定训练窗口后要包含在测试数据中的值。它可以是整数、整数列表或sktime ForecastingHorizon对象。

    • initial_window -第一个折的训练窗口长度。如果未设置,window_length将用作第一个折的长度。

    • step_length -折之间的步长。默认值为1步。

    初始化后,窗口拆分器可以与KFold验证类相同的方式使用,为每个数据拆分提供训练和测试索引:

    from sktime.forecasting.model_selection import SingleWindowSplitter
    cv = SingleWindowSplitter()
    for train_idx, test_idx in cv.split(y):
        train_window = y[train_idx]
        test_window = y[test_idx]

    左右滑动查看

    滑动窗口拆分

    此拆分器会随着时间的推移在滑动窗口上生成折。每个折的训练序列和测试序列的大小是恒定的。

    from sktime.forecasting.model_selection import SlidingWindowSplitter
    cv = SlidingWindowSplitter(window_length=5, fh=[1, 2, 3])
    
    n_splits = cv.get_n_splits(y)
    print(f"Number of Folds = {n_splits}")
    >> Number of Folds = 23
    

    左右滑动查看

    在本例中, window_length =5,这意味着训练窗口始终包含5个值。预测范围FH是一个整数列表,指示训练窗口后的哪些值应在测试数据中。

    以下是将初始_窗口设置为10并将步长更改为3时的情况:

    cv = SlidingWindowSplitter(window_length=5, fh=[1, 2, 3], initial_window=10, step_length=3)
    
    n_splits = cv.get_n_splits(y)
    print(f"Number of Folds = {n_splits}")
    >> Number of Folds = 6
    

    左右滑动查看

    如下图所示,第一个折的训练窗口为10个时间步长;后续的折具有长度为5的训练窗口。此外,每个折滑动3步。

    扩展窗口拆分

    与滑动窗口拆分器一样,ExpandingWindowSplitter会随着时间的推移在滑动窗口上生成折。

    但是,训练序列的长度会随着时间的推移而增长,每个后续折都会保留完整序列历史。每个折的测试序列长度是恒定的。

    from sktime.forecasting.model_selection import ExpandingWindowSplitter
    cv = ExpandingWindowSplitter(window_length=5, fh=[1, 2, 3])
    
    n_splits = cv.get_n_splits(y)
    print(f"Number of Folds = {n_splits}")
    >> Number of Folds = 23
    

    左右滑动查看

    预测模型选择

    sktime提供了两个类,它们使用交叉验证来搜索预测模型的最佳参数:Forecasting Grid Search CV(评估所有可能的参数组合)和Forecasting Grandomized Search CV(随机选择要评估的超参数)。这些类通过反复拟合和评估同一个模型来工作。

    这两个类类似于scikit learn中的交叉验证方法,并遵循类似的界面。

    • 要调整的预测器

    • 交叉验证构造函数(例如Sliding Window Splitter)

    • 参数网格(例如{'window_length':[1,2,3]})

    • 参数

    • 评估指标(可选)

    在下面的示例中,跨时间滑动窗口使用带交叉验证的网格搜索来选择最佳模型参数。参数网格指定模型参数sp(季节周期数)和 seasonal (季节分量类型)的哪些值。

    预测器拟合60个时间步长初始窗口的数据。后续窗口的长度为20。预测范围设置为1,这意味着测试窗口仅包含在训练窗口之后出现的单个值。

    from sktime.forecasting.exp_smoothing import ExponentialSmoothing
    from sktime.forecasting.model_selection import ForecastingGridSearchCV, SlidingWindowSplitter
    forecaster = ExponentialSmoothing()
    param_grid = {"sp": [1, 6, 12], 'seasonal': ['add, 'mul']}
    cv = SlidingWindowSplitter(initial_window=60, window_length=20, fh=1)
    gscv = ForecastingGridSearchCV(
        forecaster, strategy="refit", cv=cv, param_grid=param_grid
    )
    

    左右滑动查看

    然后可以拟合,并使用该方法进行预测:

    gscv.fit(y_train)
    y_pred = gscv.predict([1, 2])  # 预测给定的未来时间步骤1和2的值
    

    左右滑动查看

    拟合对象包含两个有用的属性:

    • gscv.best_params_ :调整参数

    • gscv.best_forecaster_ :具有最佳超参数的最佳预测器实例

    有关使用sktime进行预测的更多详细信息,包括模型选择和调整,请参阅此处的sktime预测教程:

    https://www.sktime.org/en/latest/examples/01_forecasting.html

    建议阅读:

    高考失利之后,属于我的大学本科四年

    【资源分享】对于时间序列,你所能做的一切.

    【时空序列预测第一篇】什么是时空序列问题?这类问题主要应用了哪些模型?主要应用在哪些领域?

    【AI蜗牛车出品】手把手AI项目、时空序列、时间序列、白话机器学习、pytorch修炼

    公众号:AI蜗牛车
    
    保持谦逊、保持自律、保持进步
    
    
    
    个人微信
    备注:昵称+学校/公司+方向
    如果没有备注不拉群!
    拉你进AI蜗牛车交流群
    
    
    
    
    展开全文
  • K折验证交叉验证

    万次阅读 多人点赞 2021-08-17 17:59:14
    K折验证交叉验证 交叉验证既可以解决数据集的数据量不够大问题,也可以解决参数调优的问题。这块主要有三种方式:简单交叉验证(HoldOut检验)、k折交叉验证(k-fold交叉验证)、自助法。该文仅针对k折交叉验证做...
  • 【技术分享】什么是K折交叉验证?

    千次阅读 2022-06-01 23:30:09
    文章目录 1.什么是训练集、验证集和测试集?... 可以将 K 折交叉验证,概括为 N 次 K 折交叉验证。N 是指超参数组的数量,需要从 N 个超参数组中选出最好的一个来;K 是指交叉验证划分的数量,一般取5或者10。
  • linux使用cmake交叉编译arm32程序

    千次阅读 2020-08-19 21:57:48
    linux使用cmake交叉编译arm32程序
  • Go交叉编译

    千次阅读 2020-05-17 14:52:11
    交叉编译是指在一个硬件平台生成另一个硬件平台的可执行文件。而Go提供了非常方便的交叉编译方式。 如何编译 Go交叉编译,涉及到几个环境变量的... CGO_ENABLED:代表是否开启CGO,1表示开启,0表示禁用。由于CGO不.
  • Stata: 交叉验证简介

    千次阅读 2019-10-30 00:43:52
    作者:贺旭 (中央财经大学) Stata连享会   计量专题 || 精品课程 || 简书推文 || 公众号合集 ...本文介绍交叉验证方法,然后以 kfoldclass 命令和 crossfold 为范例使读者更深入的了解该方法。 ...
  • 交叉编译工具链介绍

    千次阅读 2020-07-03 10:41:35
    什么是交叉编译 交叉编译可以理解为,在当前编译平台下,编译出来的程序能运行在体系结构不同的另一种目标平台上,但是编译平台本身却不能运行该程序。 比如,我们在 x86 平台上,编写程序并编译成能运行在 ARM ...
  • 广义交叉验证

    千次阅读 2021-04-22 11:45:25
    交叉验证,有时亦称循环估计, 是一种统计学上将数据样本切割成较小子集的实用方法。于是可以先在一个子集上做分析, 而其它子集则用来做后续对此分析的确认及验证。 一开始的子集被称为训练集。而其它的子集则被...
  • 以可接受间隙理论为基础 ,通过利用概率论的方法 ,对以有 r种代表车型组成的混合车流进行分析 .建立了无信号交叉口主车流服从移位负指数分布下的支路多车型混合车流的通行...
  • 交叉编译环境搭建与测试

    千次阅读 2021-01-23 14:24:18
    一、什么是交叉编译 ​ 在一种计算机环境中运行的编译程序,能编译出在另外一种环境下运行的代码,我们就称这种编译器支持交叉编译。这个编译过程就叫交叉编译。 简单地说,就是在一个平台上生成另一个平台上的可...
  • SPSS数据分析-交叉表分析

    万次阅读 2020-08-20 12:16:03
    交叉表(交叉列联表) 分析法是一种以表格的形式同时描述两个或多个变量的联合分布及其结果的统计分析方法,此表格反映了这些只有有限分类或取值的离散变量的联合分布。 当交叉表只涉及两个定类变量时,交叉表又叫做...
  • 黑色虚线代表留一法交叉验证,橙色曲线代表10折交叉验证。 我们通过交叉验证可以判断一个给定模型在数据集上的效果。上述案例中,我们知道真实的测试误差,要找到使得真实测试误差最小的点。但在实际情况中,我们...
  • 决策树和随机森林、交叉验证

    千次阅读 2022-02-21 16:14:49
    决策树 决策树是一种非参数的监督学习方法 能从有特征和标签的数据中总结出决策规则,并用树状图来呈现这些规则,以此解决分类和回归问题。 决策树算法的两个核心问题 如何从数据表中找出最佳节点和最佳分支 ...
  • 经济学里的那些字母都代表意思

    千次阅读 2020-02-15 22:38:17
    p :价格 Q :数, O :需求 S :供给 〔 :均衡(或期望) e :弹性 ed :瀚求的价格弹性 es :供给的价格弹性 exy 二浦求的交叉价格弹性 U :效用 TU :总效用 MU :边际效用 CS :消费者刹余 M RS :商品的边际...
  • CCNet:交叉注意力语义分割

    千次阅读 2021-01-31 20:37:27
    Semantic instance segmentation with a discriminative loss function中的损失函数有三项:,分别代表了三种情况下的惩罚: (1)类别相同,特征距离较远;(2)不同类别,特征距离较近;(3)所有类别与原点损失...
  • 关于深度学习中交叉验证的探讨

    千次阅读 2021-09-08 18:57:16
    关于深度学习中交叉验证的探讨 1 交叉验证目的 对于给定的模型,通过交叉验证评价模型的泛化性能。 交叉验证通常用于数据集较小的情况,当数据不足时,随机划分数据集会使模型的泛化误差(测试集上的误差)波动较大...
  • 本发明属于电子对抗技术领域,具体的说是涉及一种基于角度信息的无源多站多目标测向交叉定位方法。背景技术:在电子侦察过程中,准确估计目标辐射源位置有助于获取辐射源信息,是做好高层次上的态势估计和威胁估计的...
  • 有同学问随机截距交叉滞后和传统交叉滞后的区别,随便记录一下,希望给到大家启发。 拟合随机截距交叉滞后模型RI-CLPM的时候我们需要将变量的观察分数分为3个部分:第一部分为总体均数grand means,就是每个变量在...
  • 交叉验证python_交叉验证

    千次阅读 2020-08-08 22:03:11
    交叉验证pythonCross validation may be any of various model validation techniques that are used to assess how well a predictive model will generalize to an independent set of data that the model has ...
  • 交叉编译工具链详解

    千次阅读 2021-08-19 13:43:15
    交叉编译是什么,为什么要交叉编译 一、 是什么 交叉编译是在一个平台上生成另一个平台上的可执行代码。 例如 1、我们在windows上面编写C51代码,并编译成可执行...交叉编译的意思 C51交叉编译发生在keil(集成环境上
  • K-折交叉验证(原理及实现)

    万次阅读 多人点赞 2020-07-13 21:26:27
    图的右上角代表了过拟合。 四、交叉验证的产生 人们发现用同一数据集,既进行训练,又进行模型误差估计,对误差估计的很不准确,这就是所说的模型误差估计的乐观性。为了克服这个问题,提出了交叉验证。基本思想是将...
  • 模型选择和交叉验证

    万次阅读 2018-05-16 13:10:06
    显然越高次数的多项式模型越能够适应我们的训练数据集,但是适应训练数据集并不代表着能推广至一般情况。我们应该选择一个更能适应一般情况的模型。如果在模型选择过程中不断重复使用相同的测试数据,这样的话测试...
  • 【SPSS笔记01】交叉分析表

    千次阅读 2021-05-05 20:53:36
    交叉交叉表用途&使用步骤Step1Step2变量解释Step3交叉表结果观察卡方分析的解释 交叉表用途&使用步骤 主要用途:主要用于分析分类变量的相关关系,如果是连续变量的相关性,主要使用相关分析 Step1 :分析...
  • 交叉验证是什么? 在模型建立中,通常有两个数据集:训练集(train)和测试集(test)。训练集用来训练模型;测试集是完全不参与训练的数据,仅仅用来观测测试效果的数据。 一般情况下,训练的结果对于训练集的拟合...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 117,285
精华内容 46,914
热门标签
关键字:

交叉代表的意思