为什么需要交叉验证
- 训练数据一般划分为训练集和测试集,训练集用于模型构建,训练模型,确定权重;
- 测试集用于检测模型构建,只在模型检验时使用,用于评估测试集模型的准确率,检验模型的泛化能力;
- 验证集也是用于模型构建,但不参与训练,它主要用于确定网络结构,调整模型的超参数。测试集是与训练独立的数据,完全不参与训练,用于最终模型的评估。
在训练过程中,经常会出现过拟合的问题,就是模型可以很好的匹配训练数据,却不能很好在预测训练集外的数据。如果此时就使用测试数据来调整模型参数,就相当于在训练时已知部分测试数据的信息,会影响最终评估结果的准确性。通常的做法是在训练数据中分出一部分做为验证(Validation)数据,用来评估模型的训练效果。
适用情况
当数据总量较小时,其他方法无法继续提升性能,可以尝试K-Fold。但当数据量很大,就没必要更多训练数据,同时训练成本——时间,也要扩大K倍。
定义
K-Fold 交叉验证 (Cross-Validation)**它将原始数据分成K组(K-Fold),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型。**这K个模型分别在验证集中评估结果,最后的误差MSE(Mean Squared Error)加和平均就得到交叉验证误差。交叉验证有效利用了有限的数据,并且评估结果能够尽可能接近模型在测试集上的表现,可以做为模型优化的指标使用。
例如:
[0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
分为K=3组后
Fold1: [0.5, 0.2]
Fold2: [0.1, 0.3]
Fold3: [0.4, 0.6]
交叉验证的时会使用如下三个模型,分别进行训练和测试,每个测试集误差MSE加和平均就得到了交叉验证的总评分
Model1: Trained on Fold1 + Fold2, Tested on Fold3
Model2: Trained on Fold2 + Fold3, Tested on Fold1
Model3: Trained on Fold1 + Fold3, Tested on Fold2
KFold与StratifiedKFold 的区别
StratifiedKFold用法类似Kfold,但是他是分层采样,确保训练集,测试集中各类别样本的比例与原始数据集中相同。
下面这个例子6个数据对应6个标签,我们分成三折,则每次训练时,4个数据为train,2个数据为test。
StratifiedKFold能保证样本的比例与原始数据集中相同,即不会出现train_index=[0,1,2,3] train_label=[1,1,1,0]
test_index=[4,5] test_label=[0,0]****-----数据分布偏颇现象
import numpy as np
from sklearn.model_selection import KFold,StratifiedKFold
x = np.array([[1, 1], [2, 2], [3, 3], [4, 4],[5,5],[6,6]])
y=np.array([1,1,1,0,0,0])
kf = StratifiedKFold(n_splits=3,shuffle=True)
for train_index, test_index in kf.split(x,y):
print('train_index:', train_index)
print('test_index', test_index)
print("--------二折时,测试集成了训练集分割线--------")
train_index: [0 1 4 5]
test_index [2 3]
--------二折时,测试集成了训练集分割线--------
train_index: [0 2 3 5]
test_index [1 4]
--------二折时,测试集成了训练集分割线--------
train_index: [1 2 3 4]
test_index [0 5]
--------二折时,测试集成了训练集分割线--------
StratifiedKFold参数说明:
class sklearn.model_selection.StratifiedKFold(n_splits=’warn’, shuffle=False, random_state=None)
n_splits:表示几折(折叠的数量)
shuffle== True:选择是否在分割成批次之前对数据的每个分层进行打乱。
供5次2折使用,这样每次的数据是进行打乱的,否则,每次取得的数据是相同的
random_state:控制随机状态,随机数生成器使用的种子
class sklearn.model_selection.StratifiedKFold(n_splits=’warn’, shuffle=False, random_state=None)
n_splits:表示几折(折叠的数量)
shuffle== True:选择是否在分割成批次之前对数据的每个分层进行打乱。
供5次2折使用,这样每次的数据是进行打乱的,否则,每次取得的数据是相同的
random_state:控制随机状态,随机数生成器使用的种子