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

如何在拆分数据集后反归一化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

火山引擎 最新活动