首页天道酬勤交叉验证步骤(sklearn 交叉验证)

交叉验证步骤(sklearn 交叉验证)

admin 11-30 07:26 335次浏览

注:本文所有代码均来自scikit-learn官网。

实际上,如果模型上线,数据分析师需要反复调试模型,以防止模型仅在已知数据集上表现良好,而在未知数据集上表现不佳。即保证模型的泛化能力,是指机器学习对新鲜样本的适应性。只有保证模型的泛化能力,模型的构建才有意义。因此,交叉验证在整个建模过程中尤为重要。

如果不处理数据集,而只用带标签的已知数据训练模型,会得到很高的分数,但却无法预测未知数据,这就是所谓的“过拟合”。过拟合的出现表明模型没有学习到数据中的本质规律,导致模型的预测能力较差。因此,如何避免模型的过拟合是一个值得关注和必须解决的问题。在scikit-learn中,可以使用训练集/测试集拆分和交叉验证来避免这种情况。如下图所示,将数据集拆分为训练集/测试集,在训练集上交叉验证后得到最佳模型参数,这样就可以在测试集上得到模型的得分。

分享之前,要搞清楚两个概念:过拟合和欠拟合。其中,过拟合意味着模型在训练集中得分较高,在测试集中得分较低。欠拟合是指模型拟合程度不高,数据距离拟合曲线较远,或者模型没有很好地捕捉数据特征,不能很好地拟合数据。相对于过拟合,欠拟合并不经常发生。很容易想到,如果模型的拟合能力局限在过拟合和欠拟合之间,会得到更好的模型预测结果,但训练集/测试集的划分和交叉验证只能帮助避免过拟合而不是欠拟合。

以sklearn中的iris数据集为例说明:

将numpy作为np导入

来自sklearn.model_selection导入train_test_split

从sklearn导入数据集

从sklearn导入svm

X,y=数据集。load_iris(return_X_y=True)

x形,y形

((150,4),(150,150))将数据集分为60%的训练集和40%的测试集。代码如下:

X_train,X_test,y_train,y_test=train_test_split(

.x,y,test_size=0.4,random_state=0)

X_train.shape,y_train.shape

((90, 4), (90,))

X_test.shape,y_test.shape

((60, 4), (60,))

clf=svm。SVC(核='线性',C=1)。拟合(X_train,y_train)

clf.score(X_test,y_test)

0.96 .虽然该模型在测试集上得分较高,此时表现良好,但并不意味着找到了最佳适用模型,如支持向量机的超参数C。在上例中,当参数C=1设置时,可能在训练集上表现良好,但仍然无法避免过拟合的现象,因为不适当的超参数设置可能会导致模型学习数据中的主要规则,因此在测试集上会出现过拟合。为了避免上述情况,scikit-learn提供了交叉验证(CV)。需要注意的是,k值越大,即皱纹越多,可以减少的偏差引起的误差就越多,但训练集越大,模型的方差和误差就越大。同时,k值越大,时间成本越高。所以k值的选择很重要,常用的值是k=10。

在下面的示例中,cv值设置为5,并且执行五次交叉验证迭代以获得五个模型分数:

来自sklearn.model_selection导入cross_val_score

clf=svm。核='线性',C=1

分数=cross_val_score(clf,X,y,cv=5)

得分

数组([0.96. 1 . 0.96 . 0.96 . 1 .】)还可以根据不同的模型和实际场景调整交叉验证的评分策略。需要注意的是,在scikit-learn的官方文档中,有五种交叉验证方法(五种方法分别是:k-fold、REP

ndom permutations cross-平淡的仙人掌 & Split)的数据应是服从独立同分布假设的,在此基础上,交叉验证的结果较好,但文档中也说明,独立同分布假设在现实中很难保证,因此,在应用交叉验证方法时,可适当放宽假设条件,但可能会让度一部分结果准确性。

其中,K折交叉验证(K-fold cross-validation)是交叉验证大家族中最简单的数据拆分策略,即将数据集拆分为训练集和测试集,如下图所示,其原理为:先将整个数据集分为k个折叠,用其中k-1个折叠作为训练集训练模型,用剩余的1个折叠作为验证集对模型进行评分,并重复k次上述过程。该种方法的优势在于不需要额外拆分数据,以避免数据的浪费和运算成本的提高;可以促使模型从多方面学习样本,避免模型陷入局部极值。

如下是对有4个样本的2-折交叉验证示例,随机将数据分为两个折叠,并且迭代上述步骤两次。其代码如下:

>>> import numpy as np >>> from sklearn.model_selection import KFold ​ >>> X = ["a", "b", "c", "d"] >>> kf = KFold(n_splits=2) >>> for train, test in kf.split(X): ...     print("%s %s" % (train, test)) [2 3] [0 1] [0 1] [2 3]

在scikit-learn中,还提供基于K折(KFold)法的进一步交叉验证法,为重复的K折(Repeated K-Fold),即将K折重复n次,通过设置n_repeats参数进行传递。其底层原理与KFold相一致,不同点在于重复的K折将K折重复n_repeats次。

选用的数据集与K折示例中的相同,设置n_repeats参数值为2,其代码如下:

>>> import numpy as np >>> from sklearn.model_selection import RepeatedKFold >>> X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]]) >>> random_state = 12883823 >>> rkf = RepeatedKFold(n_splits=2, n_repeats=2, random_state=random_state) >>> for train, test in rkf.split(X): ...     print("%s %s" % (train, test)) ... [2 3] [0 1] [0 1] [2 3] [0 2] [1 3] [1 3] [0 2]

