LSTM RNN预测的反向缩放输出中的误差



我使用LSTM模型来预测股票的未来open价格。在这里,数据被预处理,模型被建立和训练,没有任何错误,我使用标准缩放器来缩小DataFrame中的值。但是,在从模型中检索预测时,当我使用scaler.reverse()方法时,它给出了以下错误。

ValueError: non-broadcastable output operand with shape (59,1) doesn't match the broadcast shape (59,4)

完整的代码是一个太大的jupyter笔记本,无法直接显示,所以我已经将其上传到git存储库中

这是因为模型预测的输出具有形状(59,1(。但你的Scaler适合(251,4(数据帧。在y值形状的数据帧上创建一个新的缩放器,或者将模型密集层输出更改为4维而不是1维。缩放器适用的数据形状,它将仅在scaler.inverse_transform期间采用该形状。

旧代码-形状(n,1(

trainY.append(df_for_training_scaled[i + n_future - 1:i + n_future, 0])

更新的代码-形状(n,4(-使用所有4个输出

trainY.append(df_for_training_scaled[i + n_future - 1:i + n_future,:])

通常情况下,您会重新缩放自变量(特征(,因为缩放的差异可能会影响模型计算,但您试图预测的因变量通常不会受到影响。通常没有理由重新缩放因变量,缩放它会使解释结果变得极其困难。

StandardScaler类的第一行文档甚至指定了同样多的内容:

通过去除均值并按比例缩放到单位方差来标准化特征

您也可以选择缩放标签,但这通常不是必需的。

因此,在您的位置上,我要做的是(假设您的原始数据帧包含3个自变量和1个目标变量(:

X = some_df.iloc[:, :3].values
y = some_df.iloc[3].values
scaler = StandardScaler()
X = scaler.fit_transform(X)
# And then goes everything as usual

现在,当你去预测值时,你只需要像以前一样用缩放器变换你的输入。

不过,更好的方法是在模型中添加一个归一化层作为预处理步骤。通过这种方式,你只需将原始数据输入到你的估计器中,它就会为你处理所有的细节。同样,在生成预测时,您不需要对数据进行归一化,模型将为您完成所有工作。你可以添加这样的内容:

from tensorflow.keras.layers.experimental.preprocessing import Normalization
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras import Model
# this is your default batch_size
BATCH_SIZE = 128
# Here's your raw (non-normalized) X data
X = some_df.iloc[:, :3].values
norm = Normalization()
norm.adapt(X)
preprocess = Sequential([
Input(shape=(BATCH_SIZE, 3)),
norm
])
# Now finally, when you build your actual model you add 
# pre-processing step in the beginning
inp = preprocess()
x = Dense(64)(input)
x = Dense(128)(x)
x = Dense(1)(x)  
model = Model(inputs=inp, outputs=x) 

在这里,预处理步骤是模型本身的一部分,所以一旦你这样做了,你就可以直接向它提供原始数据,而不需要任何额外的转换。

这就是它将要做的:

# Skipping the imports as they are the same as above + numpy
X = np.array([[1, 2, 3], [10, 20, 40], [100, 200, 400]])
norm = Normalization()
norm.adapt(X)
preprocess = Sequential([
Input(shape=(3, 3)),
norm
]) 
x_new = preprocess(X)
print(x_new)
Out: tf.Tensor(
[[-0.80538726 -0.80538726 -0.807901  ]
[-0.60404044 -0.60404044 -0.6012719 ]
[ 1.4094278   1.4094278   1.4091729 ]], shape=(3, 3), dtype=float32)

最新更新