如何在拆分数据集后反归一化StandardScaler处理的目标值与预测值?
解决目标值反归一化的问题
这个问题很典型——当初把包含特征和目标的整个数据集一起喂给StandardScaler时,确实会给后续目标值的反归一化带来麻烦,不过咱们有明确的解决办法,分两种情况来说:
针对当前已有的代码场景
你现在的核心问题是:scaler是基于**整个训练集(包含特征X和目标y)**拟合的,它的mean_和scale_属性存储的是所有列(包括特征列和目标列)的均值和标准差。直接用scaler.inverse_transform(y_test)会报错,因为y_test的列数和拟合时的总列数不匹配。
解决思路是:提取目标列对应的缩放参数,手动做反归一化(因为StandardScaler的变换是线性的,很容易逆推)。
具体代码实现
import numpy as np # 从已拟合的scaler中提取目标列对应的均值和标准差 # 你的y_train是train的最后2列,所以取scaler统计量的最后2个元素 y_mean = scaler.mean_[-2:] y_scale = scaler.scale_[-2:] # 反归一化y_test(缩放后的目标值) y_test_original = y_test * y_scale + y_mean # 反归一化模型预测的y_pred(假设y_pred是缩放后的预测结果) y_pred_original = y_pred * y_scale + y_mean
原理很简单:StandardScaler的正向变换公式是x_scaled = (x - mean) / scale,所以逆变换就是x = x_scaled * scale + mean,我们只需要用到目标列对应的mean和scale即可。
更规范的优化方案(避免未来再踩坑)
其实更合理的做法是把特征和目标的归一化分开处理,因为特征和目标的分布、缩放需求往往不同,分开处理也会让后续的反归一化更直观:
优化后的代码流程
# 第一步:先拆分原始数据集的特征和目标(还未做任何缩放) X_train_raw, y_train_raw = train_raw[:, 1:21], train_raw[:, -2:] X_test_raw, y_test_raw = test_raw[:, 1:21], test_raw[:, -2:] # 第二步:单独对特征做归一化 scaler_X = StandardScaler() X_train = scaler_X.fit_transform(X_train_raw) X_test = scaler_X.transform(X_test_raw) # 第三步:如果需要对目标值做归一化(比如回归任务中),单独用另一个StandardScaler scaler_y = StandardScaler() y_train_scaled = scaler_y.fit_transform(y_train_raw) # 第四步:训练模型(用缩放后的X和y) model.fit(X_train, y_train_scaled) # 第五步:预测并反归一化 y_pred_scaled = model.predict(X_test) y_pred_original = scaler_y.inverse_transform(y_pred_scaled) # 原始的y_test如果需要对比,直接用y_test_raw即可,或者如果之前缩放了y_test,也用scaler_y.inverse_transform
这样拆分后,特征和目标的缩放参数完全独立,后续反归一化直接调用scaler_y.inverse_transform()就可以,不需要手动计算,更不容易出错。
内容的提问来源于stack exchange,提问作者Andrea




