假如我们有一个带标签的数据集D,我们如何选择最优的模型? 衡量模型好坏的标准是看这个模型在新的数据集上面表现的如何,也就是看它的泛化误差。因为实际的数据没有标签,所以泛化误差是不可能直接得到的。于是我们需要在数据集D上面划分出来一小部分数据测试D的性能,用它来近似代替泛化误差。
留出法
留出法的想法很简单,将原始数据直接划分为互斥的两类,其中一部分用来训练模型,另外一部分用来测试。前者就是训练集,后者就是测试集。通常训练集和测试集的比例为7:3。
需要注意:训练\测试集的划分要尽可能保持数据分布的一致性,避免因数据划分过程引入额外的偏差而对最终结果产生影响。那么问题来啦,什么叫保持一致性?譬如在分类过程中,要保证训练集和测试集中每一类的比例要和总样本中每一类的比例保持一致,这样的采样方式成为分层采样。
要注意,train_test_split没有采用分层采样,相当于对数据集进行了shuffle后按照给定的test_size进行数据集划分。
from sklearn import datasets #数据集模块
from sklearn.model_selection import train_test_split #训练集和测试集分割模块
from sklearn.neighbors import KNeighborsClassifier
iris = datasets.load_iris()
iris_x = iris.data
iris_y = iris.target
train_x,test_x,train_y,test_y = train_test_split(iris_x,iris_y,test_size=0.3)
KNN = KNeighborsClassifier(n_neighbors=5)
KNN.fit(train_x,train_y)
print(KNN.score(test_x,test_y))
0.9555555555555556
留出法非常的简单。但是存在一些问题,比如有些模型还需要进行超参数评估,这个时候还需要划分一类数据集,叫做验证集。最后数据集的划分划分变成了这样:训练集,验证集还有测试集。 训练集是为了进行模型的训练,验证集是为了进行参数的调整,测试集是为了看这个模型的好坏。
但是,上面的划分依然有问题,划分出来验证集还有测试集,那么我们的训练集会变小。并且还有一个问题,那就是我们的模型会随着我们选择的训练集和验证集不同而不同。所以这个时候,我们引入了交叉验证。
交叉验证法数据集切分策略
1、 KFold方法 K折交叉验证
将数据集分为k等份,对于每一份数据集,其中k-1份用作训练集,单独的那一份用作测试集。
sklearn中的方法实现为
from sklearn.model_selection import KFold
kf = KFold(n_splits=2)
2、 RepeatedKFold p次k折交叉验证
在实际当中,我们只进行一次k折交叉验证还是不够的,我们需要进行多次,最典型的是:10次10折交叉验证,RepeatedKFold方法可以控制交叉验证的次数。
sklearn中的方法实现为
from sklearn.model_selection import RepeatedKFol