数据分割

留出法、交叉验证法、自助法

Posted by 新宇 on February 3, 2020

一、留出法

1. 概念

  • 直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另一个作为测试集T
    • 即 D = S ∪ T, S ∩ T = ∅
  • 在S上训练出模型后,用T来评估其测试误差,作为对泛化误差的估计
    • 泛化能力:训练好的模型对于未知数据和未知场景下的表现能力;
    • 泛化误差:模型在未知数据上的误差,一般可以使用测试误差来近似泛化误差;

2. 代码实现

from sklearn.model_selection import train_test_split 
# 使用train_test_split划分训练集和测试集

train_X , test_X, train_Y ,test_Y = train_test_split(X, Y, test_size=0.2,random_state=0)

3. 留一法

  1. 在留出法中,有一个特例,叫: 留一法(Leave-One-Out,简称LOO),即每次抽取一个样本做为测试集。
  2. 代码实现
     from sklearn.model_selection import LeaveOneOut
    
     data = [1, 2, 3, 4]
     loo = LeaveOneOut()
     for train, test in loo.split(data):
         print("%s %s" % (train, test)) 
    
     # 结果
    
     [1 2 3] [0] 
     [0 2 3] [1] 
     [0 1 3] [2] 
     [0 1 2] [3] 
    
    
  3. 优缺点
    • 优点:留一法的评估结果往往被认为比较准确
    • 缺点:在数据集比较大时,训练m个模型的计算开销可能是难以忍受的

二、交叉验证法

1. 概念

  • 先将数据集D划分为k个大小相似的互斥子集
    • 即 D = D1 ∪ D2 ∪ D3 …… ∪ Dk , Di ∩ Dj = ∅ (i!=j)
  • 每个子集Di都尽可能保持数据分布的一致性,即从D中通过分层抽样得到。
  • 然后,每次用k-1个子集的并集作为训练集,余下的那个子集作为测试集;
  • 这样就可获得k组训练/测试集,从而可进行k次训练和测试,最终返回的是这k个测试结果的均值。

2. API

  • KFold
    • 随机采样,不能保证各样本比例一致;
  • StratifiedKFold
    • 分层采样,确保训练集,测试集中,各类别样本的比例是和原始数据集中的一致。

3. 代码

import numpy as np
from sklearn.model_selection import KFold,StratifiedKFold

X = np.array([[1,2,3,4], [11,12,13,14], [21,22,23,24], [31,32,33,34], [41,42,43,44], [51,52,53,54], [61,62,63,64], [71,72,73,74]])
y = np.array([1,1,0,0,1,1,0,0])


folder = KFold(n_splits = 4, random_state=0, shuffle = False)
sfolder = StratifiedKFold(n_splits = 4, random_state = 0, shuffle = False)
for train, test in folder.split(X, y): 
	print('train:%s | test:%s' %(train, test)) 
	print("")

for train, test in sfolder.split(X, y): 
 	print('train:%s | test:%s'%(train, test)) 
 	print("")

三、自助法

1. 概念

2. 优缺点

  • 优点:
    • 自助法在数据集较小、难以有效划分训练/测试集时很有用;
    • 此外,自助法能从初始数据集中产生多个不同的训练集,这对集成学习等方法有很大的好处。
  • 缺点:
    • 自助法产生的数据集改变了初始数据集的分布,这会引入估计偏差。因此,在初始数据量足够时,留出法和交叉验证法更常用一些。

四、总结

  • 当我们数据量足够时,选择留出法简单省时,在牺牲很小的准确度的情况下,换取计算的简便;
  • 当我们的数据量较小时,我们应该选择交叉验证法,因为此时划分样本集将会使训练数据过少;
  • 当我们的数据量特别少的时候,我们可以考虑留一法