You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多列特征下LSTM预测中inverse_transform失败问题求助

解决LSTM多列特征下StandardScaler.inverse_transform报错问题

问题场景

我正在学习机器学习,现有一段LSTM预测代码在仅使用单列特征时可正常运行,但希望训练模型使用open、close等多列特征。添加第二列特征后,inverse_transform操作执行失败,只需修改代码中的features = ["open", "close"]即可复现该问题。

问题根源

  • 当使用多列特征时,StandardScaler是基于所有特征列拟合的(比如2列),其inverse_transform方法要求输入数据的列数必须和拟合时的列数完全一致。
  • 模型预测的结果是单列(比如预测的是open列的数值),直接将这个单列数组传入inverse_transform,会因维度不匹配触发报错。

解决方案

核心思路

  1. 复用训练阶段的Scaler:测试阶段不能重新初始化Scaler并执行fit,必须使用训练时拟合好的Scaler,否则缩放规则不一致,预测结果无意义。
  2. 构造匹配维度的输入数组:将预测结果放到对应特征列的位置,其他列用测试数据中对应位置的缩放值填充,确保输入到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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 03:05:18