精华内容
下载资源
问答
  • 五折交叉验证

    万次阅读 多人点赞 2020-05-18 14:06:42
    五折交叉验证详细解说 步骤: step1:将数据集分为5堆; step2:选取一堆作为测试集,另外四堆作为训练集; step3:共重复step2 五次,每次选取的训练集不同。 图示: data data1 data2 data3 data4 data5 1 ...

    五折交叉验证详细解说
    步骤:
    step1:将数据集分为5堆;
    step2:选取一堆作为测试集,另外四堆作为训练集;
    step3:重复step2 五次,每次选取的训练集不同。
    图示:

    data data1 data2 data3 data4 data5
    1 test train train train train
    2 train test train train train
    3 train train test train train
    4 train train train test train
    5 train train train train test

    matlab实现代码:

    clear;clc;
    load('Winedata.mat')   %红酒数据在UCI数据集中即可下载
    nFold = 5; 
    [n,p] = size(winedata);
    c_out = cvpartition(n,'k',nFold);
    for k = 1:nFold
        Train_dat = winedata(training(c_out,k),:);
        Test_dat = winedata(test(c_out,k),:);   
    end
    

    注:此代码直接运行后,工作空间中显示的是最后一折的数据。若想得到每折数据,则可以设置结点,逐步运行,然后save数据即可;若想在此代码中直接使用每折数据,则在for循环中加入相应使用代码即可。

    第一次写文章,欢迎批评指正。

    展开全文
  • 五折交叉验证: 把数据平均分成5等份,每次实验拿一份做测试,其余用做训练。实验5次求平均值。如上图,第一次实验拿第一份做测试集,其余作为训练集。第二次实验拿第二份做测试集,其余做训练集。依此类推~ 但是,...

    在这里插入图片描述
    五折交叉验证: 把数据平均分成5等份,每次实验拿一份做测试,其余用做训练。实验5次求平均值。如上图,第一次实验拿第一份做测试集,其余作为训练集。第二次实验拿第二份做测试集,其余做训练集。依此类推~

    但是,道理都挺简单的,但是代码我就不会写,比如我怎么把数据平均分成5份?我怎么保证每次实验的时候,数据都是这么划分的?本来一般的训练时,把数据按6:2:2分成训练集、验证集和测试集,在训练集上训练图像,验证集上保存最佳模型,测试集用来最后的测试。现在交叉验证没有验证集了,怎么保存模型?以下为大家一一解答。

    1.把数据平均分成K等份

    使用KFold类。
    class sklearn.model_selection.KFold(n_splits=5, *, shuffle=False, random_state=None)
    sklearn提供的这个函数就是用来做K折交叉验证的。
    提供训练集/测试集索引以分割数据。将数据集拆分为k折(默认情况下不打乱数据。

    参数介绍
    n_splits:int, 默认为5。表示拆分成5折
    shuffle: bool, 默认为False。切分数据集之前是否对数据进行洗牌。True洗牌,False不洗牌。
    random_state:int, 默认为None 当shuffle为True时,如果random_state为None,则每次运行代码,获得的数据切分都不一样,random_state指定的时候,则每次运行代码,都能获得同样的切分数据,保证实验可重复。random_state可按自己喜好设定成整数,如random_state=42较为常用。当设定好后,就不能再更改。

    使用KFold类需要先初始化,然后再调用它的方法实现数据划分。它的两个方法为:

    • get_n_splits(X=None, y=None, groups=None)
      返回交叉验证器中的拆分迭代次数
    • split(X, y=None, groups=None)
      生成索引,将数据拆分为训练集和测试集。
      X: 数组, 形状为: (n_samples, n_features)
      其中n_samples是样本数,n_features是特征数。
      y: 数组,形状为(n_samples,), default=None。可要可不要
      return:train和test的索引,注意返回的是每个集合的索引,而不是数据

    举例1:设置shuffle=False,每次运行结果都相同

    from sklearn.model_selection import KFold
    import numpy as np
    X = np.arange(24).reshape(12,2)
    y = np.random.choice([1,2],12,p=[0.4,0.6])
    kf = KFold(n_splits=5,shuffle=False)  # 初始化KFold
    for train_index , test_index in kf.split(X):  # 调用split方法切分数据
        print('train_index:%s , test_index: %s ' %(train_index,test_index))
    

    结果:5折数据的索引
    train_index:[ 3 4 5 6 7 8 9 10 11] , test_index: [0 1 2]
    train_index:[ 0 1 2 6 7 8 9 10 11] , test_index: [3 4 5]
    train_index:[ 0 1 2 3 4 5 8 9 10 11] , test_index: [6 7]
    train_index:[ 0 1 2 3 4 5 6 7 10 11] , test_index: [8 9]
    train_index:[0 1 2 3 4 5 6 7 8 9] , test_index: [10 11]

    通过索引去获取数据和对应的标签可用:

    fold1_train_data, fold1_train_label = X[train_index], y[train_index]
    

    在这里插入图片描述

    举例2:设置shuffle=True,每次运行结果都不相同

    在这里插入图片描述

    举例3:设置shuffle=True和random_state=整数,每次运行结果相同

    在这里插入图片描述
    因此,实际使用的时候建议采用案例3这种方式,即可保证实验可重复,有增加了数据的随机性。

    举例4: 真实案例数据划分

    我有一些nii.gz的三维数据用来做分割,图像和label分别放在不同的文件夹。如:
    └── 根目录
    └── image
    │ ├── 1.nii.gz
    │ │── 2.nii.gz
    │ └── 3.nii.gz

    ── label
    │ ├── 1.nii.gz
    │ │── 2.nii.gz
    │ └── 3.nii.gz

     images1 = sorted(glob.glob(os.path.join(data_root, 'ImagePatch', 'l*.nii.gz')))
     labels1 = sorted(glob.glob(os.path.join(data_root, 'Mask01Patch', 'l*.nii.gz')))
     images2 = sorted(glob.glob(os.path.join(data_root, 'ImagePatch', 'r*.nii.gz')))
     labels2 = sorted(glob.glob(os.path.join(data_root, 'Mask01Patch', 'r*.nii.gz')))
     data_dicts1 = [{'image': image_name, 'label': label_name}
                       for image_name, label_name in zip(images1, labels1)]
     data_dicts2 = [{'image': image_name, 'label': label_name}
                       for image_name, label_name in zip(images2, labels2)]
     all_files = data_dicts1 + data_dicts2
     # 把image和label创建成字典,统一放在列表里
    

    在这里插入图片描述
    all_files是一个包含所有数据的列表,但列表里的每一个数据又是一个字典,分别当image和label的数据地址。
    我们对 all_files的数据进行五折交叉验证:

        floder = KFold(n_splits=5, random_state=42, shuffle=True)
        train_files = []   # 存放5折的训练集划分
        test_files = []     # # 存放5折的测试集集划分
        for k, (Trindex, Tsindex) in enumerate(floder.split(all_files)):
            train_files.append(np.array(all_files)[Trindex].tolist())
            test_files.append(np.array(all_files)[Tsindex].tolist())
    
        # 把划分写入csv,检验每次是否相同
        df = pd.DataFrame(data=train_files, index=['0', '1', '2', '3', '4'])
        df.to_csv('./data/Kfold/train_patch.csv')
        df1 = pd.DataFrame(data=test_files, index=['0', '1', '2', '3', '4'])
        df1.to_csv('./data/Kfold/test_patch.csv')
    

    我们把数据集的划分保存到csv里面,以防止代码改动丢失了原本的划分方法。

    数据集划分好了,就可以进行训练和测试了。每一次拿划分好的一折数据就行。

        # 五折分开train, 每次拿一折train 和 test
        train(train_files[0], test_files[0])
        test(test_files[0])
    

    在train和test方法里面,肯定要写好对应的dataloder, 因为我们刚只是把数据的名字进行了划分,并没有加载数据集。

    通常的做法里,会循环5次,运行一次代码,把五折的结果都做出来。但是我们这种写法的好处在于,你想训练第几折,就把索引值改一下就是,不需要一下子全部训练完。只要你不动代码,你一年后再训练,数据集的划分都不会变。变了也不怕,我们把划分已经保存成csv了。

    当然,这只是一种写法,如果有更好的方案,欢迎留言探讨~~

    2.没有验证集了,怎么保存最佳模型

    这是我之前一直好奇的问题。因为,如果不做交叉验证,那么我会根据测试集上的指标保存最佳模型。比如以下代码是在验证集上完成的。

    if metric > best_metric:
         best_metric = metric
         best_metric_epoch = epoch + 1
         save_dir = 'checkpoints/checkpoint_04264/'
         if not os.path.exists(save_dir):
             os.makedirs(save_dir)
         save_path = save_dir + str(epoch + 1) + "best_metric_model.pth"
         torch.save(model.state_dict(), save_path)
         print('saved new best metric model')
    

    但是,现在,没有验证集了,我是根据训练集上的指标保存模型呢,还是根据测试集上的指标?这个问题,没有统一答案,两者做法都有。正因为没有统一答案,那我们可以选择对自己最有利的答案啊😜。比如,写论文的时候,根据测试集上的结果保存模型,那肯定得到的结果更好啊。

    而且,还有一个小tips, 用交叉验证的得到的结果通常比按6:2:2划分训练集验证集测试集上的结果要好。想想是为什么😉

    在这里插入图片描述

    展开全文
  • 使用catboost进行五折交叉验证 import numpy as np import pandas as pd import catboost as cbt from sklearn.metric import f1_score from sklearn.model_selection import train_test_split from sklearn.model...

    使用catboost进行五折交叉验证

    import numpy as np
    import pandas as pd
    import catboost as cbt
    from sklearn.metric import f1_score
    from sklearn.model_selection import train_test_split
    from sklearn.model_selection import StratifiedKFold
    
    
    train_data = pd.read_csv('.....')
    train_label = pd.read_csv('.....')
    test_data = pd.read_csv('.....')
    
    
    cat_list = [] #catboost中需要处理的离散特征属性列
    oof = np.zeros(train_data.shape[0])  #训练集长度
    prediction = np.zeros(test_data.shape[0])     #测试集长度
    seeds = [2017,2018,2019,2020]     #随机种子
    num_model_seed = 1
    
    
    train_x, test_x, train_y, test_y = train_test_split(train_data, train_label, test_size=0.2, random_state = 2019)     #拆分训练集
    for model_seed in range(num_model_seed):     #选用几个随机种子
        oof_cat = np.zeros(train_data.shape[0])
        prediction_cat = np.zeros(test_data.shape[0])
        skf = StratifiedKFold(n_splits=5, random_state=seeds[model_seed], shuffle=True) #五折交叉验证,shuffle表示是否打乱数据,若为True再设定随机种子random_state
        for index, (train_index, test_index) in enumerate(skf.split(train_data, train_label)): #将数据五折分割
            train_x, test_x, train_y, test_y = train_data.iloc[train_index], test_data.iloc[test_index], train_label.iloc[train_index], train_label.iloc[test_index]
            cbt_model = cbt.CatBoostClassifier(iterations=5000, learning_rate=0.1, max_depth=7, verbose=100, early_stopping_rounds=500,task_type='GPU', eval_metric='F1',cat_features=cat_list)     #设置模型参数,verbose表示每100个训练输出打印一次
            cbt_model.fit(train_x, train_y, eval_set=(test_x, test_y)) #训练五折分割后的训练集
            gc.collect() #垃圾清理,内存清理
            oof_cat[test_index] += cbt_model.predict_proba(test_x)[:,1] #
            prediction_cat += cbt_model.predict_proba(test_data)[:,1]/5
        print('F1', f1_score(train_label, np.round(oof_cat)))
        oof += oof_cat / num_model_seed     #五折训练集取均值
        prediction += prediction_cat / num_model_seed #测试集取均值
    print('score', f1_score(train_label, np.round(oof)))
    
    ##结果写入csv文件
    submit = test_data['id']
    submit['label'] = (prediction>=0.499).astype(int)
    print(submit['label'].value_counts())
    submit.to_csv('submission.csv',index=False)

     

    展开全文
  • 使用网格搜索法对7个模型进行调优(调参时采用五折交叉验证的方式),并进行模型评估,记得展示代码的运行结果 二 k折交叉验证&网格搜索法 K折交叉验证(k-fold cross validation),将初始采样...

    一 本次任务


    使用网格搜索法对7个模型进行调优(调参时采用五折交叉验证的方式),并进行模型评估,记得展示代码的运行结果

    二 k折交叉验证&网格搜索法


    K折交叉验证(k-fold cross validation),将初始采样(样本集X,Y)分割成K份,一份被保留作为验证模型的数据(test set),其他K-1份用来训练(train set)。交叉验证重复K次,每份验证一次,平均K次的结果或者使用其它结合方式,最终得到一个单一估测。

    Grid Search:一种调参手段;穷举搜索:在所有候选的参数选择中,通过循环遍历,尝试每一种可能性,表现最好的参数就是最终的结果。其原理就像是在数组里找最大值。(为什么叫网格搜索?以有两个参数的模型为例,参数a有3种可能,参数b有4种可能,把所有可能性列出来,可以表示成一个3*4的表格,其中每个cell就是一个网格,循环过程就像是在每个网格里遍历、搜索,所以叫grid search)

    三 代码实践

    1.逻辑回归

    best_score = 0.0
    # for gamma in [0.001,0.01,0.1,1,10,100]:
    for C in [0.001,0.01,0.1,1,10,100]:
        log_model = LogisticRegression(C=C,random_state =2018)
        scores = cross_val_score(log_model,X_train_stand,y_train,cv=5) #5折交叉验证
        score = scores.mean() #取平均数
        if score > best_score:
            best_score = score
            best_parameters = {"C":C}
    log_model = LogisticRegression(**best_parameters)
    log_model.fit(X_train_stand,y_train)
    test_score = log_model.score(X_test_stand,y_test)
    print("Best score on validation set:{:.2f}".format(best_score))
    print("Best parameters:{}".format(best_parameters))
    print("Score on testing set:{:.2f}".format(test_score))
    
    Best score on validation set:0.79
    Best parameters:{'C': 0.01}
    Score on testing set:0.78
    

    2.svm

    best_score = 0.0
    for gamma in [0.001,0.01,0.1,1,10,100]:
        for C in [0.001,0.01,0.1,1,10,100]:
            svm = SVC(gamma=gamma,C=C,random_state =2018)
            scores = cross_val_score(svm,X_train_stand,y_train,cv=5) #5折交叉验证
            score = scores.mean() #取平均数
            if score > best_score:
                best_score = score
                best_parameters = {"gamma":gamma,"C":C}
    svm = SVC(**best_parameters)
    svm.fit(X_train_stand,y_train)
    test_score = svm.score(X_test_stand,y_test)
    print("Best score on validation set:{:.2f}".format(best_score))
    print("Best parameters:{}".format(best_parameters))
    print("Score on testing set:{:.2f}".format(test_score))
    
    Best score on validation set:0.79
    Best parameters:{'gamma': 0.001, 'C': 10}
    Score on testing set:0.78
    

    3.决策树

    以决策树为例,当我们确定了要使用决策树算法的时候,为了能够更好地拟合和预测,我们需要调整它的参数。在决策树算法中,我们通常选择的参数是决策树的最大深度。

    于是我们会给出一系列的最大深度的值,比如 {‘max_depth’: [1,2,3,4,5]},我们会尽可能包含最优最大深度。

    def accuracy_score(truth, pred):
        """ Returns accuracy score for input truth and predictions. """
        
        # Ensure that the number of predictions matches number of outcomes
        # 确保预测的数量与结果的数量一致
        if len(truth) == len(pred): 
            
            # Calculate and return the accuracy as a percent
            # 计算预测准确率(百分比)
            # 用bool的平均数算百分比
            return(truth == pred).mean()*100
        
        else:
            return 0
    
    clf = fit_model_k_fold(X_train_stand, y_train)
    print ("k_fold Parameter 'max_depth' is {} for the optimal model.".format(clf.get_params()['max_depth']))
    print ("k_fold Parameter 'criterion' is {} for the optimal model.".format(clf.get_params()['criterion']))
    
    k_fold Parameter 'max_depth' is 3 for the optimal model.
    k_fold Parameter 'criterion' is gini for the optimal model.
    

    4.随机森林

    %%time
    rf_clf = RandomForestClassifier(n_estimators=100, max_depth=5, max_features=0.6, oob_score=True, random_state=2018)
    param_grid = [
        {
          'n_estimators': range(50,300,10),
        }
    ]
    #以AUC值为评判标准,使用5折交叉验证开始搜索
    grid_search4 = GridSearchCV(rf_clf, param_grid, scoring='roc_auc', cv=5, n_jobs=-1)
    grid_search4.fit(X_train_stand,y_train)
    print("best para:", grid_search4.best_params_)
    print("Best score on:", grid_search4.best_score_)
    
    best para:{'n_estimators': 280}
    Best score on:0.7886
    

    5.GBDT

    model= GradientBoostingClassifier(learning_rate=1.0, random_state=2018)
    score = cross_validate(model, X_train_stand, y_train, cv=10, scoring='accuracy')
    print("最佳accuracy", score)
    
    最佳accuracy {'fit_time': array([0.94503713, 0.89858294, 0.93704295, 0.92252803, 0.99808264,
           0.94257784, 1.03067875, 0.96216011, 0.99138594, 1.08498693]), 'score_time': array([0.00094891, 0.00092816, 0.00090098, 0.00241685, 0.0009973 ,
           0.00093627, 0.0008862 , 0.00088882, 0.00092483, 0.00136495]), 'test_score': array([0.75748503, 0.74550898, 0.75449102, 0.74474474, 0.70481928,
           0.74698795, 0.74096386, 0.72891566, 0.76807229, 0.76204819]), 'train_score': array([0.9973271 , 0.9923154 , 0.9973271 , 0.99532398, 0.99833055,
           0.99465776, 0.99732888, 0.99732888, 0.99465776, 0.99766277])}
    

    6.XGBoost

    best_score = 0.0
    # xgb_model = XGBClassifier()
    for gamma in [0.001,0.01,0.1,1,10,100]:
        for C in [0.001,0.01,0.1,1,10,100]:
            xgb_model = XGBClassifier(gamma=gamma,C=C,random_state =2018)
            scores = cross_val_score(svm,X_train_stand,y_train,cv=5) #5折交叉验证
            score = scores.mean() #取平均数
            if score > best_score:
                best_score = score
                best_parameters = {"gamma":gamma,"C":C}
    xgb_model = XGBClassifier(**best_parameters)
    xgb_model.fit(X_train_stand,y_train)
    test_score = xgb_model.score(X_test_stand,y_test)
    print("Best score on validation set:{:.2f}".format(best_score))
    print("Best parameters:{}".format(best_parameters))
    print("Score on testing set:{:.2f}".format(test_score))
    
    Best score on validation set:0.79
    Best parameters:{'gamma': 0.001, 'C': 0.001}
    Score on testing set:0.78
    

    7.lightGBM

    best_score = 0.0
    # lgb_model = LGBMClassifier()
    for gamma in [0.001,0.01,0.1,1,10,100]:
        for C in [0.001,0.01,0.1,1,10,100]:
            lgb_model = LGBMClassifier(gamma=gamma,C=C,random_state =2018)
            scores = cross_val_score(svm,X_train_stand,y_train,cv=5) #5折交叉验证
            score = scores.mean() #取平均数
            if score > best_score:
                best_score = score
                best_parameters = {"gamma":gamma,"C":C}
    lgb_model = LGBMClassifier(**best_parameters)
    lgb_model.fit(X_train_stand,y_train)
    test_score = lgb_model.score(X_test_stand,y_test)
    print("Best score on validation set:{:.2f}".format(best_score))
    print("Best parameters:{}".format(best_parameters))
    print("Score on testing set:{:.2f}".format(test_score))
    
    Best score on validation set:0.78
    Best parameters:{'gamma': 0.01, 'C': 0.001}
    Score on testing set:0.76
    

    四 参考

    https://blog.csdn.net/Softdiamonds/article/details/80062638
    https://blog.csdn.net/ChenVast/article/details/79257097
    https://www.cnblogs.com/ysugyl/p/8711205.html
    https://www.jianshu.com/p/3183dd02d579 决策树
    http://www.cnblogs.com/maybe2030/p/4585705.html 随机森林
    https://www.cnblogs.com/zhangbojiangfeng/p/6428988.html XGboost

    五 思考

    1.GridSearchCV & cross_val_score

    GridSearchCV(网格搜索)用简答的话来说就是你手动的给出一个模型中你想要改动的所用的参数,程序自动的帮你使用穷举法来将所用的参数都运行一遍。
    cross_val_score 一般用于获取每折的交叉验证的得分,然后根据这个得分为模型选择合适的超参数,通常需要编写循环手动完成交叉验证过程;
    GridSearchCV 除了自行完成叉验证外,还返回了最优的超参数及对应的最优模型

    展开全文
  • 1.数据:R自带inis花数据。用已经学习的分类预测方法(至少两种)采用五折交叉验证的方法做分类预测分析,
  • 这边主要是使用sklearn的决策树算法对乳腺癌数据集进行分类,并用五折交叉验证评估 以前我们是直接将数据分割成70%的训练数据和测试数据,现在我们利用5折交叉验证分割数据,首先将数据分为5组,然后再从5组数据之...
  • 最近做作业的时候需要做Logistic回归的交叉验证,这里记录一下 首先对数据集进行拆分,这里用到caret包里的函数 拆分数据 然后对其进行交叉验证+logistic回归 交叉验证 ...
  • 在绘制交叉验证的平均ROC曲线时采用将五折的fpr和tpr求平均以获得最终tpr和fpr,这么做有依据吗?以前前面部分求插值的操作,是在有点看不懂,有大神帮忙讲解下嘛? 代码来源:...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 169
精华内容 67
关键字:

五折交叉验证