比较出名的是留一法(Leave One Out),它是一个简单又有趣的交叉验证方法。其原理是出去一个样本外,保留数据集中的所有样本,从而将用于交叉验证的数据集(假设共有n个样本)分为训练集(n-1个样本)和测试集(1个样本)的组合,使得对于一个包含n个样本的数据集而言,可以有n个测试集对模型进行评估。该方法的优势在于最大可能的保证用于模型训练的数据量,仅牺牲一个样本作为测试集,对于大样本而言是可以忽略不计的。

如下的示例中,仍延用上一个例子中的包含四个样本的数据,在每次迭代中,从四个样本中分出一个样本作为测试集。其代码如下:

>>> from sklearn.model_selection import LeaveOneOut ​ >>> X = [1, 2, 3, 4] >>> loo = LeaveOneOut() >>> for train, test in loo.split(X): ...     print("%s %s" % (train, test)) [1 2 3] [0] [0 2 3] [1] [0 1 3] [2] [0 1 2] [3]

提到留一法(Leave One Out)就不得不说留P法(Leave P Out),两种方法的底层逻辑相同,只是留P法在留一方的基础上为使用者提供更大的自由空间,使用者可以根据业务场景需要自定义要移除的样本个数,即作为测试集样本的个数。需要注意的是:与留一法和KFold法不同的是,当参数p>1时,测试集可能会重叠。

在如下例子中,仍延用上文中包含四个样本的例子,将参数p设置为2对数据集进行拆分,在四个样本的例子中,可以有6种数据拆分的方法。代码如下:

>>> from sklearn.model_selection import LeavePOut ​ >>> X = np.ones(4) >>> lpo = LeavePOut(p=2) >>> for train, test in lpo.split(X): ...     print("%s %s" % (train, test)) [2 3] [0 1] [1 3] [0 2] [1 2] [0 3] [0 3] [1 2] [0 2] [1 3] [0 1] [2 3]

最后,想要分享的交叉验证方法是随机排列交叉验证 a.k.a. Shuffle & Split(Random permutations cross-平淡的仙人掌 & Split)。如下图所示,其底层逻辑为:在用户指定数量的基础上,利用ShuffleSplit迭代器生成独立的训练集/测试集划分。其步骤是先打乱样本,再将样本分为不同的训练集和测试集的组合。由于该中方法的随机性较强,因此可以设置随机数种子保证每次数据拆分的结果相同,以得到相同的交叉验证结果,该参数为random_state。

该例子是用np.arange(10)生成从0-9的10个数,n_splits参数限制数据集划分的组数,test_size参数限制用于交叉验证的测试集大小,其代码示例如下:

>>> from sklearn.model_selection import ShuffleSplit >>> X = np.arange(10) >>> ss = ShuffleSplit(n_splits=5, test_size=0.25, random_state=0) >>> for train_index, test_index in ss.split(X): ...     print("%s %s" % (train_index, test_index)) [9 1 6 7 3 0 5] [2 8 4] [2 9 8 0 6 7 4] [3 5 1] [4 5 1 0 6 9 7] [2 3 8] [2 7 5 8 0 3 4] [6 1 9] [4 1 0 6 8 9 3] [5 2 7]

本部分新的主要分享了最基本的交叉验证的调用,和五个不同的交叉验证方法,分别为K-折叠(K-Fold),重复的K-折叠(Repeated K-Fold),留一法(Leave One Out),留P法(Leave P Out),随机排列交叉验证a.k.a. Shuffle & Split(Random permutations cross-平淡的仙人掌 & Split),从而,更加细化的了解交叉验证方法。

不同的交叉验证方法针对的场景不同,因次,需要根据不同的实际情况,选择不同的方法对数据进行交叉验证,以提高模型的泛化能力和避免过拟合情况的出现。在后面的内容中,将继续分享交叉验证部分的学习心得。

(1)获取更多优质内容及精彩资讯,可前往:https://www.cda.cn/?seo

(2)了解更多数据领域的优质课程:

UCloud获聘网络安全卓越验证示范中心合作伙伴laravel是否内置了vueC语言进度条的实现原理是什么
t统计量多少是显著(f统计量和t统计量关系) 回归结果调整后的r方为负数(spss调整后的r方什么意思)
相关内容