我使用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)