一、概述

1.1 交叉验证的含义与作用

交叉验证的思想是,将数据集分为k等份,其中k-1份作为训练集,单独留出的一份作为测试集。
进行模型验证的目的就是为了确定最合适的模型,对于监督学习而言,为了使得创建的模型具有很好的泛化能力,通常需要将得到的数据预留出测试数据进行交叉验证。因此,交叉验证的目的主要为了解决建立模型的过拟合问题。
交叉验证的具体过程为,将所有数据分为训练集与测试集两部分,采用训练集对模型进行训练。采用测试准确度指标,对得到的模型用测试集来衡量模型的预测能力。

1.2 交叉验证的分类

交叉验证的分类主要体现再划分方法上,根据划分方法的不同常用的交叉验证方法包括:k折交叉验证、p次k折交叉验证、留一法、留p法、随机分配方法。
1、k折交叉验证(KFold),将数据集划分为k等份,使用python的sklearn.model_selection库中的KFold方法实现。
2、p次k折交叉验证(RepeatedKFold),在实际应用中,只进行以此k折交叉验证往往不够,需要进行多次交叉验证,使用python的sklearn.model_selection库中RepeatedKFold方法实现。
3、留一法(LeaveOneOut),是对整个数据集每次选取一个样本作为验证集,其余样本作为训练集。它是k折交叉验证的一种特殊情况,即k=n(n为数据集的个数)的情况,使用python的sklearn.model_selection库中的LeaveOneOut方法实现。
4、留p法(LeavePOut),原理与留一法一样,只不过是对整个数据集每次选取p个样本作为验证集,其余样本作为训练集。它使用python的sklearn.model_selection库中的LeavePOut方法实现。
5、随机分配(ShuffleSplit),随机把数据打乱,然后划分训练集与测试集,使用python的sklearn.model_selection库中的ShuffleSplit方法实现。
另外,针对某些特殊情况,通常采用特殊的交叉验证方法
1、对于分类数据,预测目标可能是不均匀分配的,比如抽烟的烟得肺癌的比率彼不抽的人大,这种情况的数据划分通常采用StratifiedKFold、StratifiedShuffleSplit方法。
2、对于分组数据来说,它的划分方法是不一样的,主要的方法有 GroupKFold,LeaveOneGroupOut,LeavePGroupOut,GroupShuffleSplit。
3、对于时间关联的数据,方法有TimeSeriesSplit。

二、交叉验证实例分析

本文python的版本为3.8,各个版本之间函数名字略有不同,但是原理都是一样的,集成开发环境使用的是Anaconda的Spyder,以下程序都是经过编译后,顺利执行的,读者如果有什么疑问,可以留言。

2.1 留一法实例

留一法的python源代码如下所示:

from sklearn.datasets import load_iris  #导入鸢尾花数据库
#下面语句导入留一法LeaveOneOut,交叉验证评价指标cross_val_score评价指标
from sklearn.model_selection import LeaveOneOut, cross_val_score
#下面语句导入逻辑斯特回归LogisticRegression
from sklearn.linear_model import LogisticRegression

iris = load_iris()	#将鸢尾花数据库中的数据放入iris变量中
print('Iris labels:\n{}'.format(iris.target))	#输出鸢尾花的目标分类,共有三种分别表示为0,1,2
logreg = LogisticRegression()	#逻辑斯特回归对象logreg
loout = LeaveOneOut()	#留一法对象loout
#下面的语句计算评价指标并输出到scores对象,采用cress_val_score方法,
#方法参数含义为,采用逻辑斯特回归方法logreg拟合数据:iris.data,iris.target,
#交叉验证的方法为留一法loout
scores = cross_val_score(logreg,iris.data,iris.target,cv=loout)
#下面语句输出每个样本的拟合评价结果
print("leave-one-out cross validation scores:{}".format(scores))
#下面语句输出整体评价结果,即所有样本的评价结果平均值
print("Mean score of leave-one-out cross validation:{:.2f}".format(scores.mean()))

输出结果如下图所示:
在这里插入图片描述

2.2 留p法实例

留p法的python源代码如下所示:

#导入训练集数据划分方法库train_test_split、留p法库LevePOut
from sklearn.model_selection import train_test_split, LeavePOut
from sklearn import datasets	#导入数据集
from sklearn import svm			#导入支持向量机svm
from sklearn.metrics import accuracy_score	#导入评价指标库
import numpy as np	#导入数学分析库

