多列特征下LSTM预测中inverse_transform失败问题求助
解决LSTM多列特征下StandardScaler.inverse_transform报错问题
问题场景
我正在学习机器学习,现有一段LSTM预测代码在仅使用单列特征时可正常运行,但希望训练模型使用open、close等多列特征。添加第二列特征后,inverse_transform操作执行失败,只需修改代码中的features = ["open", "close"]即可复现该问题。
问题根源
- 当使用多列特征时,
StandardScaler是基于所有特征列拟合的(比如2列),其inverse_transform方法要求输入数据的列数必须和拟合时的列数完全一致。 - 模型预测的结果是单列(比如预测的是
open列的数值),直接将这个单列数组传入inverse_transform,会因维度不匹配触发报错。
解决方案
核心思路
- 复用训练阶段的Scaler:测试阶段不能重新初始化Scaler并执行
fit,必须使用训练时拟合好的Scaler,否则缩放规则不一致,预测结果无意义。 - 构造匹配维度的输入数组:将预测结果放到对应特征列的位置,其他列用测试数据中对应位置的缩放值填充,确保输入到
inverse_transform的数组列数和拟合时一致,最后提取目标列的逆变换结果。
修改后的完整代码
import math import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler from keras.models import Sequential from keras.layers import Dense, LSTM def get_source(): data = np.random.randint(1, 101, size=(1000, 2)) data[:, 1] = data[:, 0] + np.random.randint(1, 101, size=1000) return [{'open': row[0], 'close': row[1]} for row in data] def main(): TRAINING_STEP = 10 features = ["open", "close"] # 多列特征配置 target_col_idx = 0 # 指定要预测的特征列索引(这里是open列) data = get_source() df = pd.DataFrame(data, columns=features) dataset = df.values training_data_len = math.ceil(len(dataset) * .8) # 训练阶段:拟合Scaler,后续测试阶段必须复用该实例 scaler = StandardScaler() scaled_data = scaler.fit_transform(dataset) train_data = scaled_data[0:training_data_len, :] x_train = [] y_train = [] for i in range(TRAINING_STEP, len(train_data)): x_train.append(train_data[i-TRAINING_STEP:i, :]) y_train.append(train_data[i, target_col_idx]) # 目标为指定列的缩放值 x_train, y_train = np.array(x_train), np.array(y_train) x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], x_train.shape[2])) model = Sequential() model.add(LSTM(50, return_sequences=True, input_shape=(x_train.shape[1], x_train.shape[2]))) model.add(LSTM(50, return_sequences=False)) model.add(Dense(1)) # 新增Dense层,确保输出单列结果 model.compile(optimizer='adam', loss='mean_squared_error') model.fit(x_train, y_train, batch_size=1, epochs=1) # 测试阶段:复用训练时的scaler,仅执行transform data_test = get_source() df_test = pd.DataFrame(data_test, columns=features) dataset_test = df_test.values scaled_test_data = scaler.transform(dataset_test) test_data = scaled_test_data[training_data_len - TRAINING_STEP:, :] x_test = [] t = len(test_data) x_test.append(test_data[t-TRAINING_STEP:t]) x_test = np.array(x_test) x_test = np.reshape(x_test, (x_test.shape[0], x_test.shape[1], x_test.shape[2])) predictions = model.predict(x_test) # 构造与scaler拟合时同维度的数组:列数等于特征总数 dummy_array = np.zeros((predictions.shape[0], len(features))) # 用测试数据最后一行的缩放值填充基础数组 dummy_array[0] = test_data[-1] # 将预测值替换到目标列的位置 dummy_array[0, target_col_idx] = predictions[0, 0] # 执行逆变换并提取目标列结果 result_scaled_back = scaler.inverse_transform(dummy_array) final_result = result_scaled_back[0, target_col_idx] print("预测的open值为", final_result) if __name__ == "__main__": main()
关键修改说明
- 新增
target_col_idx变量,明确要预测的特征列索引,便于后续维护。 - 模型末尾添加
Dense(1)层,确保输出结果为单列,对应目标特征的预测值。 - 测试阶段复用训练时的
scaler,仅调用transform方法,保证缩放规则与训练阶段一致。 - 构造
dummy_array填充非目标列的缩放值,仅替换目标列为预测结果,满足inverse_transform的维度要求。 - 逆变换后提取目标列的数值,得到最终的真实尺度预测结果。
内容的提问来源于stack exchange,提问作者user3677173
相关产品推荐
相关产品推荐

