机器学习划分方法
留出法(hold-out)
留出法直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另一个作为测试集T,即D=S∪T,S∩T=空集。在S上训练出模型后,用T来评估其测试误差,作为对泛化误差的估计。
注意训练/测试集的划分要尽可能保持数据分布的一致性,避免因数据划分过程引入额外的偏差而对最终结果产生影响。
交叉验证(cross validation)
交叉验证法先将数据集D划分为k个大小相似的互斥子集,即D=D1∪D2∪……Dk,Di∩Dj=空集(i≠j)。每个子集Di都尽可能保持数据分布的一致性,即从D中通过分层采样得到。然后,每次用k-1个子集的并集作为训练集,余下的那个子集作为测试集,这样就可获得k组训练/测试集,从而可进行k次训练和测试,最终返回的是这k个测试结果的均值。
显然,交叉验证法评估结果的稳定性和保真性在很大程度上取决于k的取值。k的常用取值是10,其他常用的k值有5和20等。
为减小因样本划分不同而引入的差别,k折交叉验证通常要随机使用不同的划分重复p次,最终的评估结果是这p次k折交叉验证结果的均值,例如常见的“10次10折交叉验证”。
特例: 留一法(样本数目m等于划分子集数k)留一法不受随机样本划分方式的影响,因为m个样本只有唯一的方式划分为m个子集。
在留出法和交叉验证法中,保留了一部分样本用于测试,因此实际评估的模型所使用的训练集比D小,这必然会引入一些因训练样本规模不同而导致的估计偏差。留一法受训练样本规模变化的影响较小,但计算复杂度过高。
自助法(BootStrapping)
——可减少训练样本规模不同造成的影响,同时能比较高效地进行实验估计。在数据集较小、难以有效划分训练/测试集时很有用。
以自助采样法为基础,给定包含m个样本的数据集D,我们对它进行采样产生数据集D’:每次随机从D中挑选一个样本,将其拷贝到D’中,然后放回样本,重复m次得到包含m个样本的数据集D’。
通过极限估计,初始数据集D中约有36.8%的样本未出现在采样数据集中,于是将D’作为训练集,D\D’作为测试集。
代码实现
def hold_out(dataSet, train_size):
"""
留出法
dataSet:数据集
train_size:留出法中训练集所占得比例
"""
totalLen = dataSet.shape[0]
train_len = int(totalLen * train_size)
index = range(totalLen)
index_1 = np.random.choice(index, train_len, replace=False) # 训练集的索引
index_2 = np.delete(index, index_1) # 测试集的索引
train = dataSet[index_1]
test = dataSet[index_2]
return train, test
def cross_validation(dataSet, k):
"""
交叉验证法
dataSet:数据集
k:交叉验证的次数
return : datasets:shape(k,num,feature) list类型
"""
datasets = []
num = int(dataSet.shape[0]/k)
start = 0
end = num
for i in range(k):
datasets.append(dataSet[start:end, :].tolist())
start += num
end += num
return datasets
def BootStrapping(dataSet):
"""
自助法
:param dataSet:数据集
:return: train训练集,test测试集
"""
m = dataSet.shape[0]
index1 = []
index2 = []
for i in range(m):
index1.append(np.random.randint(m))
index2 = np.delete(range(m), index1)
train = dataSet[index1]
test = dataSet[index2]
return train, test