1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 时间序列预测--基于CNN的股价预测

时间序列预测--基于CNN的股价预测

时间:2023-10-25 16:09:23

相关推荐

时间序列预测--基于CNN的股价预测

最近应一位读金融学朋友的求助,正好最近任务不忙,决定花小半天的时间帮他写一份有关股价预测的代码,也当作给自己练练手了。于是想把这个过程记录下来,希望可以帮助到像我一样的小白。

一、 数据集

1. 数据分析

首先,先看看数据集长什么样。

这是最简单的单变量时间序列数据,是自/11/01到/10/29的上证医疗指数收盘价,由于这是单变量时间序列数据,所以不需要考虑特征工程,对于多变量的任务,可以通过特征工程对变量进行筛选,这里对此不过多解释,有需要的话自行搜索。

2. 读取数据

首先,加载数据并对数据进行可视化的操作。

# data readingdf = pd.read_csv(r'*****\000109.csv', index_col=0, parse_dates=['time'])print(df)# visualizationplt.figure(figsize=(12, 4))plt.grid(True)plt.plot(df['close'])plt.show()

得到打印的数据和折线图:

3. 数据处理

读取数据之后,就要对数据进行处理,此处主要有两点,第一个是对数据进行归一化操作,第二是将数据集分成训练集和验证集。

对数据进行归一化操作的目的是归纳统一样本的统计分布性,此处将数据归一化到(-1,1)上,是统计的坐标分布。因为神经网络是以样本在事件中的统计分别几率来进行训练(概率计算)和预测的,且Sigmoid函数的取值是0到1之间,网络最后一个节点输出也是如此,所以要对样本的输出进行归一化处理。将数据集分成训练集和验证集,本次数据共有1216组,本次实验将最后的75组数据作为验证集,用以预测并和真实值进行比较。

# divide the dataset into training set and test sety = df['close'].values.astype(float)print('y is')print(y)test_size = 76train_set = y[:-test_size]test_size = y[-test_size:]# normalizationscaler = MinMaxScaler(feature_range=(-1, 1)) # normalize the data into(-1,1)train_norm = scaler.fit_transform(train_set.reshape(-1, 1))print(train_norm)# transfer to tensortrain_norm = torch.FloatTensor(train_norm).view(-1)window_size = 76

此处直接将test_size设置为76,是为了预测/11/01的股价。

二、 建立CNN模型

时间序列预测有很多方法,如传统的时序建模方法ARIMA、周期因子法、深度学习网络等,本次实验采用最简单的卷积神经网络进行训练。对于用CNN处理时序数据,通常使用一维卷积网络Conv1d;本次实验的结构是:卷积层通过2*2卷积核将一维数据展开为三维张量,使用激活函数ReLU将小于0的数据丢弃,再使用全连接层将三维张量转换为一维张量,最后通过两次Linear线性变换得到最后预测值。

class CNNmodel(nn.Module):def __init__(self):super(CNNmodel, self).__init__()self.conv1d = nn.Conv1d(1, 64, kernel_size=2)self.relu = nn.ReLU(inplace=True)self.Linear1 = nn.Linear(64*75, 50)self.Linear2 = nn.Linear(50, 1)def forward(self, x):x = self.conv1d(x)x = self.relu(x)x = x.view(-1)x = self.Linear1(x)x = self.relu(x)x = self.Linear2(x)return x

三、 模型训练

对于训练阶段,本次实验采用MSELoss(均方损失函数),使用Adam优化器,将训练学习率设置为0.001,训练周期为50(一般像本次实验这么少的数据量,epochs用大概30-50就ok了,epochs设置为100太大了,容易过拟合)

# trainingmodel = CNNmodel()print(model)criterion = nn.MSELoss()optimizer = torch.optim.Adam(model.parameters(), lr=0.001)epochs = 50model.train()start_time = time.time()for epoch in range(epochs):for seq, y_train in train_data:# The gradient is zeroed and initialized before each parameter updateoptimizer.zero_grad()# reshape# convert to conv1d input size(batch size, channel, series length)y_pred = model(seq.reshape(1,1,-1))loss = criterion(y_pred, y_train)loss.backward()optimizer.step()print(f'Epoch: {epoch+1:2} Loss: {loss.item():10.8f}')print(f'\nDuration: {time.time() - start_time:.0f} seconds')

四、 数据预测

众所周知,节假日是不开盘的,当时没想起来,出了点问题,在这边卡了很久hhh。模型训练过后是验证阶段和测试阶段。此处将最后75天的预测股价与真实值进行比较。最后预测出/11/01的股价为14298.55013075。

# validatingfuture = 76# Select the last 75 values of the sequence to start the predictionpreds = train_norm[-window_size:].tolist()# set to eval modemodel.eval()# Each step of the cycle represents sliding back one space in the time seriesfor i in range(future):seq = torch.FloatTensor(preds[-window_size:])with torch.no_grad():preds.append(model(seq.reshape(1,1,-1)).item())# Inverse normalization restores the true valuetrue_predictions = scaler.inverse_transform(np.array(preds[window_size:]).reshape(-1, 1))# Compare the actual value with the predicted valueplt.figure(figsize=(12,4))plt.grid(True)plt.plot(df['close'])x = np.arange('-07-08', '-11-02', dtype='datetime64[D]')index = [2, 3, 9, 10, 16, 17, 23, 24, 30, 31, 37, 38, 44, 45, 51, 52, 58, 59, 65, 66, 72, 73, 74, 75, 79, 80, 85, 86, 87, 88, 89, 90, 91, 93, 94, 100, 101, 107, 108, 114, 115]x = np.delete(x, index)print(true_predictions)print('The predicted stock price of -11-01 is:', true_predictions[-1])plt.plot(x, true_predictions)plt.show()

五、 总结

从结果来看,使用CNN来处理时间序列数据产生的预测值总体来说还行,但与真实值存在一定出入。对于股票来说,影响股价波动因素繁多,单单从历史股价进行预测未来股价是不足够的,这也符合弱式有效市场假说,即技术分析失败;另一方面,本次实验采用的网络结构较简单,采用更强大的网络进行回归预测任务则会得到更好的效果。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。