Data set partitioning

数据集划分

Posted by biggan on September 15, 2018

数据集划分

1. 留出法(hold-out)

1.将数据集D划分为两个互斥的集合

——训练集S,测试集T。

  • 其中训练集用来训练模型,而测试集用来验证模型对新样本的判别能力。
2.将数据集D划分为三个互斥的集合

——训练集S、验证集V和测试集T。

  • 训练集用来训练模型,验证集用来观察模型性能,测试集用来验证模型效果。

  • 划分为三个集合的方式,相比划分成两个集合的方式更科学。因为我们会根据验证集的效果调整模型参数,导致模型会往验证集效果好的方向收敛,所以用验证集的效果来评估模型性能并不科学。

  • 工具:

    sklearn.model_selection.train_test_split

  • 代码:

from sklearn.model_selection import train_test_split

def divide_data(lang1_path, lang2_path, save_path):
    '''读取数据'''
    with open(lang1_path, 'r', encoding='utf-8') as f:
        lang1 = f.read().strip().split('\n')
    with open(lang2_path, 'r', encoding='utf-8') as f:
        lang2 = f.read().strip().split('\n')
    lang1 = [s + '\n' for s in lang1]
    lang2 = [s + '\n' for s in lang2]
    
    '''划分数据集'''
    x_train, x_valid, y_train, y_valid = train_test_split(lang1, lang2, test_size=1000)
    
    x_valid, x_test, y_valid, y_test = train_test_split(x_valid, y_valid, test_size=300)
    
    #test_id = random.sample(list(range(len(x_valid))), 300)
    #x_test = [x_valid[index] for index in test_id]
    #y_test = [y_valid[index] for index in test_id]
    
    '''保存划分的数据集'''
    train_lang1 = save_path + 'train_' + lang1_path.split('/')[-1]
    train_lang2 = save_path + 'train_' + lang2_path.split('/')[-1]
    valid_lang1 = save_path + 'valid_' + lang1_path.split('/')[-1]
    valid_lang2 = save_path + 'valid_' + lang2_path.split('/')[-1]
    test_lang1 = save_path + 'test_' + lang1_path.split('/')[-1]
    test_lang2 = save_path + 'test_' + lang2_path.split('/')[-1]
    with open(train_lang1, 'w', encoding='utf-8') as f:
        f.writelines(x_train)
    with open(train_lang2, 'w', encoding='utf-8') as f:
        f.writelines(y_train)
    with open(valid_lang1, 'w', encoding='utf-8') as f:
        f.writelines(x_valid)
    with open(valid_lang2, 'w', encoding='utf-8') as f:
        f.writelines(y_valid)
    with open(test_lang1, 'w', encoding='utf-8') as f:
        f.writelines(x_test)
    with open(test_lang2, 'w', encoding='utf-8') as f:
        f.writelines(y_test)
    print('finished!')

2. k折交叉验证

1. KFold

 k折划分

  • 将全部训练集D等分成k个不相交的子集{d1,d2,…,dk}。每次从分好的子集里面,拿出一个作为测试集,其他k-1个作为训练集,这样就可以获得k组训练-测试集,可以进行k次训练与测试,最终的评估结果取K次交叉验证的平均值。

  • 对于交叉验证法,其k值的选取往往决定了评估结果的稳定性和保真性。通常k值选取10。

  • 工具

    sklearn.model_selection.KFold

2. StratifiedKFold

 分层k折划分

  • 和KFold的区别在于,此划分会确保训练集,测试集中各类别样本的比例与原始数据集中相同。

  • 工具

    sklearn.model_selection.StratifiedKFold

  • 代码

    N=10
    kf = StratifiedKFold(n_splits=N, random_state=2019).split(data, labels)
    for i, (train_fold, test_fold) in enumerate(kf):
         X_train, X_validate, label_train, label_validate = \
         	data[train_fold, :],data[test_fold, :], 						labels[train_fold],train_labels[test_fold]
    

3.自助法

 自助法使用有放回重复采样的方式进行数据采样,重点在于有放回,即我们每次从数据集D中取一个样本作为训练集中的元素,然后把该样本放回,重复该行为m次,这样我们就可以得到大小为m的训练集,在这里面有的样本重复出现,有的样本则没有出现过,我们把那些没有出现过的样本作为测试集。