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

Keras LSTM股价预测报错:无法将数组重塑为指定形状

Keras LSTM德黑兰证券交易所股价预测:数组重塑错误解决

问题描述

执行代码中X = np.reshape(X, (1, X.shape[0], X.shape[1]))语句时触发ValueError,提示无法将大小为9200的数组重塑为(1,460,10)。

完整代码

import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout
import matplotlib.pyplot as plt
import finpy_tse as fpy

# 定义股票代码和时间区间
stock_symbol = 'وغدیر'
start_date = '1400-01-01'
end_date = '1402-01-01'

# 从德黑兰证券交易所获取股价数据
stock_data = fpy.Get_Price_History(stock_symbol, start_date, end_date)

# 打印获取的数据
print("从站点获取的数据:")
print(stock_data)

data = pd.DataFrame(stock_data)

# 重复获取数据(可删除此冗余代码)
stock_data = fpy.Get_Price_History(stock_symbol, start_date, end_date)
data = pd.DataFrame(stock_data)

# 打印列名检查数据结构
print(data.columns)

# 特征工程:创建额外特征
if 'Close' in data.columns and 'Volume' in data.columns:
    data['DailyReturn'] = data['Close'].pct_change()
    data['VolumeChange'] = data['Volume'].pct_change()

    # 删除缺失值
    data = data.dropna()

    # 检查删除后数据集是否为空
    if data.empty:
        print("删除缺失值后数据集为空,无法继续。")
    else:
        # 选择训练用特征
        features = ['DailyReturn', 'VolumeChange']
        dataset = data[features].values

        # 检查特征工程后数据集是否为空
        if dataset.shape[0] == 0:
            print("特征工程后数据集为空,无法继续。")
        else:
            # 数据归一化
            scaler = MinMaxScaler(feature_range=(0, 1))
            dataset_scaled = scaler.fit_transform(dataset)

            # 创建时间序列数据集
            def create_dataset(dataset, time_steps=1):
                X, y = [], []
                for i in range(len(dataset) - time_steps):
                    a = dataset[i:(i + time_steps), :]
                    X.append(a)
                    y.append(dataset[i + time_steps, 0])  # 预测DailyReturn
                return np.array(X), np.array(y)

            # 定义时间步长
            time_steps = 10

            # 生成数据集
            X, y = create_dataset(dataset_scaled, time_steps)

            # 调试打印形状和大小
            print("重塑前 - X形状:", X.shape, "X大小:", X.size)

            # 错误的重塑语句
            X = np.reshape(X, (1, X.shape[0], X.shape[1]))

            # 构建LSTM模型
            model = Sequential()
            model.add(LSTM(units=100, return_sequences=True, input_shape=(X.shape[1], X.shape[2])))
            model.add(Dropout(0.2))
            model.add(LSTM(units=100, return_sequences=True))
            model.add(Dropout(0.2))
            model.add(LSTM(units=50, return_sequences=False))
            model.add(Dropout(0.2))
            model.add(Dense(units=1))
            model.compile(optimizer='adam', loss='mean_squared_error')

            # 训练模型
            model.fit(X, y, epochs=10, batch_size=32, validation_split=0.1)

            # 测试模型
            test_data = dataset_scaled[-time_steps:]
            test_data = np.reshape(test_data, (1, time_steps, len(features)))
            predicted_price = model.predict(test_data)

            # 错误的逆变换逻辑
            predicted_price = scaler.inverse_transform(np.reshape(predicted_price, (1, time_steps, len(features))))
            print("调试形状:")
            print("test_data形状:", test_data.shape)
            print("predicted_price形状:", predicted_price.shape)

            # 重复逆变换
            predicted_price = scaler.inverse_transform(np.reshape(predicted_price, (time_steps, len(features))))

            # 提取预测结果
            predicted_price = predicted_price[0, :, 0]

            # 可视化结果
            plt.plot(data['Close'].values, label='Actual Stock Price')
            plt.plot(np.arange(len(data['Close']), len(data['Close']) + time_steps), predicted_price, marker='o', color='red',
                     label='Predicted Stock Price')
            plt.xlabel('Days')
            plt.ylabel('Stock Price')
            plt.title(f'Stock Price Prediction for {stock_symbol} using LSTM')
            plt.legend()
            plt.show()
else:
    print("数据中不存在'Close'或'Volume'列。")
    print("请检查股价数据或提供包含这些列的数据集。")

报错信息

Traceback (most recent call last): File "...:/Users/...../PycharmProjects/untitled1/.....py", line 76, in
X = np.reshape(X, (1, X.shape[0], X.shape[1])) File "<array_function internals>", line 180, in reshape File "....:\Users.....\PycharmProjects\untitled1\venv\lib\site-packages\numpy\core\fromnumeric.py", line 298, in reshape
return _wrapfunc(a, 'reshape', newshape, order=order) File "....:\Users....\PycharmProjects\untitled1\venv\lib\site-packages\numpy\core\fromnumeric.py", line 57, in _wrapfunc
return bound(*args, **kwds) ValueError: cannot reshape array of size 9200 into shape (1,460,10)

问题原因

create_dataset函数生成的X已经是LSTM要求的三维格式[样本数, 时间步长, 特征数]。从报错数据计算:460102=9200,说明X的实际形状是(460,10,2)(460个样本,每个样本包含10个时间步的2个特征)。但你试图将其重塑为(1,460,10),总元素数仅为4600,和原数组大小不匹配,导致报错。

解决步骤

  1. 删除错误的重塑语句:直接删掉X = np.reshape(X, (1, X.shape[0], X.shape[1])),因为create_dataset已经输出了正确的三维结构。
  2. 修正预测部分的逆变换逻辑:模型输出的是单个预测值(DailyReturn),而scaler是基于2个特征训练的,需要将预测值补全为对应特征数的数组后再逆变换。
  3. 调整可视化代码:模型每次仅预测一个时间步的数值,无需生成多个预测点。

修正后的关键代码片段

# 生成时间序列数据集后,无需额外重塑
X, y = create_dataset(dataset_scaled, time_steps)
print("X的正确形状:", X.shape)  # 输出应为 (样本数, 10, 2)

# 构建模型(input_shape参数保持不变,与X的结构匹配)
model = Sequential()
model.add(LSTM(units=100, return_sequences=True, input_shape=(X.shape[1], X.shape[2])))
model.add(Dropout(0.2))
model.add(LSTM(units=100, return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(units=50, return_sequences=False))
model.add(Dropout(0.2))
model.add(Dense(units=1))
model.compile(optimizer='adam', loss='mean_squared_error')

# 训练模型
model.fit(X, y, epochs=10, batch_size=32, validation_split=0.1)

# 预测部分修正
test_data = dataset_scaled[-time_steps:]
test_data = np.reshape(test_data, (1, time_steps, len(features)))
predicted_price = model.predict(test_data)

# 逆变换:补全特征维度,匹配scaler的输入要求
predicted_full = np.zeros((1, len(features)))
predicted_full[0, 0] = predicted_price[0, 0]  # 将预测的DailyReturn放入对应列
predicted_price = scaler.inverse_transform(predicted_full)[0, 0]

# 可视化修正
plt.plot(data['Close'].values, label='实际股价')
plt.plot(len(data['Close']), predicted_price, marker='o', color='red', label='预测股价')
plt.xlabel('天数')
plt.ylabel('股价')
plt.title(f'{stock_symbol} 股价LSTM预测')
plt.legend()
plt.show()

内容的提问来源于stack exchange,提问作者sobhan soleimani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:50:54