一般情况将K折交叉验证用于模型调优,找到使得模型泛化性能最优的超参值。
一开始我们先对数据划分为测试集和训练集,然后对训练集进行交叉验证。
1.过拟合
当训练集误差较小,而测试集误差较大时,我们即可认为模型过拟合。换句话说,如果模型评估指标的方差(variance)较大,即可认为模型过拟合。
无论监督学习还是非监督学习,均存在过拟合的问题。
最简单的判断模型是否过拟合的方法,就是通过训练精确度和测试精确度数值大小,直观的判断模型是否过拟合。例如,训练集的准确率为90%,而测试集的准确率为70%,那么我们可以认为模型过拟合。
判断模型是否过拟合还可以通过采用学习曲线(learning curve)的方法来判断,通过画学习曲线图可以直观的看出训练集和测试集的误差随着训练样本数量的变化。在学习曲线中,如果训练准确度和测试准确度两条曲线相距较远,则说明模型的方差较大(一般情况下,训练精度都会高于测试精度),模型过拟合。
而我们期望的理想状况是,训练集和测试集的两条精度曲线相距较近,并且随着训练样本数量的增加,越来越近,逐渐收敛。
2.交叉验证
2.1 k折交叉验证原理
- 第1步:将训练数据随机分为k份
- 第2步:每次选取其中k-1份作为训练集,剩余的1份作为测试集进行训练。
- 第3步:循环k次,训练出k个模型
- 第4步:计算k个模型评估结果的平均值作为模型的最终得分。
我们在运用机器学习算法模型时,要考虑两个问题:(1) 如何验证模型是否过拟合?(2) 如何避免过拟合?
接下来想针对python机器学习算法模块sklearn中交叉验证相关函数的使用加以说明。
2.2 cross_validate 与 cross_val_score
这两个函数的区别是,cross_validate允许指定多个指标进行评估,同时,它还可以显示交叉验证训练集的评估score,而cross_val_score只能显示测试集的score。当我们需要直观判断模型是否过拟合时,可以采用 cross_validate 观察训练和测试集评估score相差的大小。而cross_val_score可以用作对模型性能的综合评估。
2.3 如何利用交叉验证避免过拟合?
避免模型过拟合的方法,总结大概以下几点:
- 重新清洗数据(删除稀疏特征、对噪声数据进行处理(删除/替换))
- 重新采样(改变采样方法等)
- 增加训练数据
- 采用交叉验证训练模型
- 重新筛选特征
- 降低模型复杂度(增加正则项:L1,L2)
- dropout(神经网络中,让神经元一定的概率不工作)
本文主要探讨一下如何利用交叉验证来避免模型过拟合。
首先,我们要明确一下交叉验证的作用是什么,什么场景下会用到交叉验证。
第一个作用就是对模型的性能进行评估。当我们通过一次划分样本对模型进行训练和测试时,由于样本划分的偶然性,会导致我们对模型的评估不准确。因此,可以采用交叉验证对模型进行评估(一般采用5折或10折,sklearn默认采用的是3折),以 n 折交叉验证结果的均值,作为模型的性能评估。
第二个作用就是用来避免过拟合。例如当我们进行10折交叉验证时,训练了10次,得到了10个模型,每个模型的参数也是不同的,那么我们究竟用哪个模型作为我们最终的模型呢?答案是:一个都不用!我们要利用全量数据重新训练出一个最终模型!
如果你觉得有点迷糊的话不用急,我们一起来梳理一下。我们训练模型是为了什么?是为了确定模型中的参数,例如多元回归模型的系数、神经网络各神经元的权重等。但是,有些模型除了参数还有超参数,例如KNN和KMeans的k值,支持向量机的C值,这些超参数是需要人为设定,没有办法让模型自己学习得到,我们只能通过经验或者多次训练比较,主观设定一个我们认为相对最优的值。而交叉验证的作用,就是让我们进行多次的模型训练比较。例如,我们期望从 [ 1, 10, 100, 1000 ] 这几个值中选择一个最优值,作为支持向量机的C值。那么我们就得分别用这4个值进行10折交叉验证(该过程经历了40次模型的训练测试),把每一次交叉验证结果的均值进行比较,从而选择出一个最优值。最优值选出来了,那么模型的超参数确定了,接下来,利用全量的训练数据(不要划分训练集测试集,而是用全部的数据)进行模型训练,训练出来的模型才是我们的最终模型。在此过程中可以看出,交叉验证帮助我们确定模型的超参数。这样训练出来的模型,是经过多次综合比较得出的相对最优模型,在一定程度上可以避免过拟合的问题,这就是为什么我们会说交叉验证可以避免过拟合。