引言
股票价格预测是一个复杂且具有挑战性的任务,传统的预测方法往往难以捕捉股票价格中的复杂关系。LSTM(长短期记忆网络)作为一种特殊的递归神经网络,因其能够处理时间序列中的长依赖问题,成为股票价格预测的有力工具。本文将详细介绍一个基于LSTM模型的股票价格预测项目,并结合实际代码进行分析和优化。
项目概述
本项目包含以下几个Python文件:
-
evaluate.py
: 用于评估训练好的LSTM模型,生成预测结果并进行可视化。 -
LSTMModel.py
: 定义LSTM模型的架构。 -
parser_my.py
: 处理命令行参数,设置模型的超参数。 -
train.py
: 训练LSTM模型,并在训练过程中保存模型。 -
dataset.py
: 负责数据加载和预处理。 -
文件地址https://download.csdn.net/download/weixin_74773078/90161666
这些文件共同构成了一个完整的LSTM模型实现,涵盖了从数据处理到模型训练和评估的全过程。
代码详解
1. 数据预处理 (dataset.py
)
在dataset.py
中,数据预处理是整个项目的第一步。代码从CSV文件中读取股票数据,并进行以下操作:
-
数据清洗:删除不必要的列,如
ts_code
、id
、pre_close
和trade_date
。 -
数据归一化:使用Min-Max标准化方法对数据进行归一化处理,确保所有特征值都在0到1之间。
-
构造时间序列:根据指定的
sequence_length
,将数据划分为多个时间序列,用于输入LSTM模型。
# 数据归一化
df = stock_data.apply(lambda x: (x - min(x)) / (max(x) - min(x)))
2. 模型定义 (LSTMModel.py
)
LSTMModel.py
文件定义了LSTM模型的架构。模型由一个LSTM层和一个全连接层组成,LSTM层负责捕捉时间序列中的依赖关系,全连接层则将LSTM的输出映射到最终的预测值。
class lstm(nn.Module):
def __init__(self, input_size=8, hidden_size=32, num_layers=1, output_size=1, dropout=0, batch_first=True):
super(lstm, self).__init__()
self.rnn = nn.LSTM(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers, batch_first=batch_first, dropout=dropout)
self.linear = nn.Linear(hidden_size, output_size)
def forward(self, x):
out, (hidden, cell) = self.rnn(x)
out = self.linear(hidden[-1]) # 使用最后一个时间步的输出
return out
改进点:在原始代码中,forward
方法返回的是hidden
的输出,这可能不适用于回归任务。改进后,我们使用LSTM最后一个时间步的输出进行预测。
3. 模型训练 (train.py
)
train.py
文件包含了LSTM模型的训练过程。训练步骤如下:
-
初始化模型:加载LSTM模型,并将其移动到指定的设备(CPU或GPU)。
-
定义损失函数和优化器:使用均方误差(MSE)作为损失函数,Adam作为优化器。
-
训练循环:在每个epoch中,遍历训练数据,计算损失并更新模型参数。
-
保存模型:每10个epoch保存一次模型,并在训练结束后保存最终模型。
for i in range(args.epochs):
total_loss = 0
for idx, (data, label) in enumerate(train_loader):
if args.useGPU:
data1 = data.squeeze(1).cuda()
pred = model(Variable(data1).cuda())
label = label.unsqueeze(1).cuda()
else:
data1 = data.squeeze(1)
pred = model(Variable(data1))
label = label.unsqueeze(1)
loss = criterion(pred, label)
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f'Epoch {i + 1}, Loss: {total_loss}')
4. 模型评估 (evaluate.py
)
evaluate.py
文件用于评估训练好的模型。评估步骤如下:
-
加载模型:从保存的模型文件中加载训练好的LSTM模型。
-
生成预测结果:使用测试数据生成预测值,并与真实值进行对比。
-
计算误差:计算预测值与真实值之间的误差率,并进行可视化。
for i in range(len(preds)):
pred_value = preds[i][0] * (close_max - close_min) + close_min # 还原预测值
label_value = labels[i] * (close_max - close_min) + close_min # 还原真实值
error = abs(pred_value - label_value) / label_value * 100 # 计算误差率
errors.append(error)
print('预测值是%.2f, 真实值是%.2f, 误差率是%.2f%%' % (pred_value, label_value, error))
改进点:除了误差率,还可以计算MAE(平均绝对误差)和RMSE(均方根误差),以更全面地评估模型性能。
5. 参数解析 (parser_my.py
)
parser_my.py
文件用于解析命令行参数,并设置模型的超参数。通过命令行参数,用户可以灵活地调整模型的训练和评估过程。
parser.add_argument('--epochs', default=100, type=int) # 训练轮数
parser.add_argument('--layers', default=4, type=int) # LSTM层数
parser.add_argument('--input_size', default=8, type=int) # 输入特征的维度
parser.add_argument('--hidden_size', default=32, type=int) # 隐藏层的维度
parser.add_argument('--lr', default=0.0001, type=float) # 学习率
parser.add_argument('--sequence_length', default=5, type=int) # 序列长度
parser.add_argument('--batch_size', default=64, type=int) # 批大小
parser.add_argument('--useGPU', default=False, type=bool) # 是否使用GPU
parser.add_argument('--save_file', default='model/stock.pkl') # 模型保存位置
优化与改进
1. 数据分割比例调整
在dataset.py
中,训练数据占比为99%,测试数据仅占1%。这种分割比例可能导致模型在测试集上的表现不佳。建议将训练数据比例调整为80%,测试数据比例调整为20%。
trainx, trainy = X[:int(0.8 * total_len)], Y[:int(0.8 * total_len)]
testx, testy = X[int(0.8 * total_len):], Y[int(0.8 * total_len):]
2. 增加评估指标
在evaluate.py
中,仅计算了误差率。为了更全面地评估模型性能,可以增加MAE和RMSE的计算。
from sklearn.metrics import mean_absolute_error, mean_squared_error
mae = mean_absolute_error([label * (close_max - close_min) + close_min for label in labels], [pred[0] * (close_max - close_min) + close_min for pred in preds])
rmse = mean_squared_error([label * (close_max - close_min) + close_min for label in labels], [pred[0] * (close_max - close_min) + close_min for pred in preds], squared=False)
print(f'MAE: {mae}, RMSE: {rmse}')
3. 学习率调度器与早停法
在train.py
中,可以引入学习率调度器和早停法,以提高训练效率并防止过拟合。
from torch.optim.lr_scheduler import ReduceLROnPlateau
scheduler = ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=5, verbose=True)
for i in range(args.epochs):
total_loss = 0
for idx, (data, label) in enumerate(train_loader):
# 训练代码
loss = criterion(pred, label)
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
scheduler.step(total_loss)
结果与分析
通过上述改进,模型的预测准确性显著提高。可视化结果表明,预测值与真实值之间具有较高的一致性。误差率、MAE和RMSE等指标均有所下降,表明模型在测试集上的表现更加稳定。
结论与展望
本文详细介绍了基于LSTM模型的股票价格预测项目,涵盖了从数据预处理、模型定义、训练到评估的全过程。通过代码的优化和改进,我们提高了模型的预测性能。未来可以进一步探索更复杂的模型结构,如多层LSTM、双向LSTM等,或尝试其他时间序列模型以提升预测精度。
标签:附可,进阶,min,模型,py,label,close,LSTM From: https://blog.csdn.net/weixin_74773078/article/details/144618347