m0_74420115 2024-05-01 18:09 采纳率: 71.9%
浏览 1
已结题

这是我的代码,为什么在最后一步画图的时候X轴和Y轴和实际的年份和股票价格对应不上


import pandas as pd
file_path = r"D:\\findata.csv"  
df = pd.read_csv(file_path)
def Stock_Price_LSTM_Data_Precesing(df,mem_his_days,pre_days):
    df.dropna(inplace=True)
    df.sort_index(inplace=True)
    df['label']= df['Close'].shift(-pre_days)
    from sklearn.preprocessing import StandardScaler
    scaler = StandardScaler()
    sca_X=scaler.fit_transform(df.iloc[:,:-1])   
    mem_his_days = 10
    
    from collections import deque
    deq = deque(maxlen=mem_his_days)
    
    X = []
    for i in sca_X:
        deq.append(list(i))
        if len(deq)==mem_his_days:
            X.append(list(deq))
    X_lately = X[-pre_days:]
    X = X[:-pre_days]
    y = df['label'].values[mem_his_days-1:-pre_days]
    
    
    import numpy as np
    X = np.array(X)
    y = np.array(y)
    return X,y,X_lately
 
X,y,X_lately = Stock_Price_LSTM_Data_Precesing(df,5,10)
pre_days = 10
# mem_days=[5,10,15]
# lstm_layers=[1,2,3]
# dense_layers=[1,2,3]
# units = [16,32]
mem_days=[15]
lstm_layers=[3]
dense_layers=[2]
units =[32]
from tensorflow.keras.callbacks import ModelCheckpoint
 
for the_mem_days in mem_days:
    for the_lstm_layers in lstm_layers:
        for the_dense_layers in dense_layers:
            for the_units in units:
                filepath=f"./thebestmodel/{{val_mape:.2f}}{{epoch:02d}}men{the_mem_days}lstm{the_lstm_layers}dense{the_dense_layers}unit{the_units}.keras"
                checkpoint = ModelCheckpoint(
                    filepath=filepath,
                    save_weights_only=False,
                    monitor='val_mape',
                    mode='min',
                    save_best_only=True)
                X,y,X_lately = Stock_Price_LSTM_Data_Precesing(df,the_mem_days,pre_days)
                from sklearn.model_selection import train_test_split
                X_train,X_test,y_train,y_test = train_test_split(X,y,shuffle=False,test_size=0.1)
                import tensorflow as tf
                from tensorflow.keras.models import Sequential
                from tensorflow.keras.layers import LSTM,Dense,Dropout
                model = Sequential()
                model.add(LSTM(the_units,input_shape=X.shape[1:],activation='relu',return_sequences=True))
                model.add(Dropout(0.1))
                for i in range(the_lstm_layers):
                    model.add(LSTM(the_units,activation='relu',return_sequences=True))
                    model.add(Dropout(0.1))
                
                model.add(LSTM(the_units,activation='relu'))
                model.add(Dropout(0.1))
                for i in range(the_dense_layers):
                    model.add(Dense(the_units,activation='relu'))
                    model.add(Dropout(0.1))
                
                model.add(Dense(1))
                model.compile(optimizer='adam',
                             loss='mse',
                             metrics=['mape'])
                model.fit(X_train,y_train,batch_size=32,epochs=50,validation_data=(X_test,y_test),callbacks=[checkpoint])
from tensorflow.keras.models import load_model
best_model = load_model('./thebestmodel/7.8713men15lstm3dense2unit32.keras')
best_model.summary()
best_model.evaluate(X_test,y_test)
pre = best_model.predict(X_test)
print(len(pre))
import matplotlib.pyplot as plt
df_time = df.index[- len(y_test):]
plt.plot(df_time,y_test,color='red',label='price')
plt.plot(df_time,pre,color='green',label='predict')
plt.show()

这是我的代码,为什么在最后一步画图的时候X轴和Y轴和实际的年份和股票价格对应不上

  • 写回答

6条回答 默认 最新

  • 专家-皆知 2024-05-01 18:09
    关注

    参考免费微信小程序:皆我百晓生 作答,经由专家-皆知整理回复,如问题解决,望采纳;如仍有疑问,请评论回复。

    你的代码主要问题是,你在处理数据时,并没有保留原始的日期信息与股票收盘价的直接对应关系到预测阶段。在进行LSTM模型训练时,你对数据进行了标准化处理、序列化操作,并切分了训练集和测试集,但这些步骤导致原始日期与预测值之间的关联丢失。在最后的绘图阶段,你使用了df.index[- len(y_test):]来获取日期,这实际上并没有正确反映出测试集对应的日期,因为你原始数据的索引可能并不直接对应于预测的那段时期,特别是在有缺失值或数据预处理之后。

    为了解决这个问题,你需要确保在进行模型预测和绘图之前,日期信息能够与预测的数据点正确对齐。以下是一个修改后的方案,以确保X轴是正确的日期,而Y轴是实际的股票价格和预测价格:

    1. 保留日期信息:首先,在数据预处理之前,从DataFrame中提取日期列,并将其保存在一个独立的变量中。
    2. 对齐预测结果:在预测后,确保预测值与正确的日期对齐。

    修改后的代码示例:

    import pandas as pd
    import matplotlib.pyplot as plt
    from tensorflow.keras.models import load_model
    
    # 假设CSV文件的第一列是日期,且格式正确可被pd.to_datetime解析
    file_path = r"D:\\findata.csv"  
    df = pd.read_csv(file_path)
    df['Date'] = pd.to_datetime(df.pop(df.columns[0]))  # 假设日期在第一列并移动到最后一列
    
    def extract_dates_for_prediction(df, pre_days):
        # 获取用于预测的日期范围,这里简化处理,实际情况需根据数据切分逻辑调整
        last_dates = df['Date'][-(pre_days + len(y_test)):]  # 包含最后一个用于预测的日期及其前pre_days天
        return last_dates[-len(y_test):]  # 取出与预测结果对应的部分
    
    # ... (你的数据预处理和模型训练代码保持不变)
    
    # 加载最佳模型并进行预测
    best_model = load_model('./thebestmodel/7.8713men15lstm3dense2unit32.keras')
    pre = best_model.predict(X_test)
    
    # 提取正确的日期范围
    correct_dates = extract_dates_for_prediction(df, pre_days)
    
    # 绘制图表
    plt.figure(figsize=(14, 7))
    plt.plot(correct_dates, y_test, color='red', label='Actual Price')
    plt.plot(correct_dates, pre, color='green', label='Predicted Price')
    plt.title('Stock Price Prediction')
    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.legend()
    plt.grid(True)
    plt.xticks(rotation=45)  # 旋转X轴标签以便更好地显示
    plt.show()
    

    这段代码假设你的CSV文件的第一列是日期,并且我们通过移动这一列并命名为'Date'来保留它。然后,我们在预测后根据预测数据的长度提取相应的日期范围,以确保在绘图时X轴代表的是正确的日期。请根据你的实际数据结构调整日期列的处理部分。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 5月14日
  • 已采纳回答 5月6日
  • 创建了问题 5月1日