You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

训练小型回归模型时,StandardScaler应在train_test_split之前还是之后执行?

训练小型回归模型时,StandardScaler应在train_test_split之前还是之后执行?

这个问题问得特别戳中新手的痛点——我刚学特征工程的时候也纠结过:反正测试集最后才用来评估,提前一起缩放好像也没差?直到踩过一次坑才彻底明白,核心问题就是数据泄漏,我给你用大白话掰扯清楚:

先给你打个生活化的比方:把训练集当成你平时刷的练习题,测试集当成期末考试的真题。要是你提前把期末考试的真题混进练习题里,一起总结知识点的高频分布、解题套路,那你模考分数肯定很高,但这根本不是你真实的水平——因为你提前“偷看”了本该未知的考试信息,等真的遇到全新的考题,你就抓瞎了。

回到数据缩放这件事上,本质是一样的:

  • 如果你先缩放整个数据集再拆分,相当于用所有数据(包括测试集)的均值和标准差来统一缩放。这就意味着,你在训练模型之前,已经把测试集里的统计信息(比如有没有离群点、整体数据分布)提前灌输给了训练过程。
  • 而正确的做法是先拆分数据集,只用训练集的均值和标准差拟合scaler,再用同一个scaler去转换测试集。这就模拟了真实场景:你训练模型时完全不知道未来要面对的新数据是什么样的,只能基于已有的训练数据制定缩放规则,这样模型学到的规律才是通用的,泛化能力才靠谱。

给你举个具体的数值例子,一眼就能看出区别:
假设训练集是[1,2,3,4,5],测试集是[100]

  • 先缩放再拆分:整个数据集的均值是19.17,标准差约37.5。缩放后训练集变成[-0.48, -0.46, -0.43, -0.40, -0.38],测试集是≈2.16
  • 先拆分再缩放:训练集的均值是3,标准差约1.58。缩放后训练集是[-1.26, -0.63, 0, 0.63, 1.26],测试集用训练集的规则计算是≈61.39

你看,第一种情况里,测试集的100被硬生生拉低到2.16,因为整个数据集的均值被这个离群点拉高了。但真实场景下,当你遇到100这种全新数据时,你根本不知道它的存在,所以必须用训练集的统计量来缩放,这样模型才会对未知数据做出正确的判断。

最后再明确一下代码的对错:

错误做法(会导致数据泄漏):

X_scaled = StandardScaler().fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y)

正确做法(保证泛化能力):

X_train, X_test, y_train, y_test = train_test_split(X, y)
scaler = StandardScaler().fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

总之,记住一句话:所有和数据统计相关的预处理操作(缩放、归一化、甚至特征选择),都必须在拆分数据集之后,只基于训练集来做,绝对不能碰测试集的任何信息——这是保证模型泛化能力的基本准则之一!

火山引擎 最新活动