诡异问题的背后,有可能是低级问题——过拟合原来是正则化惹的祸?

发布时间 2023-10-21 23:49:41作者: AkutaZehy

算是编程的初学者吧,简单问题经常犯蠢,写的不对多多包涵。

最近碰到的一件挺有意思的事,自己本身是干土木,目前和师兄在做一个混凝土流变和屈服的预测,用的机器学习准备发paper,快到交稿师兄自己看了下数据发现数据炸了,跟我说最好那个XGB的验证集预测结果普遍偏低,怪事。

第一反应就是数据问题,之前作了图看了拿原始数据按0.85和0.15分的训练和预测,R2一个0.99一个0.96都还行,看了下情况一到新验证数据直接歪的离谱全部超出±20%范围,而且普遍偏低,感觉是原始数据训练集测试集歪了,实际500多的数据预测出来300左右。先排查了模型问题,结果几个模型预测下来都是这个趋势,不单单是XGB一个出了问题,问题不出在模型上那十有八九是数据问题,做实验的时间不一样受气温影响偏了。

这下开始慌了,做土木的这种实验还是比较耗时间,4个点快半个小时,整个训练数据100多个点,虽然规模不大但是也够做很久的了。

进一步检查:把原始数据掏了一部分出来检查,训练集没啥问题,测试集取出来的数据预测出来普遍偏低超出20%范围,也不知道图是怎么得到的0.96的R2。之后尝试了一下把新验证集的数据和原先训练集的交换了一部分,测试集的问题明显改善了,但是验证集数据依旧飘的不行超出范围,像是过拟合。

现在数据和模型应该暂时找不出毛病了,为什么训练还是有问题?——于是将目标锁定到了数据处理流程上面。

别的确实也挑不出毛病了,突然灵光一现,上网查了一下数据预处理的数据归一化,找到了一篇使用Pipeline避免数据泄露,发现确实会有导致过拟合的问题:

简单来说就是使用标准归一化的时候,因为用到了全体数据的均值和方差,就使用到了训练的全体数据(训练集+测试集),导致了数据泄露,进而引起过拟合,正确的做法是用管道流式化封装。

顺着这个思路调了下代码,用Pipeline重封了,中间整合Pipeline+GridSearchCV出了点顺序问题导致not callable以外没别的大问题,再预测验证集除了特别极端的离群数据基本都在20%以内了,回过头来验证不调训练集的样本验证集依旧炸锅,完美解决。


说起来还是有一点很诡异的地方,就是中间为什么图上面R2那么高但是实际上预测集就已经炸了,图上反映的很正常但是数据export出来拿excel一标全是红的离群,random_state也限死了可以复现,中间也做过把test_split拉到0.2让预测准度下降一点然后又对的上了,拉回来又爆了,百思不得其解挺怪的感觉像版本bug,逻辑上说不通。

总的来说就是因为数据略偏+正则化过程数据泄露导致验证集炸了,看着诡异调了一下午其实还是低级问题,吸取教训,解决怪问题先看有没有低级错误。