iris = datasets.load_iris()		#将鸢尾花数数据放入iris变量中
clf_svc = svm.SVC(kernel='linear')	#线性核函数svm模型对象为clf_svc

lpo = LeavePOut(p=3)				#留p法对象lpo
lpo.get_n_splits(iris.data)		#对鸢尾花数据进行划分
mean_accuracy_score_list = []
for train_index, test_index in lpo.split(iris.data):
	clf_svc.fit(iris.data[train_index], iris.target[train_index])
	prediction = clf_svc.predict(iris.data[test_index])
	mean_accuracy_score_list.append(accuracy_score(iris.target[test_index],prediction))
print(np.average(mean_accuracy_score_list))

输出结果如下图所示:
在这里插入图片描述

2.3 k折交叉验证(Standard Cross Validation)实例

在python语言中,该方法需要通过train_test_split方法对数据集进行划分,然后再不同的数据集上进行训练、测试评估,进而得到评价结果。k通常取5或者10,如果取10,则表示再原始数据集上,进行10次划分,每次划分都进行以此训练、评估,对5次划分结果求取平均值作为最终的评价结果。10折交叉验证的原理图如下所示:
在这里插入图片描述
这里以python自带的乳腺癌数据为分析对象,采用k折交叉验证分析拟合模型的准确性,k折交叉验证的python源代码如下所示:

#以下几行代码,例行公事,载入需要的库函数
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression

cancer = load_breast_cancer()
logreg = LogisticRegression()

#以下指令中的cross_val_score自动对乳腺癌数据进行k折交叉验证,
#注意:cross_val_score的参数cv没有设置,默认是3,可以修改cv为5或10,
#则该方法则成为5或10折交叉验证
scores = cross_val_score(logreg,cancer.data,cancer.target)

#打印分析结果,由于默认cv为3,即3折交叉验证,所以第一个输出为三个指标值
print("Cross validation scores:{}".format(scores))
print("Mean cross validation score:{:2f}".format(scores.mean()))

输出结果如下图所示:
在这里插入图片描述

2.4 随机分配交叉验证(Shuffle-split cross-validation)实例

使用ShuffleSplit方法,可以随机的把数据打乱,然后分为训练集和测试集。随机分配交叉验证的python源代码如下所示:

from sklearn.datasets import load_iris
from sklearn.model_selection import ShuffleSplit,cross_val_score
from sklearn.linear_model import LogisticRegression

iris = load_iris()
shufspl = ShuffleSplit(train_size=.5,test_size=.4,n_splits=8) #迭代8次;
logreg = LogisticRegression()
scores = cross_val_score(logreg,iris.data,iris.target,cv=shufspl)

print("shuffle split cross validation scores:\n{}".format(scores))
print("Mean score of shuffle split cross validation:{:.2f}".format(scores.mean()))

输出结果如下图所示:
在这里插入图片描述

2.5 分层交叉验证(Stratified k-fold cross validation)实例

分层交叉验证(Stratified k-fold cross validation):首先它属于交叉验证类型,分层的意思是说在每一折中都保持着原始数据中各个类别的比例关系,比如说:原始数据有3类,比例为1:2:1,采用3折分层交叉验证,那么划分的3折中,每一折中的数据类别保持着1:2:1的比例,这样的验证结果更加可信。
通常情况下,可以设置cv参数来控制几折,但是我们希望对其划分等加以控制,所以出现了KFold,KFold控制划分折,可以控制划分折的数目,是否打乱顺序等,可以赋值给cv,用来控制划分。
分层交叉验证的python源代码如下所示:

from sklearn.datasets import load_iris
from sklearn.model_selection import StratifiedKFold,cross_val_score
from sklearn.linear_model import LogisticRegression

iris = load_iris()
print('Iris labels:\n{}'.format(iris.target))
logreg = LogisticRegression()
strKFold = StratifiedKFold(n_splits=3,shuffle=False,random_state=0)
scores = cross_val_score(logreg,iris.data,iris.target,cv=strKFold)
print("straitified cross validation scores:{}".format(scores))
print("Mean score of straitified cross validation:{:.2f}".format(scores.mean()))

输出结果如下图所示:
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