数据集按照csv格式标签划分为训练集和验证集(完整代码)

前言

最近参加一个比赛,拿到的数据集分为两部分,需要先进行划分,于是看看网上有没有代码可以借用,这样效率更高,但是发现,大部分代码都是bug满天飞,作者也不给出必要的说明,于是只能自己修改和重写。(不忍吐槽,那些复制别人代码的人,能不能自己跑通了再发布?)

正文

前排提示:我的方法不是一步到位那种,而是拆分为两部分:1) 先按照标签移动数据集。2) 按照比例划分出验证集(或测试集)。之所以这样做,是因为之前我参加过一个比赛,写了一个划分验证集的脚本,现在就直接用了。

拿到的数据集分为两部分:

  • 一个名叫train的文件夹,里面包含了所有样本(.jpg格式的图片)
  • 一个train.csv文件,记录了每张图片对应的标签

train文件夹:

数据集按照csv格式标签划分为训练集和验证集(完整代码)_第1张图片

 train.csv:(记住红框里的这两个名字,后面要用)

数据集按照csv格式标签划分为训练集和验证集(完整代码)_第2张图片

目的:把train文件夹里的一万多张照片,按照0-5总共6个标签,移动到对应的文件夹里,最后效果如图:

数据集按照csv格式标签划分为训练集和验证集(完整代码)_第3张图片

 例如标签为0的文件夹:

数据集按照csv格式标签划分为训练集和验证集(完整代码)_第4张图片

 接下来看代码:

import os
import shutil
import pandas as pd
import random

#打开表格文件并读取
f=open("D:/game_data1/train.csv","rb") # 打开csv文件
list=pd.read_csv(f) # 这句不能少

#创建文件夹
for i in range(6): # "6"指的是0-5总共6个类别
    if not os.path.exists('D:/game_data1/'+str(i)): # 最后一个 / 不要漏
            os.mkdir('D:/game_data1/'+str(i))
#进行分类
for i in range(6):
    listnew=list[list["CATEGORY_ID"]==i] # 对应csv文件图片那一栏的标题
    l=listnew["FILE_ID"].tolist() # 对应csv文件标签那一栏的标题
    j=str(i)
    for each in l:
        shutil.move('D:/game_data1/train/'+each, 'D:/game_data1/'+j) 
print("完成")

 接下来进行第二步:按照比例划分出验证集

path1 = 'D:/game_data1/train'
path2= 'D:/game_data1/valid'
valid_size=0.07
path_1_doc=os.listdir(path1) 
path_1_doc_path=[path1+'/'+i for i in path_1_doc]

for doc in path_1_doc: # 新建空文件夹,使得和path1里的一样 
    if not os.path.exists(path2+'/'+doc):
        os.mkdir(path2+'/'+doc)
path_2_doc=os.listdir(path2)

for k in range(len(path_1_doc)):  
    i = path1+'/'+path_1_doc[k]   
    image_list=os.listdir(i) 
    image_detailed=[i+'/'+j for j in image_list] 
    img_num=len(image_list)
    random_index=random.sample(range(0,img_num-1), int(valid_size*img_num))
    for i in random_index:
        shutil.move(image_detailed[i], path2+'/'+path_1_doc[k])

print("移动完成")

有一个点要解释下:

对于划分数据集,目前用的最多的方案是:

  • 训练集:验证集:测试集 = 8:0.5:1.5
  • 训练集:验证集:测试集 = 7:1:2

但是针对这个比赛,我从数据集里划分7%作为验证集(实际上是测试集,如果要对超参数进行网格搜索,那么需要明确划分出验证集和测试集),是因为:在之前参加的另一个竞赛中,按照这样的比例划分,能够做到线上线下对最终测试结果的精度几乎保持一致。

换句话说,如果有可以用来比对的指标(比如能看到线上和线下的测试集精度),那么可以调整划分验证集的比例,使得两个指标在多次测试中都很接近。如果没有这样的指标,那么最好按照主流的划分标准来划分数据集。

另外,我之前还在知乎上看到一个观点:

对于较深的网络来说,参数量如果比较大,那么需要更多的训练样本拿去训练,如果训练样本较少的话,可能难以填充参数空间。

听起来挺有道理,但是我还没有找到相应的证明,如果有谁知道,还望告知!

注意:主要容易在path上出问题,比如多一个"/"。

最终效果:

数据集按照csv格式标签划分为训练集和验证集(完整代码)_第5张图片

 数据集按照csv格式标签划分为训练集和验证集(完整代码)_第6张图片

你可能感兴趣的:(机器学习/深度学习,Python,深度学习,kaggle,机器学习,python)