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

训练集与测试集拆分前后何时做数据归一化?对建模有影响吗?

先拆分数据集,再做归一化!别搞反了,这直接关乎模型的真实泛化能力

这绝对是机器学习入门阶段最容易踩的坑之一,我当年第一次做项目也差点搞反,结果测试集准确率高得离谱,上线后直接拉胯,完全是血的教训!

为什么不能先归一化再拆分?

核心问题是数据泄露(Data Leakage)

  • 如果你先对整个数据集做归一化,计算均值、标准差这些统计量时,已经包含了测试集的数据。相当于模型在训练时间接“偷看”了测试集的信息,这会让测试集的评估结果严重失真——看起来模型效果很好,但实际面对全新数据时根本没法用。
  • 真实场景里,模型部署后处理的是完全陌生的新数据,你不可能提前拿到这些数据的统计量来做归一化。所以必须模拟这个场景:只用训练集的统计量来归一化所有数据(包括测试集和未来的新数据)。

两种做法的差异到底有多大?

  • 先归一化再拆分:测试集的准确率会虚高,甚至可能达到90%+,但上线后面对真实数据,准确率可能直接掉到50%以下。因为模型学到的不是数据的真实规律,而是包含了测试集信息的“作弊”规律。
  • 先拆分再归一化:测试集的评估结果能真实反映模型的泛化能力,这也是工业界和学术研究的标准操作,确保模型在真实场景中能稳定工作。

举个代码示例(用Scikit-learn)

这是正确的操作流程:

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier

# 第一步:先拆分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    your_features, your_labels, test_size=0.2, random_state=42
)

# 第二步:用训练集拟合归一化器,然后转换训练集和测试集
scaler = StandardScaler()
# 只在训练集上fit,避免泄露测试集信息
X_train_scaled = scaler.fit_transform(X_train)
# 用训练集的均值/标准差来转换测试集
X_test_scaled = scaler.transform(X_test)

# 第三步:用归一化后的训练集训练模型
model = RandomForestClassifier()
model.fit(X_train_scaled, y_train)

# 第四步:用测试集评估模型(这时候的结果才真实)
test_acc = model.score(X_test_scaled, y_test)
print(f"测试集准确率:{test_acc:.2f}")

记住:任何数据预处理步骤(除了完全不依赖数据统计量的操作,比如简单的特征编码),都应该只在训练集上拟合参数,再应用到测试集和新数据上,这是避免数据泄露的核心原则。

内容的提问来源于stack exchange,提问作者hemant

火山引擎 最新活动