m0_74420115 2024-04-28 20:19 采纳率: 71.9%
浏览 5
已结题

python用lstm预测股票

代码运行报错了,文件名希望保留每次运行时的{val_mape:.2f}_{epoch:02d},{the_lstm_layers},{the_lstm_layers},{the_dense_layers},{the_units}的值,为什么会出现这个错误

import pandas_datareader.data as web
import datetime
start = datetime.datetime(2000,1,1)
end = datetime.datetime(2024,1,1)
df = web.DataReader('GOOGL', 'stooq',start,end)
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)
print(len(X))
print(len(y))
print(len(X_lately))
pre_days = 10
mem_days=[5,10,15]
lstm_layers=[1,2,3]
dense_layers=[1,2,3]
units = [16,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="./models4/{val_mape:.2f}_{epoch:02d}_men_{the_lstm_layers}_lstm_{the_lstm_layers}_dense_{the_dense_layers}_unit_{the_units}.weights.h5"
                checkpoint = ModelCheckpoint(
                    filepath=filepath,
                    save_weights_only=True,
                    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])

错误原因

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[21], line 41
     37 model.add(Dense(1))
     38 model.compile(optimizer='adam',
     39              loss='mse',
     40              metrics=['mape'])
---> 41 model.fit(X_train,y_train,batch_size=32,epochs=50,validation_data=(X_test,y_test),callbacks=[checkpoint])

File D:\anaconda\Lib\site-packages\keras\src\utils\traceback_utils.py:122, in filter_traceback.<locals>.error_handler(*args, **kwargs)
    119     filtered_tb = _process_traceback_frames(e.__traceback__)
    120     # To get the full stack trace, call:
    121     # `keras.config.disable_traceback_filtering()`
--> 122     raise e.with_traceback(filtered_tb) from None
    123 finally:
    124     del filtered_tb

File D:\anaconda\Lib\site-packages\keras\src\callbacks\model_checkpoint.py:323, in ModelCheckpoint._get_file_path(self, epoch, batch, logs)
    319         file_path = self.filepath.format(
    320             epoch=epoch + 1, batch=batch + 1, **logs
    321         )
    322 except KeyError as e:
--> 323     raise KeyError(
    324         f'Failed to format this callback filepath: "{self.filepath}". '
    325         f"Reason: {e}"
    326     )
    327 return file_path

KeyError: 'Failed to format this callback filepath: "./models4/{val_mape:.2f}_{epoch:02d}_men_{the_lstm_layers}_lstm_{the_lstm_layers}_dense_{the_dense_layers}_unit_{the_units}.weights.h5". Reason: \'the_lstm_layers\''

  • 写回答

5条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-04-28 20:19
    关注

    引自免费微信小程序:皆我百晓生

    根据提供的错误信息,KeyError: 'the_lstm_layers' 表明在尝试格式化文件路径字符串时,找不到名为 'the_lstm_layers' 的键。这可能是因为你在定义模型检查点(ModelCheckpoint)对象时,没有正确地将变量传递给文件路径模板。

    为了修复这个问题,你需要确保在创建ModelCheckpoint对象时,已经为所有占位符提供了值。在循环中,你需要先将这些变量的当前值存储到一个字典中,然后使用这个字典来格式化文件路径。

    这里是一个修改后的版本,包含了必要的更改:

    import os
    import pandas_datareader.data as web
    import datetime
    import numpy as np
    import tensorflow as tf
    from tensorflow.keras.callbacks import ModelCheckpoint
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import LSTM, Dense, Dropout
    from sklearn.preprocessing import StandardScaler
    from sklearn.model_selection import train_test_split
    
    # ... (保持其他函数不变)
    
    # 新增一个字典来保存参数值
    params_dict = {}
    
    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:
    
                    # 将当前的参数值添加到字典中
                    params_dict["mem_days"] = the_mem_days
                    params_dict["the_lstm_layers"] = the_lstm_layers
                    params_dict["the_dense_layers"] = the_dense_layers
                    params_dict["the_units"] = the_units
    
                    # 使用字典中的参数值格式化文件路径
                    filepath = "./models4/val_mape_{val_mape:.2f}_epoch_{epoch:02d}_mem_{mem_days}_lstm_{the_lstm_layers}_dense_{the_dense_layers}_unit_{the_units}.h5".format(**params_dict)
    
                    # ... (其余部分保持不变)
    
    # 在fit方法中使用相同的字典
    model.fit(X_train, y_train, batch_size=32, epochs=50, validation_data=(X_test, y_test), callbacks=[checkpoint])
    
    # 在训练完成后,记得清理字典以便于下次循环
    params_dict.clear()
    

    在这个修改版中,我首先创建了一个空字典params_dict,然后在每次循环开始时将当前的参数值添加到字典中。接着,我在格式化文件路径时使用了这个字典。这样,在调用format()方法时,它会从字典中查找对应的键值对进行替换。

    注意:由于在实际运行中,val_mape 是一个指标,通常在训练过程中是未知的,因此在循环内设置文件路径可能会有问题。为了得到准确的验证MAPE值,你应该在训练完成之后,基于整个验证集计算MAPE,并使用这个值重命名保存的模型文件。一种可能的方法是在训练结束后保存模型,并在外部使用评估数据计算MAPE,然后手动重命名模型文件。

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

报告相同问题?

问题事件

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