之前使用train_test_split函数将数据集随机划分为训练集和测试集,然后使用score方法评估监督学习模型。随机划分时,如果恰好很不幸不容易分类的数据集都在测试集,会得到一个不切实际的低分。
于是使用交叉检验,每个分类样例都会出现在测试集和训练集。
交叉检验的是评估给定算法在特定数据集上训练后的泛化性能好坏的统计学方法。不会返回一个模型,不是一种构建可应用于新数据的模型的方法。
标准k折交叉检验:回归问题默认使用。根据用户指定的k划分数据,经历k次训练测试,每次一折当测试集其它的是训练集。
分层k折交叉检验:分类问题使用。划分数据,是每个折中类别比例与整个数据集中比例相同。防止出现某折中指包含一个类别的样本,无法评估整体信息。
每一次检验返回一个精度值,最后通过计算平均值总结交叉验证精度。
k折交叉检验
在iris数据集上对LogisticRegression进行评估:
from sklearn.model_selection import cross_val_scorefrom sklearn.datasets import load_irisfrom sklearn.linear_model import LogisticRegressioniris = load_iris()logreg = LogisticRegression()scores = cross_val_score(logreg, iris.data, iris.target, cv=5)print(scores) # [0.96666667 1. 0.93333333 0.96666667 1. ]print(scores.mean()) # 0.9733333333333334
cross_val_score函数实现交叉验证,返回k个精度值。需要传递参数(评估的模型,训练数据,真实标签)。可选cv参数,指定k值,默认3。
mean()函数:求取均值。
分层k折交叉验证
使用KFold分离器(通过将数据打乱代替分层)作为cv参数对数据划分进行控制:
from sklearn.model_selection import KFoldkfold = KFold(n_splits=5, shuffle=True)print(cross_val_score(logreg, iris.data, iris.target, cv=kfold))
sklearn.model_selection.KFold(n_splits=’warn’, shuffle=False, random_state=None)将训练/测试数据集划分n_splits个互斥子集。
shuffle=True则对传入的数据集打乱,随机划分n_splits组数据。常与random_state配合使用,以保证重复运行代码得到的随机划分一致。
留一法交叉检验
可以看作没这只包含单个样本的k折交叉检验,即每次选择单个数据点作为测试集。耗时大,但是在小型数据集估计结果较好。
from sklearn.model_selection import LeaveOneOutloo = LeaveOneOut()scores = cross_val_score(logreg, iris.data, iris.target, cv=loo)print(len(scores)) # 150print(scores.mean()) # 0.9666666666666667
打乱划分交叉验证
可以控制迭代次数,控制训练集测试集占比,还允许每次迭代中进使用部分数据。
from sklearn.model_selection import ShuffleSplitshuffle_split = ShuffleSplit(test_size=.5, train_size=.5, n_splits=10)print(cross_val_score(logreg, iris.data, iris.target, cv=shuffle_split))
分组交叉验证
由一个数组指定分组代替k折
from sklearn.model_selection import GroupKFoldfrom sklearn.datasets import make_blobsx, y = make_blobs(n_samples=12, random_state=0)groups = [0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3]print(cross_val_score(logreg, x, y, groups, cv=GroupKFold(n_splits=3)))
【机器学习】(二十一)模型评估——交叉检验:k折交叉检验 分层k折交叉验证 留一法交叉检验 打乱划分交叉验证 分组交叉验证