python训练集和测试集实例,Python训练集
机器学习的简单流程:使用大量任务相关数据集训练模型;通过模型在数据集上的误差,反复训练模型,得到一个合理拟合数据集的模型。将训练和调整后模型应用于真实场景;我们的最终目的是将训练好的模型部署到真实环境中,希望训练好的模型能够在真实数据上得到很好的预测效果,换句话说就是希望模型对真实数据的预测结果误差越小越好。我们把模型在真实环境下的误差称为泛化误差,最终的目的是希望训练好的模型泛化误差越低越好。
我们希望通过某个信号来了解模型的泛化误差,从而指导我们得到一个泛化能力更强的模型:
使用泛化误差本身。这是很自然的想法。我们训练模型的最终目标是最小化模型的泛化误差。当然,泛化误差本身可以用作检测信号。如果泛化误差小,还可以接受,但通常就没那么幸运了,泛化误差可能很大。这个时候你肯定会撤回部署的模型,重新训练。您可能需要在部署和培训之间来回多次。这种方法虽然可以更好的指导我们的模型,但是成本和效率都很差;在数据集上训练的模型的拟合度被用作评估模型的信号。然而,通常我们得到的数据集并不完全干净和具有代表性。通常,我们得到的数据集可能很少,代表性不够,包含太多噪声或者被一些不相关的特征污染。我们得到的数据集或多或少都会有这些问题,所以模型对训练数据集的拟合程度并不能引导泛化误差。也就是说,训练时拟合好并不代表模型的泛化误差小。你甚至可以把模型在数据集上的误差降低到0,但由于训练模型时数据集往往不干净,这样的模型并不代表泛化能力强。
1.训练集与测试集如前所述,我们既不能直接用泛化误差作为信号来知道模型的泛化能力,因为在部署环境和训练模型之间往复代价很高,也不能用模型对训练数据集的拟合程度作为信号来知道模型的泛化能力,因为我们得到的数据往往不干净。
更好的方法是将数据分成两部分:训练集和测试集。我们可以用训练集的数据来训练模型,然后用测试集的误差作为最终模型在处理真实场景时的泛化误差。通过测试集,我们希望验证模型的最终效果。我们只需要计算训练好的模型在测试集上的误差,就可以看作是泛化误差的近似。我们只需要使我们的训练模型在测试集上的误差最小。
这里有几点需要注意:
一般80%的数据集作为训练集,20%作为测试集;通常,我们需要在建立模型之前划分数据集,以防止数据窥探错误。也就是说,要避免过多了解测试集中样本的特征,防止我们认为有助于测试测试集中数据的模型。这个结果会过于乐观,但实际上并没有预想的那么好。通常我们在建立模型的时候,需要对数据进行处理,包括一些数据清洗和数据特征缩放(标准化或规范化)。这时候我们只需要对训练集进行这些操作,然后将从训练集得到的参数应用到测试集。也就是说,在工作流中,你不能使用任何在测试数据集上计算的结果。比如我们得到的属性中可能会有缺失值,因为在这些操作之前,我们已经把数据集分成了训练集和测试集。通常的方法是通过计算属性值的中值来填充缺失值。请注意,计算属性值的中值是由训练集中的数据计算的。当我们得到一个模型时,如果要测试模型的测试误差来逼近泛化误差,此时测试集中可能会有一些缺失值,对应属性的缺失值就是训练集计算出来的中位数。由于测试集是泛化误差的一个近似,所以对模型进行了很好的训练,最后在测试集上近似估计模型的泛化能力。这时,假设有两种不同的机器学习模型。当你犹豫不决的时候,可以对两个模型进行训练,然后在测试数据上比较它们的泛化误差,选择泛化能力强的模型。说了这么多,如何把数据集分成训练集和测试集?其实很简单。您可以编写自己的程序或使用sklearn提供的模块:
通过简单代码实现:
导入numpy为NP def split _ train _ test (data,test _ ratio): #设置随机数种子,保证每次生成的结果都是一样的np.random.seed(42) #permutation随机生成0-len(data)随机序列shuffled _ indicators=NP。随机的。permutation(len(data))# Test _ ratio是测试集Test _ set _ size=int(len(data))* Test _ ratio Test _ indicators=shuffled _ indicators[:Test _ ratio]Train _ indicators=shuffled _ indicators[Test _ set _ size:]# iloc在参数序列中选择相应的行,返回data.iloc [train _ indicators],data . iloc[Test _ indicators]# Test Train _ set,test_set=split_train_test(data,0.2)print(len(len(Train _ set),。
Fromsklearn.model _ selection导入train _ test _ split # data:要划分的数据集#random_state:设置随机种子以确保每次运行时生成相同的随机数#test_size:将数据划分到训练集的比率# train_set,Test _ set=train _ test _ split (data,test _ size=0.2,random _ state=42)。前面介绍的两种数据集分割方法都是采用纯随机抽样,对于大量数据集和目标值的均匀分布是可行的。比如分类任务,我们训练一个二元分类器,数据可能包含大量的正例,只有10%的负例。这时候标签分布很不均匀。如果我们随机抽样,在极端情况下,所有的正例可能被分到训练集,而所有的负例恰好被分到测试集。这样,训练出来的模型效果不会很好,所以我们需要对数据集进行分层抽样划分,也就是说。
好在sklearn提供了我们的分层抽样功能。在此之前,看一下官方的例子:
from sklearn.model_selection导入StratifiedShuffleSplitX=NP . array([[1,2],[3,4],[1,2],[3,4]])y=np.array([0,0,1,1])split=StratifiedShuffleSplit(n _ splits=3,test_size=0.5,random_state=0)print(split)# doctest:省略号StratifiedShuffleSplit(n _ splits=3,random _ state=0,)for train_index,test_index in split.split(X,y): print(TRAIN:,train_index, test:,test_index) X_train,X_test=X[train_index],X[test_index] y_train,y_test=y[train_index],y[TEST _ index] StratifiedShuffleSplit(n _ split=3,random_state=0,Test _ size=0.5,TRAIN _ size=none)TRAIN:[12]TEST:[30]TRAIN:[02]
N_splits:分裂迭代次数,如果我们要划分训练集和测试集,设置为1;Test_size:分割测试集的比例;Random_state:设置随机种子;有两种方法划分原始mnist数据集。首先,准备数据集:
Fromsklearn.datasets导入fetch _ mldata #我把最原始的mnist数据集下载到当前路径,指定data _ homemnist=fetch _ ml data( MNIST原始,data_home=r 。/)x_data=mnist[data]。shape((mnist[data])。shape[0],-1))y_data=mnist[target]。整形((mnist[target])。shape[0],-1))print(x_data.shape) #(70000,784)print(y_data.shape) #(70000,1)随机抽样划分数据集:#随机抽样划分数据集从sklearn.model _ selection导入train _ test _ split导入numpy as NP data=NP . h stack((x _ data,y _ data)) #先拼接数据集,否则如果只抽样,就找不到train _ set,test _了Len(test_set))56000 14000 分层抽样拆分数据集:from sklearn.model _ selection导入分层混洗拆分=分层混洗拆分(n _ splits=1,Test _ size=0.2,random _ state=42) #分层抽样根据mnist[target] for train _ index,Test _ index in Split . Split(data[:-1]):train _ set=data[train _ index,] test _ set=data [test _ index,]print(len(len len (test _ set)) 56000 14000 如果想知道每个样本抽取的比例,可以将数据转换成DataFrame对象(当然也可以在数据处理开始时将数据转换成DataFrame,方便操作。
#将分段的训练数据转换成DataFrame#这里的参数数据可以是分段的训练集或测试集train _ data=PD . data frame(train _ set)#快速查看数据train_data.info()的描述#查看各个类别的比例打印(train _ data [784])。value_counts()/len(train_data))下面的数字分别是:原始数据的10类比例,随机抽样的10类比例通过sklearn实现:和分层抽样的10类比例训练集(当然测试集也可以统计)。
统计比较
从上面的分析可以看出,分层抽样的10个类别的比例与原始数据中10个类别的比例非常接近。
训练集如前所述,我们将数据集分为训练集和测试集。我们在训练集上训练模型,然后在测试集上近似模型的泛化能力。如果要选择不同的模型,可以在训练集上分别训练这两个模型,然后在测试集上分别测试这两个训练好的模型。因为我们把测试集上的误差近似为泛化误差,自然可以选择测试集上误差小的模型作为泛化能力强的模型。
但是我们要做的不仅仅是不同模型之间的比较,很多时候我们需要选择模型本身。如果我们有两个模型,一个线性模型和一个神经网络模型,我们知道神经网络的泛化能力比线性模型强。我们选择了神经网络模型,但是神经网络中还有很多参数需要手动选择。比如神经网络的层数,每层神经网络的神经元个数以及一些正则化参数等。我们称这些参数为2.验证集。这些参数的不同选择对模型的最终效果也非常重要。我们在开发模型时总是需要调整这些超级参数。
现在我们需要调整这些超参数,使模型的泛化能力最强。我们用测试集作为泛化误差估计,我们的最终目的是选择一个泛化能力强的模型。然后,我们可以直接通过模型在测试集上的误差来调整这些参数。可能测试集中模型的误差为0,但是如果你拿这样的模型部署到真实场景,效果可能会很差。
这种现象被称为超参数。。我们用测试集作为泛化误差的近似值,所以直到最后也不能泄露测试集的信息,就像考试一样。我们平时做的题相当于训练集,测试集相当于期末考试。我们通过期末考试测试自己最后的学习能力,泄露考试集合的信息,相当于学生提前知道考试题目。那么最后,提前把这些已知的考题考好,当然也就没什么意思了,期末考试你还能拿更高的分数。如果你通过测试集调整模型,相当于不仅知道了试题,还学会了怎么做(因为我们一定会人为的把测试集中模型的误差做到最小,因为这是你调整超参数的目的)。如果再拿这些题来考,大家可能都是满分,但是对学生的学习能力没有起到检验的作用。我们以前是通过测试集来近似泛化误差,也就是通过考试来测试学生的学习能力。但是由于信息泄露,此时的测试集,也就是考试,已经没有任何意义了。现实中,学生的能力可能很差。所以我们在学习的时候,老师会准备一些小测验,帮助我们查漏补缺。这些小测试也是要说的验证集。我们以验证集为基础来调整模型,这样测试集中的信息就不会泄露。
也就是说,我们把数据分为训练集、验证集和测试集。该模型在训练集上被训练,并在验证集上被评估。一旦找到最佳参数,就在测试集上进行最后一次测试,将测试集中的误差作为泛化误差的近似值。至于验证集的划分,可以参考测试集的划分,不过都是一样的,这里就不赘述了。
冷艳小懒猪老师的视频中,如果数据量不大(10000以下),训练集、验证集、测试集的划分是6:2:2;如果数据量较大,可以将训练集、验证集和测试集的比例调整为98:1:1;但在可用数据较少的情况下,可以使用一些先进的方法,如搁置、K倍交叉验证等。
信息泄露
1.《Hands-On Machine Learning with Scikit-Learn and TensorFlow》
历史提交的图片或压缩文件
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。