在做机器学习项目的时候,一开始我们会将数据集分为训练集和测试集,要记住测试集只能用一次,只能用来评估最终最好的模型。如果你反复去使用测试集,反复测试后从里面挑最好的,你就是在耍流氓。
建模过程中肯定有模型调整,必然涉及到模型挑选的问题,当过程中我需要做很多个模型时,问题来了,如果我不去评估我怎么知道哪一个模型是最好的?
Typically we can’t decide on which final model to use with the test set before first assessing model performance. There is a gap between our need to measure performance reliably and the data splits (training and testing) we have available.
想想在利用测试集之前,怎么也得加上一个评估过程,帮助我们确定,到底哪个模型才是最好的,才是值得最终被用到测试集上的。
这个过程就涉及到重复抽样了resampling!
Resampling methods, such as cross-validation and the bootstrap, are empirical simulation systems. They create a series of data sets similar to the training/testing split
首先理解过拟合
写重复抽样前我们先回顾过拟合的概念,数据划分后,我们会在训练集中训练好模型,怎么评估这个模型?很自然的我可以想到,就将模型用在训练集中,将真实值和预测值对比不就好了?有文章确实是这么做的,但是现在有很多的黑箱模型几乎可以做到完全复制出训练集,做到训练集预测无偏差,这个时候这个黑箱模型就一定好吗?
bias is the difference between the true pattern or relationships in data and the types of patterns that the model can emulate. Many black-box machine learning models have low bias, meaning they can reproduce complex relationships. Other models (such as linear/logistic regression, discriminant analysis, and others) are not as adaptable and are considered high bias models
不一定的。举个实际例子吧。
对于同一个数据集,我做了两个模型,一个线性回归lm_fit,另外一个随机森林rf_fit,在训练集中他们的表现如下:
[图片上传失败...(image-8cf873-1676026248127)]
看上图,明显从rmse和rsq这两个指标看,都提示随机森林模型在训练集中表现更好。按照上面的逻辑怎么说我都应该选择随机森林模型才对。
于是我真的认为随机森林模型优于线性回归模型,然后我将随机森林模型用在了测试集中去最终评估模型表现,得到结果如下。
[图片上传失败...(image-c86e02-1676026248127)]
结果显示rmse相对于训练集从0.03一下跑到了0.07,r方也有明显下降。
到这,按照原来的思路,其实我的工作已经完了,我就单纯地认为确实我选随机森林是对的,模型的预测能力确实也只能这样了。
不妨在多做一步。
虽然刚刚说线性模型不如随机森林模型,但是我又好奇这个模型在陌生的测试集中表现究竟怎样?于是我又多做一步,把我们抛弃的线性模型用在测试集中看看表现:
[图片上传失败...(image-829431-1676026248127)]
可以看到线性模型在训练集和测试集中的表现一致性非常强,在测试集中的表现其实和随机森林差不太多。
上面的例子给大家的启发就是,模型训练的好(在训练集中表现好)不意味着其在测试集中也好。模型在训练集中表现好,而测试集中就不行了,就是模型过拟合的表现,模型训练时避免过拟合的,保证表现一致性的方法就是重复抽样训练。
再来看重复抽样
[图片上传失败...(image-3c215f-1676026248127)]
重复抽样训练的逻辑在于:
我们会将原来的训练集进行反复抽样形成很多和抽样样本。
对于每一个抽样样本,又会分为analysis样本集和assessment样本集,我们会在analysis样本中训练模型,然后再assessment样本中评估模型,比如我现在重复抽样20,意味着我要做20个模型,每个模型评估一次,就会评估20次,整体模型好不好,是这20次的均值说了算的。这样就大大增加了模型的推广稳健性,避免过拟合。
重复抽样的常见方法包括交叉验证和自助抽样验证,其做法代码如下:
folds <- vfold_cv(cell_train, v = 10) #交叉验证设置代码
交叉验证
交叉验证属于resampling的一种方法,一个简单的例子如下,比如我训练集30个样本,3折交叉验证的图示:
[图片上传失败...(image-38f1d1-1676026248127)]
30个数据别均分为3份,每一份都当做一次assessment数据集,相应地剩下的2个数据集为analysis数据集用来训练模型
[图片上传失败...(image-f29845-1676026248127)]
数据随机切为3份之后,每一份都会用来评估模型表现。
仔细想一下,上面的交叉验证其实还有随机性,就是你一开始就将数据切成了3份,如果只切一次其实也是有随机性的,所以我们实际使用交叉验证的时候要考虑这一点,我们会重复很多次,比如10折交叉验证再重复10次。这个就是反复交叉验证的思想,叫做Repeated cross-validation。这也是为什么交叉验证函数都会有一个repeats参数的原因。
自助法Bootstrapping
Bootstrap本身是一种确定统计量的样本分布的方法,上篇文章刚刚提到过哈
Bootstrap resampling was originally invented as a method for approximating the sampling distribution of statistics whose theoretical properties are intractable
在机器学习中,我们对训练集进行自助抽样就是在训练集中有放回地随机抽一个和训练集一样大的样本。同样的,我们还是看一个30个样本的训练集的自助抽样例子:
[图片上传失败...(image-483c92-1676026248126)]
可以看到,我们对原始30个训练集样本进行了3次自助抽样,每次抽出来的30个样本都是有重复的,比如在第一次的时候8这个样本就重复了,而2这个样本没抽到。这样我们就让自助样本做训练,没抽到的样本做assessment set。没抽到的样本也叫做out-of-bag sample。论文中的out-of-bag验证就是指的这个意思。
滚动抽样
对于时间依赖的数据,比如面板数据,我们再考虑抽样的时候一定要将时间的先后顺序考虑进去,这时候我们用到的方法叫做Rolling forecast origin resampling:下面是这个方法的图示:
[图片上传失败...(image-7d98ae-1676026248126)]
可以看到我们的抽样是按时间前进的,保证每次我们都是用老数据训练,新数据评估。上面的示例是每次丢掉一个样本,前进一个样本,实际使用的时候我们可以不丢掉,一次前进多个。
理解随机抽样的地位
上面又再次回忆了不同的重复抽样的方法,始终需要记得的是,重复抽样是服务于发现最优模型的,服务于减少欠拟合和过拟合的(很多同学做预测模型其实是略过这一步的,只能说不完美,不能说错),使用重复抽样我们会在每一个样本集中训练模型并对其进行评估,比如我某种抽样方法抽出20个样本集那么我就训练并评估模型20次,最终20个模型的平均表现作为该模型的表现。通过这么样的方式尽最大努力使得用到测试集中进行测试的模型是最优的,保证测试集只用一次并且这一次确实反映了最优模型的表现。
This sequence repeats for every resample. If there are B resamples, there are B replicates of each of the performance metrics. The final resampling estimate is the average of these B statistics. If B = 1, as with a validation set, the individual statistics represent overall performance.
这个方法怎么用呢?tidymodels给了我们相应的使用界面:
model_spec %>% fit_resamples(formula, resamples, ...)
model_spec %>% fit_resamples(recipe, resamples, ...)
workflow %>% fit_resamples( resamples, ...)
如果你看不懂上面的界面,之后我会专门写tidymodels框架给大家,请持续关注。