交叉验证

在前面深度学习一章中,我们曾经提到过留出验证、K折验证和重复K折验证。不论在Keras还是PyTorch中,这些验证方法一般都需要自行实现。而这些验证方法往往关系着模型参数的调优。所以在进行参数设置时需要利用大量数据进行大量的试验。在scikit-learn中,除了使用交叉验证来调整参数外,更加有效的方法是后一节要介绍的利用Grid Search的超参数调整。

使用交叉验证往往是最简单有效的解决过拟合问题的方法。scikit-learn提供了非常便利的将样本数据进行划分的方法。

方法train_test_split(data, target, test_size, random_state)可以将一组样本按照test_size设置的比例划分为训练组和验证组,调用后会返回由四个元素组成的元组,其中元素分别是(训练数据, 验证数据, 训练标签, 验证标签)。以下是一个划分出30%验证数据的示例。

import numpy as np
from sklearn.mode_selection import train_test_split
from sklearn import datasets
from sklearn import svm


iris = datasets.load_iris()
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.3, random_state=0)
clf = svm.SVC(kernel='linear', C=1).fit(x_train, y_train)
clf.score(x_test, y_test)

在这个示例中参数C就是超参数,它用来配置模型并且需要手动设置。对于模型的调参实际上主要就是对各个超参数的调整。但是无论如何调整,在模型训练过程中,验证集数据在用过一次后就没有用了,反复使用同一组验证集数据会加重模型的过拟合。这就需要前面介绍的K折验证来解决验证集重复使用的问题。

scikit-learn中在sklearn.model_selection包中提供了KFoldRepeatedKFoldLeaveOneOut等几个工具类,其中的.split()方法可以返回一个生成器,给出按照相应的分隔方法所分离出的样本索引分组,后续可以按照这些索引来编排样本的训练和验证组合。以下给出一个使用K-Fold进行分组的示例,其他的分组方法也都大同小异,只是参数不同而已。

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(f'{train}, {test}')