StratifiedKFold和KFold的区别(几种常见的交叉验证)

一、交叉验证的定义

交叉验证即把得到的样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测试集来评估模型预测的好坏。交叉验证通过重复使用数据,多次切分可得到多组不同的训练集和测试集,某次训练集中的某样本在下次可能成为测试集中的样本,即所谓“交叉”。

通常在数据量不大,或者想要减少过拟合的时候用到。

二、几种常用的交叉验证对比

1.sklearn.train_split_test

通常不进行交叉验证的时候,用sklearn.train_split_test来对数据进行切分。train_split_test只把原数据集按test_size随机不重复地划分成训练集和测试集,用训练集来验证模型,用测试集来评估模型的得分高低。由于只划分一次,所以没有交叉验证。

from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(train_data,train_lable,test_size=0.3,random_state=o,stratify=train_lable)

参数说明:

train_data:样本特征集
train_target:样本的标签集
test_size:样本占比,测试集占数据集的比重,如果是整数的话就是样本的数量
random_state:是随机数的种子。在同一份数据集上,相同的种子产生相同的结果,不同的种子产生不同的划分结果

stratify:有时候遇见非平衡数据,让该参数等于标签列,可以让数据划分的时候按标签来划分,避免划分后的训练集和测试集在标签分布上不均。

2.sklearn.cross_val_score,cross_validate

最简单的交叉验证可以在训练模型后用cross_val_score,cross_validate 来进行,下面用svm来解释

from sklearn.model_selection import cross_val_score,cross_validate
from sklearn import svm
clf = svm.SVC(kernel='linear', C=1) scores = cross_val_score(clf, iris.data, iris.target, cv=5) #交叉验证cv为迭代次数。 print('迭代5次的scores',scores) # 打印输出每次迭代的度量值(准确度) # [0.96666667 1. 0.96666667 0.96666667 1. ] print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2)) # 获取置信区间。(也就是均值和方差),std()计算标准偏差Accuracy: 0.98 (+/- 0.03) # =======================多种度量结果=================== scoring = ['precision_macro', 'recall_macro'] # precision_macro为精度,recall_macro为召回率 # sklearn.metrics.SCORERS.keys() scores = cross_validate(clf, iris.data, iris.target, scoring=scoring,cv=5, return_train_score=True) sorted(scores.keys()) print('测试结果:',scores) # scores类型为字典。包含训练得分,拟合次数, score-times (得分次数)

3.StratifiedKFold和KFold

K折交叉验证会把样本数据随机的分成K份(一般是均分),每次随机的选择K-1份作为训练集,剩下的1份做测试集。当这一轮完成后,重新随机选择K-1份来训练数据。若干轮(小于K)之后,选择损失函数评估最优的模型和参数。

将每个子集数据分别做一次测试集,其余的K-1组子集数据作为训练集,所以一般分成K份就这样会得到K组模型,用这K个模型最终的测试集的分类准确率的平均数作为此K-CV下分类器的性能指标。

优点是可以降低由一次随机划分带来的偶然性,提高其泛化能力。但K折还有个问题就是因为是随机划分,很有可能划分的过程中刚好把类别都划分开了,比如第一折训练集里全是0标签,第二折测试集里全是1标签,这样对模型训练就不太好,在其中的某个模型学习的时候就没有学习到测试集的分类特征。在KFold中就是这样的,对于不平衡数据集,特别是一些比赛数据正类非常少,那么直接用KFold就可能出现这种问题。

所以对非平衡数据可以用分层采样StratifiedKFold,就是在每一份子集中都保持和原始数据集相同的类别比例。若数据集有4个类别,比例是2:3:3:2,则划分后的样本比例约是2:3:3:2,StratifiedShuffleSplit() 划分中每个类的比例和完整数据集中的相同,若数据集有4个类别,比例是2:3:3:2,则划分后的样本比例也是2:3:3:2

from sklearn.model_selection import KFold
from sklearn.model_selection import StratifiedKFold

kfolder = KFold(n_splits=4,random_state=1)
for train, test in kfolder.split(X,y):
    print('Train: %s | test: %s' % (train, test),'\n')
>>>
Train: [2 3 4 5 6 7] | test: [0 1]
Train: [0 1 4 5 6 7] | test: [2 3]
Train: [0 1 2 3 6 7] | test: [4 5]
Train: [0 1 2 3 4 5] | test: [6 7]

folder = StratifiedKFold(n_splits=4,random_state=0)
for train, test in sfolder.split(X,y):
    print('Train: %s | test: %s' % (train, test))
>>>
Train: [1 3 4 5 6 7] | test: [0 2]
Train: [0 2 4 5 6 7] | test: [1 3]
Train: [0 1 2 3 5 7] | test: [4 6]
Train: [0 1 2 3 4 6] | test: [5 7]

 

 

更多交叉验证参考:https://blog.csdn.net/u010986753/article/details/98069124

 

上一篇:XPOSED优秀模块列表 --- xRenamer


下一篇:欧盟项目--税务系统ELSTER连接