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

调用scaler.inverse_transform()时出现维度不匹配ValueError问题求助

解决LSTM股票预测中scaler.inverse_transform的维度错误问题

问题现象

基于LSTM的股票价格预测代码运行正常,但执行predicted_stock_price = scaler.inverse_transform(predicted_stock_price)时触发错误:

ValueError: Found array with dim 3. Estimator expected <= 2.

完整错误栈:

ValueError                                Traceback (most recent call last)
<ipython-input-224-dacdc53f9aa9> in <module>
      1 #PREDIZIONE
      2 predicted_stock_price = model1.predict(X_test)
----> 3 predicted_stock_price = scaler.inverse_transform(predicted_stock_price)
      4 
      5 #nsamples, nx, ny = predicted_stock_price.shape

1 frames
/usr/local/lib/python3.7/dist-packages/sklearn/preprocessing/_data.py in inverse_transform(self, X)
    524 
    525         X = check_array(
--> 526             X, copy=self.copy, dtype=FLOAT_DTYPES, force_all_finite="allow-nan"
    527         )
    528 

/usr/local/lib/python3.7/dist-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator)
    794             raise ValueError(
    795                 "Found array with dim %d. %s expected <= 2."
--> 796                 % (array.ndim, estimator_name)
    797             )
    798 

ValueError: Found array with dim 3. Estimator expected <= 2.

错误原因

你的LSTM模型中所有LSTM层都设置了return_sequences=True,这个参数会让LSTM层返回每个时间步的输出,导致最终模型的预测结果是3维数组(形状为(样本数, 时间步长, 1))。而MinMaxScaler是基于2维数据((样本数, 特征数))拟合的,inverse_transform方法只接受2维及以下的数组,因此触发维度不匹配错误。

此外,股票价格预测任务中,我们只需要每个输入序列对应一个预测值,不需要每个时间步都输出结果,所以最后一个LSTM层设置return_sequences=True是不合理的。

解决方案

方案1:修改模型结构(推荐)

将最后一个LSTM层的return_sequences改为False,这样最后一个LSTM层会返回每个样本的最终输出(2维数组),后续的Dense层输出也会是2维,完全匹配scaler.inverse_transform的要求。

修改后的模型结构代码:

#LSTM
model1 = Sequential()

model1.add(LSTM(70, activation = "relu", return_sequences = True, input_shape = (X_allenamento.shape[1], 1)))
model1.add(Dropout(0.2))

model1.add(LSTM(90, activation = "relu", return_sequences = True))
model1.add(Dropout(0.3))

model1.add(LSTM(120, activation = "relu", return_sequences = True))
model1.add(Dropout(0.4))

# 修改最后一个LSTM层的return_sequences为False
model1.add(LSTM(150, activation = "relu", return_sequences = False))
model1.add(Dropout(0.6))

model1.add(Dense(1))

方案2:临时降维(不推荐,仅用于无法修改模型的场景)

如果必须保留原模型结构,可以在逆转换前将3维的预测结果降为2维。取每个样本最后一个时间步的输出即可:

predicted_stock_price = model1.predict(X_test)
# 取每个样本最后一个时间步的预测值,将形状从(样本数,60,1)转为(样本数,1)
predicted_stock_price = predicted_stock_price[:, -1, :]
predicted_stock_price = scaler.inverse_transform(predicted_stock_price)

完整修正代码

import pandas_datareader as web
from datetime import datetime
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
import numpy as np
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, LSTM, Dropout

ticker = "AAPL"

while True:
    data_inizio = str(input("data d'inizi dell'analisi (inserisci giorno mese ed anno): " ))
    try:
        start1 = datetime.strptime(data_inizio, '%d %m %Y')
        break
    except ValueError:
        print('il formato inserito non è corretto scrivere la data inserendo giorno mese ed anno separati dallo spazio es. 20 01 2021')

while True:
    data_fine = str(input("data di fine analisi (inserisci giorno mese ed anno): " ))
    try:
        end1 = datetime.strptime(data_f_fine, '%d %m %Y')
        break
    except ValueError:
        print('il formato inserito non è corretto scrivere la data inserendo giorno mese ed anno separati dallo spazio es. 20 01 2021')

inizio_analisi = start1
fine_analisi = end1


dati_finanziari_ticker = web.DataReader(ticker, data_source="yahoo", start=inizio_analisi, end=fine_analisi)
periodo_analisi = dati_finanziari_ticker.shape[0]
periodo_allenamento_programma = round(periodo_analisi*0.8)
periodo_test_programma = periodo_analisi
dati_finanziari_ticker_scalati = dati_finanziari_ticker.iloc[:, 3:4].values


scaler = MinMaxScaler(feature_range=(0,1))
dati_allenamento_scalati = scaler.fit_transform(dati_finanziari_ticker_scalati)


X_allenamento = [] 
y_allenamento = []

for i in range(60, periodo_allenamento_programma):
  X_allenamento.append(dati_finanziari_ticker_scalati[i-60:i, 0])
  y_allenamento.append(dati_finanziari_ticker_scalati[i,0])


X_allenamento, y_allenamento = np.array(X_allenamento), np.array(y_allenamento)
X_allenamento = np.reshape(X_allenamento, (X_allenamento.shape[0], X_allenamento.shape[1], 1))

#LSTM
model1 = Sequential()

model1.add(LSTM(70, activation = "relu", return_sequences = True, input_shape = (X_allenamento.shape[1], 1)))
model1.add(Dropout(0.2))

model1.add(LSTM(90, activation = "relu", return_sequences = True))
model1.add(Dropout(0.3))

model1.add(LSTM(120, activation = "relu", return_sequences = True))
model1.add(Dropout(0.4))

# 修改此处的return_sequences为False
model1.add(LSTM(150, activation = "relu", return_sequences = False))
model1.add(Dropout(0.6))

model1.add(Dense(1))

model1.summary()  # 修正:添加括号以正确打印模型摘要

model1.compile(optimizer = "adam", loss = "mean_squared_error")

model1.fit(X_allenamento, y_allenamento, epochs=10, batch_size=28)

#CREAZIONE DEGLI ARRAY PER IL TEST
X_test = [] 
y_test = []

for i in range(periodo_allenamento_programma, periodo_test_programma):
  X_test.append(dati_finanziari_ticker_scalati[i-60:i, 0])
  y_test.append(dati_finanziari_ticker_scalati[i,0])


X_test, y_test = np.array(X_test), np.array(y_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))


predicted_stock_price = model1.predict(X_test)
predicted_stock_price = scaler.inverse_transform(predicted_stock_price)

内容的提问来源于stack exchange,提问作者Francesco Stocchi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 00:15:49